]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Pass the option map through load_build_file and to Loader
[builder.git] / source / builder.cpp
index 3344429c433728f01a54ca6c2ea3ae98e166426f..ea96534cdb0afb7b10bd42d9c4f4608df09e8803 100644 (file)
 #include "binarypackage.h"
 #include "builder.h"
 #include "copy.h"
+#include "datatool.h"
 #include "gnuarchiver.h"
 #include "gnuccompiler.h"
 #include "gnucxxcompiler.h"
 #include "gnulinker.h"
 #include "installedfile.h"
+#include "mingwdlltool.h"
 #include "package.h"
 #include "pkgconfiggenerator.h"
 #include "sharedlibrary.h"
@@ -34,10 +36,10 @@ using namespace Msp;
 
 Builder::Builder(int argc, char **argv):
        package_manager(*this),
-       main_pkg(0),
        native_arch(*this, string()),
        build_type(0),
        vfs(*this),
+       build_graph(*this),
        analyzer(0),
        build(false),
        clean(0),
@@ -50,7 +52,8 @@ Builder::Builder(int argc, char **argv):
        conf_only(false),
        build_all(false),
        create_makefile(false),
-       tempdir("temp")
+       tempdir("temp"),
+       top_loader(0)
 {
        string analyze_mode;
        string work_dir;
@@ -149,9 +152,6 @@ Builder::Builder(int argc, char **argv):
                        cmdline_targets.push_back(*i);
        }
 
-       if(cmdline_targets.empty())
-               cmdline_targets.push_back("default");
-
        if(!work_dir.empty())
                FS::chdir(work_dir);
 
@@ -203,12 +203,13 @@ Builder::Builder(int argc, char **argv):
        toolchain.add_tool(new Copy(*this));
        toolchain.add_tool(new Tar(*this));
        toolchain.add_tool(new PkgConfigGenerator(*this));
+       if(current_arch->get_system()=="windows")
+               toolchain.add_tool(new MingwDllTool(*this, *current_arch));
+       toolchain.add_tool(new DataTool(*this));
 }
 
 Builder::~Builder()
 {
-       for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i)
-               delete i->second;
        delete analyzer;
 }
 
@@ -229,7 +230,7 @@ int Builder::main()
                }
        }
 
-       load_build_file(main_file);
+       load_build_file(main_file, &cmdline_options, conf_all);
 
        if(help)
        {
@@ -269,7 +270,8 @@ int Builder::main()
 
                        unsigned count = 0;
                        unsigned to_be_built = 0;
-                       for(TargetMap::iterator j=targets.begin(); j!=targets.end(); ++j)
+                       const BuildGraph::TargetMap &targets = build_graph.get_targets();
+                       for(BuildGraph::TargetMap::const_iterator j=targets.begin(); j!=targets.end(); ++j)
                                if(j->second->get_package()==i->second)
                                {
                                        ++count;
@@ -288,7 +290,7 @@ int Builder::main()
                package_details.push_back(line);
        }
 
-       logger.log("summary", format("%d active packages, %d targets", package_details.size(), targets.size()));
+       logger.log("summary", format("%d active packages, %d targets", package_details.size(), build_graph.get_targets().size()));
        for(list<string>::const_iterator i=package_details.begin(); i!=package_details.end(); ++i)
                logger.log("packages", *i);
 
@@ -313,42 +315,11 @@ int Builder::main()
        return exit_code;
 }
 
-Target *Builder::get_target(const string &n) const
-{
-       TargetMap::const_iterator i = targets.find(n);
-       if(i!=targets.end())
-               return i->second;
-       return 0;
-}
-
 void Builder::problem(const string &p, const string &d)
 {
        problems.push_back(Problem(p, d));
 }
 
-void Builder::add_target(Target *t)
-{
-       targets.insert(TargetMap::value_type(t->get_name(), t));
-}
-
-void Builder::add_primary_target(Target &t)
-{
-       get_target("world")->add_dependency(t);
-
-       if(t.get_package()==main_pkg && t.get_component() && t.get_component()->is_default())
-               get_target("default")->add_dependency(t);
-}
-
-void Builder::add_installed_target(Target &t)
-{
-       Target *inst_tgt = 0;
-       if(const Tool *tool = t.get_tool())
-               inst_tgt = tool->create_install(t);
-       if(!inst_tgt)
-               inst_tgt = toolchain.get_tool("CP").create_target(t);
-       get_target("install")->add_dependency(*inst_tgt);
-}
-
 void Builder::usage(const char *reason, const char *argv0, bool brief)
 {
        if(reason)
@@ -365,37 +336,25 @@ void Builder::usage(const char *reason, const char *argv0, bool brief)
        }
 }
 
-void Builder::load_build_file(const FS::Path &fn)
+void Builder::load_build_file(const FS::Path &fn, const Config::InputOptions *opts, bool all)
 {
        IO::BufferedFile in(fn.str());
 
        logger.log("files", format("Reading %s", fn));
 
        DataFile::Parser parser(in, fn.str());
-       Loader loader(*this);
+       Loader loader(*this, opts, all);
        loader.load(parser);
 }
 
 bool Builder::prepare_build()
 {
-       Target *world = new VirtualTarget(*this, "world");
-
-       Target *def_tgt = new VirtualTarget(*this, "default");
-       world->add_dependency(*def_tgt);
-
-       Target *install = new VirtualTarget(*this, "install");
-       world->add_dependency(*install);
+       package_manager.get_main_package().prepare();
 
-       Target *tarballs = new VirtualTarget(*this, "tarballs");
-       world->add_dependency(*tarballs);
-
-       main_pkg->prepare();
-
-       // Make the cmdline target depend on all targets mentioned on the command line
-       Target *cmdline = new VirtualTarget(*this, "cmdline");
+       // Add targets from command line as goals
        for(NameList::iterator i=cmdline_targets.begin(); i!=cmdline_targets.end(); ++i)
        {
-               Target *tgt = get_target(*i);
+               Target *tgt = build_graph.get_target(*i);
                if(!tgt)
                        tgt = vfs.get_target(*i);
                if(!tgt)
@@ -406,10 +365,10 @@ bool Builder::prepare_build()
                        return false;
                }
 
-               cmdline->add_dependency(*tgt);
+               build_graph.add_goal(*tgt);
        }
 
-       cmdline->prepare();
+       build_graph.prepare();
 
        // Apply what-ifs
        for(NameList::iterator i=what_if.begin(); i!=what_if.end(); ++i)
@@ -424,11 +383,7 @@ bool Builder::prepare_build()
        }
 
        if(build_all)
-       {
-               for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i)
-                       if(i->second->is_buildable() && !i->second->needs_rebuild())
-                               i->second->force_rebuild();
-       }
+               build_graph.force_full_rebuild();
 
        if(!dry_run)
        {
@@ -442,12 +397,7 @@ bool Builder::prepare_build()
 
 int Builder::do_build()
 {
-       Target *cmdline = get_target("cmdline");
-
-       unsigned total = 0;
-       for(map<string, Target *>::const_iterator i=targets.begin(); i!=targets.end(); ++i)
-               if(i->second->is_buildable() && i->second->needs_rebuild())
-                       ++total;
+       unsigned total = build_graph.count_rebuild_targets();
 
        if(!total)
        {
@@ -468,7 +418,7 @@ int Builder::do_build()
        {
                if(tasks.size()<jobs && !fail && !starved)
                {
-                       Target *tgt = cmdline->get_buildable_target();
+                       Target *tgt = build_graph.get_buildable_target();
                        if(tgt)
                        {
                                if(tgt->get_tool())
@@ -548,14 +498,14 @@ int Builder::do_clean()
 
        set<Target *> clean_tgts;
        list<Target *> queue;
-       queue.push_back(get_target("cmdline"));
+       queue.push_back(build_graph.get_target("cmdline"));
 
        while(!queue.empty())
        {
                Target *tgt = queue.front();
                queue.erase(queue.begin());
 
-               if(tgt->is_buildable() && (tgt->get_package()==main_pkg || clean>=2))
+               if(tgt->is_buildable() && (tgt->get_package()==&package_manager.get_main_package() || clean>=2))
                        clean_tgts.insert(tgt);
 
                const Target::Dependencies &deps = tgt->get_dependencies();
@@ -576,11 +526,12 @@ int Builder::do_clean()
 
 void Builder::package_help()
 {
-       const Config &config = main_pkg->get_config();
+       SourcePackage &main_pkg = dynamic_cast<SourcePackage &>(package_manager.get_main_package());
+       const Config &config = main_pkg.get_config();
        const Config::OptionMap &options = config.get_options();
 
        IO::print("Required packages:\n  ");
-       const Package::Requirements &requires = main_pkg->get_required_packages();
+       const Package::Requirements &requires = main_pkg.get_required_packages();
        for(Package::Requirements::const_iterator i=requires.begin(); i!=requires.end(); ++i)
        {
                if(i!=requires.begin())
@@ -602,14 +553,27 @@ string Builder::usagemsg;
 string Builder::helpmsg;
 
 
-Builder::Loader::Loader(Builder &b):
-       DataFile::ObjectLoader<Builder>(b)
+Builder::Loader::Loader(Builder &b, const Config::InputOptions *o, bool a):
+       DataFile::ObjectLoader<Builder>(b),
+       options(o),
+       conf_all(a)
 {
        add("architecture", &Loader::architecture);
        add("binary_package", &Loader::binpkg);
        add("build_type", &Loader::build_type);
        add("profile", &Loader::profile);
        add("package", &Loader::package);
+
+       if(!obj.top_loader)
+               obj.top_loader = this;
+       else if(!options && obj.top_loader!=this && obj.top_loader->conf_all)
+               options = obj.top_loader->options;
+}
+
+Builder::Loader::~Loader()
+{
+       if(obj.top_loader==this)
+               obj.top_loader = 0;
 }
 
 void Builder::Loader::architecture(const string &n)
@@ -641,11 +605,9 @@ void Builder::Loader::profile(const string &)
 void Builder::Loader::package(const string &n)
 {
        SourcePackage *pkg = new SourcePackage(obj, n, get_source());
-       if(!obj.main_pkg)
-               obj.main_pkg = pkg;
 
-       if(obj.conf_all || pkg==obj.main_pkg)
-               load_sub(*pkg, obj.cmdline_options);
+       if(options)
+               load_sub(*pkg, *options);
        else
                load_sub(*pkg);