]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Add comments
[builder.git] / source / builder.cpp
index 0b1d1bf55163b3a8c44d2a767bcb4e790a0b7b7a..c271c2bb56cf81b211efd8013e4ade5de0e92b59 100644 (file)
@@ -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<string> &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<string> &path)
 {
        string hash(8, 0);
@@ -254,7 +263,7 @@ int Builder::main()
                return 0;
        }
 
-       std::list<std::string> 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<string>::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; i<value.size(); ++i)
@@ -608,14 +667,17 @@ int Builder::build()
        return fail?-1:0;
 }
 
+/**
+Prints out information about the default package.
+*/
 void Builder::package_help()
 {
        const Config &config=default_pkg->get_config();
        const Config::OptionMap &options=config.get_options();
 
        cout<<"Required packages:\n  ";
-       const list<PackageRef> &requires=default_pkg->get_requires();
-       for(list<PackageRef>::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<<", ";