X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbuilder.cpp;h=cb8ddf610fe7b0237fb5a9f078ebcd122144e3ee;hb=0d80cabf649b931b26e7055385156c75a7385d35;hp=c900837a2d6e978079294606ccbf4f182ae520e8;hpb=97001ddfa2463e6a3526eff772962acdad45f995;p=builder.git diff --git a/source/builder.cpp b/source/builder.cpp index c900837..cb8ddf6 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -1,15 +1,23 @@ #include +#include +#include #include +#include +#include #include #include #include +#include #include "action.h" +#include "analyzer.h" #include "builder.h" #include "executable.h" #include "header.h" +#include "install.h" #include "misc.h" #include "objectfile.h" #include "package.h" +#include "systemlibrary.h" #include "virtualtarget.h" using namespace std; @@ -17,9 +25,60 @@ using namespace Msp; Builder::Builder(int argc, char **argv): verbose(1), - cwd(Path::getcwd()) + cwd(Path::getcwd()), + analyzer(0), + jobs(1), + chrome(false) { - for(int i=1; iset_mode(Analyzer::DEPS); + else if(mode=="alldeps") + analyzer->set_mode(Analyzer::ALLDEPS); + else if(mode=="rebuild") + analyzer->set_mode(Analyzer::REBUILD); + else if(mode=="rdeps") + analyzer->set_mode(Analyzer::RDEPS); + else + throw UsageError("Invalid analysis mode"); + + if(getopt["max-depth"]) + analyzer->set_max_depth(strtol(getopt["max-depth"].arg())); + analyzer->set_full_paths(getopt["full-paths"]); + } + + if(getopt['j']) + jobs=max(strtol(getopt['j'].arg()), 1L); + + if(getopt["chrome"]) + chrome=true; + + if(getopt['C']) + chdir(getopt['C'].arg().c_str()); + + for(int i=index; i dirs; + PathList dirs; if(!srcdir.empty()) dirs.push_back(srcdir); string dirname=n; - if(dirname.compare(0, 3, "msp")) + if(!dirname.compare(0, 3, "msp")) dirname.erase(0, 3); dirs.push_back(cwd/dirname); dirs.push_back(cwd/".."/dirname); - for(list::iterator j=dirs.begin(); j!=dirs.end(); ++j) + for(PathList::iterator j=dirs.begin(); j!=dirs.end(); ++j) if(!load_build_file(*j/"Build")) { i=packages.find(n); if(i!=packages.end()) return i->second; - return 0; + break; } Package *pkg=Package::create(*this, n); @@ -81,6 +147,7 @@ Target *Builder::get_target(const string &n) Target *Builder::get_header(const string &include, const string &from, const list &path) { + //XXX Should really hash the include path here string id=from+":"+include; TargetMap::iterator i=includes.find(id); if(i!=includes.end()) @@ -101,9 +168,33 @@ Target *Builder::get_header(const string &include, const string &from, const lis return 0; } +Target *Builder::get_library(const string &lib, const list &path) +{ + string hash(8, 0); + for(list::const_iterator i=path.begin(); i!=path.end(); ++i) + for(unsigned j=0; jsize(); ++j) + hash[j%8]^=(*i)[j]; + + string basename="lib"+lib+".so"; + for(list::const_iterator i=path.begin(); i!=path.end(); ++i) + { + string full=(Path::Path(*i)/basename).str(); + Target *tgt=get_target(full); + if(tgt) return tgt; + + if(Path::exists(full)) + { + add_target(tgt=new SystemLibrary(*this, full)); + return tgt; + } + } + + return 0; +} + int Builder::main() { - if(load_build_file("Build")) + if(load_build_file(cwd/"Build")) { cerr<<"No build info here.\n"; return 1; @@ -137,32 +228,58 @@ int Builder::main() for(list::iterator i=missing.begin(); i!=missing.end(); ++i) cerr<<" "<<*i<<'\n'; cerr<<"Please install them and try again.\n"; + return 1; } default_pkg->create_build_info(); - cout<<"Active packages:"; + /*cout<<"Active packages:"; for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i) { cout<<' '<second->get_name(); if(i->second->get_buildable()) cout<<'*'; } - cout<<'\n'; + cout<<'\n';*/ if(create_targets()) return 1; - /*for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i) - cout<second->get_name()<<' '<second->get_type()<<' '<second->get_rebuild()<<' '<second->get_rebuild_reason()<<'\n';*/ + cout<=2) + { + for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i) + { + cout<<' '<second->get_name(); + if(i->second->get_buildable()) + cout<<'*'; + unsigned count=0; + for(TargetMap::iterator j=targets.begin(); j!=targets.end(); ++j) + if(j->second->get_package()==i->second) + ++count; + cout<<" ("<analyze(); build(); return exit_code; } +Builder::~Builder() +{ + for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i) + delete i->second; + for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i) + delete i->second; + delete analyzer; +} + int Builder::load_build_file(const Path::Path &fn) { ifstream in(fn.str().c_str()); @@ -170,7 +287,7 @@ int Builder::load_build_file(const Path::Path &fn) return -1; Parser::Parser parser(in, fn.str()); - Loader loader(*this, cwd/fn.subpath(0, fn.size()-1)); + Loader loader(*this, fn.subpath(0, fn.size()-1)); loader.load(parser); return 0; @@ -185,41 +302,92 @@ int Builder::create_targets() add_target(def_tgt); world->add_depend(def_tgt); + Target *install=new VirtualTarget(*this, "install"); + add_target(install); + world->add_depend(install); + for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i) { + if(!i->second) + continue; if(!i->second->get_buildable()) continue; const ComponentList &components=i->second->get_components(); for(ComponentList::const_iterator j=components.begin(); j!=components.end(); ++j) { - Path::Path base=i->second->get_source()/j->get_source(); - list files=list_files(base); + PathList files; + const PathList &sources=j->get_sources(); + for(PathList::const_iterator k=sources.begin(); k!=sources.end(); ++k) + { + list sfiles=list_files(*k); + for(list::iterator l=sfiles.begin(); l!=sfiles.end(); ++l) + files.push_back(*k / *l); + } + + Path::Path inst_base=i->second->get_config().get_option("prefix").value; + bool build_exe=j->get_type()!=Component::HEADERS; + list objs; - for(list::iterator k=files.begin(); k!=files.end(); ++k) + for(PathList::iterator k=files.begin(); k!=files.end(); ++k) { - Path::Path fn=base/ *k; - string ext=Path::splitext(*k).ext; + string basename=(*k)[-1]; + string ext=Path::splitext(basename).ext; if(ext==".cpp" || ext==".c") { - SourceFile *src=new SourceFile(*this, &*j, fn.str()); - add_target(src); - - ObjectFile *obj=new ObjectFile(*this, *j, *src); - add_target(obj); - objs.push_back(obj); + if(build_exe) + { + SourceFile *src=new SourceFile(*this, &*j, k->str()); + add_target(src); + + ObjectFile *obj=new ObjectFile(*this, *j, *src); + add_target(obj); + objs.push_back(obj); + } } else if(ext==".h") - add_target(new Header(*this, &*j, fn.str())); + { + Target *hdr=get_target(k->str()); + if(!hdr) + { + hdr=new Header(*this, &*j, k->str()); + add_target(hdr); + } + if(!j->get_install_headers().empty()) + { + Path::Path inst_path=inst_base/"include"/j->get_install_headers()/basename; + Install *inst=new Install(*this, *i->second, *hdr, inst_path.str()); + add_target(inst); + install->add_depend(inst); + } + } } - Executable *exe=new Executable(*this, *j, objs); - add_target(exe); - if(i->second==default_pkg) - def_tgt->add_depend(exe); - else - world->add_depend(exe); + if(build_exe) + { + Executable *exe=new Executable(*this, *j, objs); + add_target(exe); + if(i->second==default_pkg) + def_tgt->add_depend(exe); + else + world->add_depend(exe); + + if(j->get_install()) + { + string inst_dir; + if(j->get_type()==Component::PROGRAM) + inst_dir="bin"; + else if(j->get_type()==Component::LIBRARY) + inst_dir="lib"; + if(!inst_dir.empty()) + { + Install *inst=new Install(*this, *i->second, *exe, (inst_base/inst_dir/Path::basename(exe->get_name())).str()); + add_target(inst); + install->add_depend(inst); + } + } + } } } @@ -241,7 +409,7 @@ int Builder::create_targets() if(!tgt) { cerr<<"I don't know anything about "<<*i<<'\n'; - return 1; + return -1; } cmdline->add_depend(tgt); } @@ -273,44 +441,81 @@ void Builder::add_target(Target *t) int Builder::build() { Target *cmdline=get_target("cmdline"); - list actions; - bool fail=false; - if(!cmdline->get_rebuild()) + unsigned total=cmdline->count_rebuild(); + if(!total) + { cout<<"Already up to date\n"; + return 0; + } + cout<<"Will build "< actions; + + //ProgressBar *progress=0; + if(chrome) + { + //progress=new ProgressBar(cout, total); + cout<<"0 targets built\n"; + } + unsigned count=0; - while(cmdline->get_rebuild() && !fail) + bool fail=false; + bool finish=false; + + while(!finish) { - if(actions.empty() && !fail) + if(actions.size()get_buildable_target(); if(tgt) { - //cout<<"Build "<get_name()<<'\n'; + /*if(chrome) + { + cout<<"\e["<set(count); + cout<<"\e["<build(); if(action) actions.push_back(action); } + else if(actions.empty()) + finish=true; } else - sleep(10*Time::msec); + Time::sleep(10*Time::msec); - for(list::iterator i=actions.begin(); i!=actions.end();) + for(unsigned i=0; icheck(); + int status=actions[i]->check(); if(status>=0) { - delete *i; - i=actions.erase(i); + ++count; + if(chrome) + { + cout<<"\e["<0) - fail=true; + finish=fail=true; } else ++i; } } - return 0; + //delete progress; + + return fail?-1:0; } Application::RegApp Builder::reg; @@ -328,6 +533,5 @@ void Builder::Loader::package(const string &n) load_sub(*pkg); bld.packages.insert(PackageMap::value_type(n, pkg)); bld.new_pkgs.push_back(pkg); - //cout<<"loaded "<get_name()<<'\n'; }