]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Evaluate conditions at load time to allow more flexibility
[builder.git] / source / builder.cpp
index 94bbce04d3a552480994b2d4597fdeb5e154f3b1..63323310c5226d152b2e064b58c1df4ff099069f 100644 (file)
@@ -37,6 +37,7 @@ Builder::Builder(int argc, char **argv):
        package_manager(*this),
        main_pkg(0),
        native_arch(*this, string()),
+       build_type(0),
        vfs(*this),
        analyzer(0),
        build(false),
@@ -49,7 +50,8 @@ Builder::Builder(int argc, char **argv):
        conf_all(false),
        conf_only(false),
        build_all(false),
-       create_makefile(false)
+       create_makefile(false),
+       tempdir("temp")
 {
        string analyze_mode;
        string work_dir;
@@ -57,11 +59,13 @@ Builder::Builder(int argc, char **argv):
        unsigned max_depth = 5;
        StringList cmdline_warn;
        string prfx;
+       string temp_str;
        string arch;
        bool no_externals = false;
        unsigned verbose = 1;
        bool silent = false;
        list<string> log_channels;
+       string build_type_name;
 
        GetOpt getopt;
        getopt.add_option('a', "analyze",    analyze_mode,  GetOpt::REQUIRED_ARG).set_help("Perform analysis.  MODE can be deps, alldeps or rebuild.", "MODE");
@@ -73,6 +77,7 @@ Builder::Builder(int argc, char **argv):
        getopt.add_option('l', "log",        log_channels,  GetOpt::REQUIRED_ARG).set_help("Set log channels to be displayed.", "LIST");
        getopt.add_option('n', "dry-run",    dry_run,       GetOpt::NO_ARG).set_help("Don't actually do anything, only show what would be done.");
        getopt.add_option('s', "silent",     silent,        GetOpt::NO_ARG).set_help("Don't print any messages other than errors.");
+       getopt.add_option('t', "build-type", build_type_name, GetOpt::REQUIRED_ARG).set_help("Set build type.", "TYPE");
        getopt.add_option('v', "verbose",    verbose,       GetOpt::NO_ARG).set_help("Print more information about what's going on.");
        getopt.add_option('x', "no-externals",  no_externals, GetOpt::NO_ARG).set_help("Do not load external source packages.");
        getopt.add_option('A', "conf-all",   conf_all,      GetOpt::NO_ARG).set_help("Apply configuration to all packages.");
@@ -85,6 +90,7 @@ Builder::Builder(int argc, char **argv):
        getopt.add_option(     "full-paths", full_paths,    GetOpt::NO_ARG).set_help("Output full paths in analysis.");
        getopt.add_option(     "max-depth",  max_depth,     GetOpt::REQUIRED_ARG).set_help("Maximum depth to show in analysis.", "NUM");
        getopt.add_option(     "prefix",     prfx,          GetOpt::REQUIRED_ARG).set_help("Directory to install things to.", "DIR");
+       getopt.add_option(     "tempdir",    temp_str,      GetOpt::REQUIRED_ARG).set_help("Store temporary files in DIR.", "DIR");
        getopt.add_option(     "warnings",   cmdline_warn,  GetOpt::REQUIRED_ARG).set_help("Compiler warnings to use.", "LIST");
        usagemsg = getopt.generate_usage(argv[0])+" [<target> ...]";
        helpmsg = getopt.generate_help();
@@ -99,6 +105,7 @@ Builder::Builder(int argc, char **argv):
        }
        if(verbose>=2)
        {
+               logger.enable_channel("environment");
                logger.enable_channel("packages");
                logger.enable_channel("commands");
        }
@@ -165,23 +172,13 @@ Builder::Builder(int argc, char **argv):
 
        package_manager.set_no_externals(no_externals);
 
-       load_build_file((FS::get_sys_data_dir(argv[0], "builder")/"builderrc").str());
-       load_build_file((FS::get_user_data_dir("builder")/"rc").str());
-
        if(arch.empty())
                current_arch = &native_arch;
        else
                current_arch = new Architecture(*this, arch);
 
-       if(!current_arch->is_native())
-       {
-               for(StringMap::const_iterator i=cross_prefixes.begin(); i!=cross_prefixes.end(); ++i)
-                       if(current_arch->match_name(i->first))
-                       {
-                               current_arch->set_cross_prefix(i->second);
-                               break;
-                       }
-       }
+       load_build_file((FS::get_sys_data_dir(argv[0], "builder")/"builderrc").str());
+       load_build_file((FS::get_user_data_dir("builder")/"rc").str());
 
        if(prfx.empty())
        {
@@ -193,6 +190,17 @@ Builder::Builder(int argc, char **argv):
        else
                prefix = FS::getcwd()/prfx;
 
+       if(!temp_str.empty())
+               tempdir = temp_str;
+
+       if(!build_type_name.empty())
+       {
+               BuildTypeMap::iterator i = build_types.find(build_type_name);
+               if(i==build_types.end())
+                       throw usage_error("Unknown build type");
+               build_type = &i->second;
+       }
+
        warnings.push_back("all");
        warnings.push_back("extra");
        warnings.push_back("shadow");
@@ -274,6 +282,12 @@ int Builder::main()
        logger.log("environment", format("Building on %s, for %s%s", native_arch.get_name(),
                current_arch->get_name(), (current_arch->is_native() ? " (native)" : "")));
        logger.log("environment", format("Prefix is %s", prefix));
+       if(tempdir.is_absolute())
+               logger.log("environment", format("Temporary directory is %s", tempdir));
+       else
+               logger.log("environment", format("Using per-package temporary directory %s", tempdir));
+       if(build_type)
+               logger.log("environment", format("Build type is %s", build_type->get_name()));
 
        const PackageManager::PackageMap &packages = package_manager.get_packages();
        list<string> package_details;
@@ -341,20 +355,6 @@ Target *Builder::get_target(const string &n) const
        return 0;
 }
 
-void Builder::apply_profile_template(Config &config, const string &pt) const
-{
-       vector<string> parts = split(pt, '-');
-
-       for(vector<string>::iterator i=parts.begin(); i!=parts.end(); ++i)
-       {
-               ProfileTemplateMap::const_iterator j = profile_tmpl.find(*i);
-               if(j==profile_tmpl.end())
-                       continue;
-
-               config.update(j->second);
-       }
-}
-
 void Builder::problem(const string &p, const string &d)
 {
        problems.push_back(Problem(p, d));
@@ -402,13 +402,13 @@ int Builder::create_targets()
        Target *world = new VirtualTarget(*this, "world");
 
        Target *def_tgt = new VirtualTarget(*this, "default");
-       world->add_depend(def_tgt);
+       world->add_depend(*def_tgt);
 
        Target *install = new VirtualTarget(*this, "install");
-       world->add_depend(install);
+       world->add_depend(*install);
 
        Target *tarballs = new VirtualTarget(*this, "tarballs");
-       world->add_depend(tarballs);
+       world->add_depend(*tarballs);
 
        const PackageManager::PackageMap &packages = package_manager.get_packages();
        for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i)
@@ -430,7 +430,7 @@ int Builder::create_targets()
                        return -1;
                }
 
-               cmdline->add_depend(tgt);
+               cmdline->add_depend(*tgt);
        }
 
        cmdline->prepare();
@@ -454,9 +454,11 @@ int Builder::create_targets()
                                i->second->force_rebuild();
        }
 
-       for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i)
-               if(SourcePackage *spkg = dynamic_cast<SourcePackage *>(i->second))
-                       spkg->get_deps_cache().save();
+       if(!dry_run)
+       {
+               for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i)
+                       i->second->save_caches();
+       }
 
        return 0;
 }
@@ -609,29 +611,37 @@ Builder::Loader::Loader(Builder &b, const FS::Path &s):
        DataFile::ObjectLoader<Builder>(b),
        src(s)
 {
+       add("architecture", &Loader::architecture);
        add("binary_package", &Loader::binpkg);
-       add("cross_prefix", &Loader::cross_prefix);
+       add("build_type", &Loader::build_type);
        add("profile", &Loader::profile);
        add("package", &Loader::package);
 }
 
+void Builder::Loader::architecture(const string &n)
+{
+       if(obj.current_arch->match_name(n))
+               load_sub(*obj.current_arch);
+}
+
 void Builder::Loader::binpkg(const string &n)
 {
        BinaryPackage *pkg = new BinaryPackage(obj, n);
        load_sub(*pkg);
 }
 
-void Builder::Loader::cross_prefix(const string &a, const string &p)
+void Builder::Loader::build_type(const string &n)
 {
-       obj.cross_prefixes[a] = p;
+       BuildType btype(n);
+       load_sub(btype);
+       BuildTypeMap::iterator i = obj.build_types.insert(BuildTypeMap::value_type(n, btype)).first;
+       if(!obj.build_type)
+               obj.build_type = &i->second;
 }
 
-void Builder::Loader::profile(const string &n)
+void Builder::Loader::profile(const string &)
 {
-       StringMap prf;
-       ProfileLoader ldr(prf);
-       load_sub_with(ldr);
-       obj.profile_tmpl.insert(ProfileTemplateMap::value_type(n, prf));
+       IO::print("Profiles are deprecated\n");
 }
 
 void Builder::Loader::package(const string &n)
@@ -640,17 +650,11 @@ void Builder::Loader::package(const string &n)
        if(!obj.main_pkg)
                obj.main_pkg = pkg;
 
-       load_sub(*pkg);
-}
-
-
-Builder::ProfileLoader::ProfileLoader(StringMap &p):
-       profile(p)
-{
-       add("option", &ProfileLoader::option);
-}
+       if(obj.conf_all || pkg==obj.main_pkg)
+               load_sub(*pkg, obj.cmdline_options);
+       else
+               load_sub(*pkg);
 
-void Builder::ProfileLoader::option(const string &o, const string &v)
-{
-       profile.insert(StringMap::value_type(o, v));
+       if(obj.build_type)
+               pkg->set_build_type(*obj.build_type);
 }