X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbuilder.cpp;h=c271c2bb56cf81b211efd8013e4ade5de0e92b59;hb=74266a6e650f019063cdcd1c9a7bd26d8f99041b;hp=0b1d1bf55163b3a8c44d2a767bcb4e790a0b7b7a;hpb=63adab21a6f229f434b41eb59c5718fdc3c37b15;p=builder.git diff --git a/source/builder.cpp b/source/builder.cpp index 0b1d1bf..c271c2b 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -18,6 +18,8 @@ #include "misc.h" #include "objectfile.h" #include "package.h" +#include "sharedlibrary.h" +#include "staticlibrary.h" #include "systemlibrary.h" #include "virtualtarget.h" @@ -25,12 +27,12 @@ using namespace std; using namespace Msp; Builder::Builder(int argc, char **argv): + analyzer(0), + do_build(true), verbose(1), + chrome(false), build_file("Build"), - do_build(true), - analyzer(0), - jobs(1), - chrome(false) + jobs(1) { GetOpt getopt; getopt.add_option(GetOpt::Option('a', "analyze", GetOpt::REQUIRED)); @@ -169,7 +171,9 @@ Target *Builder::get_target(const string &n) /** Tries to locate a header included from a given location and with a given include -path. Considers known targets as well as existing files. +path. Considers known targets as well as existing files. If a matching target +is not found but a file exists, a new SystemHeader target will be created and +returned. */ Target *Builder::get_header(const string &include, const string &from, const list &path) { @@ -199,6 +203,11 @@ Target *Builder::get_header(const string &include, const string &from, const lis return 0; } +/** +Tries to locate a library with the given library path. Considers known targets +as well as existing files. If a matching target is not found but a file exists, +a new SystemLibrary target will be created and returned. +*/ Target *Builder::get_library(const string &lib, const list &path) { string hash(8, 0); @@ -254,7 +263,7 @@ int Builder::main() return 0; } - std::list missing; + StringList missing; for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i) if(!i->second) missing.push_back(i->first); @@ -348,6 +357,13 @@ void Builder::usage(const char *argv0, bool brief) } } +/** +Loads the given build file. + +@param fn Path to the file + +@return 0 on success, -1 if the file could not be opened +*/ int Builder::load_build_file(const Path::Path &fn) { ifstream in(fn.str().c_str()); @@ -361,6 +377,12 @@ int Builder::load_build_file(const Path::Path &fn) return 0; } +/** +Creates targets for all packages and prepares them for building. + +@return 0 if everything went ok, -1 if something bad happened and a build + shouldn't be attempted +*/ int Builder::create_targets() { Target *world=new VirtualTarget(*this, "world"); @@ -388,6 +410,7 @@ int Builder::create_targets() const ComponentList &components=i->second->get_components(); for(ComponentList::const_iterator j=components.begin(); j!=components.end(); ++j) { + // Collect all files belonging to the component PathList files; const PathList &sources=j->get_sources(); for(PathList::const_iterator k=sources.begin(); k!=sources.end(); ++k) @@ -411,17 +434,15 @@ int Builder::create_targets() { string basename=(*k)[-1]; string ext=Path::splitext(basename).ext; - if(ext==".cpp" || ext==".c") + if((ext==".cpp" || ext==".c") && build_exe) { - 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); - } + SourceFile *src=new SourceFile(*this, &*j, k->str()); + add_target(src); + + // Compile sources + ObjectFile *obj=new ObjectFile(*this, *j, *src); + add_target(obj); + objs.push_back(obj); } else if(ext==".h") { @@ -431,6 +452,8 @@ int Builder::create_targets() hdr=new Header(*this, &*j, k->str()); add_target(hdr); } + + // Install headers if requested if(!j->get_install_headers().empty()) { Path::Path inst_path=inst_base/"include"/j->get_install_headers()/basename; @@ -443,12 +466,28 @@ int Builder::create_targets() if(build_exe) { - Executable *exe=new Executable(*this, *j, objs); + Executable *exe=0; + StaticLibrary *slib=0; + if(j->get_type()==Component::LIBRARY) + { + exe=new SharedLibrary(*this, *j, objs); + slib=new StaticLibrary(*this, *j, objs); + add_target(slib); + } + else + exe=new Executable(*this, *j, objs); + add_target(exe); if(i->second==default_pkg) + { def_tgt->add_depend(exe); + if(slib) def_tgt->add_depend(slib); + } else + { world->add_depend(exe); + if(slib) world->add_depend(slib); + } if(j->get_install()) { @@ -462,12 +501,20 @@ int Builder::create_targets() 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); + + if(slib) + { + inst=new Install(*this, *i->second, *slib, (inst_base/inst_dir/Path::basename(slib->get_name())).str()); + add_target(inst); + install->add_depend(inst); + } } } } } } + // Find dependencies until no new targets are created while(!new_tgts.empty()) { Target *tgt=new_tgts.front(); @@ -477,7 +524,8 @@ int Builder::create_targets() new_tgts.push_back(tgt); } - for(list::iterator i=what_if.begin(); i!=what_if.end(); ++i) + // Apply what-ifs + for(StringList::iterator i=what_if.begin(); i!=what_if.end(); ++i) { Target *tgt=get_target((cwd/ *i).str()); if(!tgt) @@ -488,6 +536,7 @@ int Builder::create_targets() tgt->touch(); } + // Make the cmdline target depend on all targets mentioned on the command line Target *cmdline=new VirtualTarget(*this, "cmdline"); add_target(cmdline); world->add_depend(cmdline); @@ -509,6 +558,10 @@ int Builder::create_targets() return 0; } +/** +Check if a header exists, either as a target or a file. Either an existing +target or a new SystemHeader target will be returned. +*/ Target *Builder::check_header(const Msp::Path::Path &fn) { Target *tgt=get_target(fn.str()); @@ -522,12 +575,18 @@ Target *Builder::check_header(const Msp::Path::Path &fn) return 0; } +/** +Adds a target to both the target map and the new target queue. +*/ void Builder::add_target(Target *t) { targets.insert(TargetMap::value_type(t->get_name(), t)); new_tgts.push_back(t); } +/** +Updates a hash with a string. This is used from get_header and get_library. +*/ void Builder::update_hash(string &hash, const string &value) { for(unsigned i=0; iget_config(); const Config::OptionMap &options=config.get_options(); cout<<"Required packages:\n "; - const list &requires=default_pkg->get_requires(); - for(list::const_iterator i=requires.begin(); i!=requires.end(); ++i) + const PkgRefList &requires=default_pkg->get_requires(); + for(PkgRefList::const_iterator i=requires.begin(); i!=requires.end(); ++i) { if(i!=requires.begin()) cout<<", ";