]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Miscellaneous style and comment tweaks
[builder.git] / source / builder.cpp
index d93bd0aff646a4d2c5b428e5557ad39dc14fc906..122e1b901e011d6abafd8ea86789b86e66bb628e 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.");
@@ -80,11 +85,12 @@ Builder::Builder(int argc, char **argv):
        getopt.add_option('C', "chdir",      work_dir,      GetOpt::REQUIRED_ARG).set_help("Change to DIR before doing anything else.", "DIR");
        getopt.add_option('P', "progress",   show_progress, GetOpt::NO_ARG).set_help("Display progress while building.");
        getopt.add_option('W', "what-if",    what_if,       GetOpt::REQUIRED_ARG).set_help("Pretend that FILE has changed.", "FILE");
-       getopt.add_option(     "arch",       arch,          GetOpt::REQUIRED_ARG).set_help("Architecture to build for.", "ARCH");
+       getopt.add_option(     "arch",       arch,          GetOpt::REQUIRED_ARG).set_help("Build for architecture ARCH.", "ARCH");
        getopt.add_option(     "conf-only",  conf_only,     GetOpt::NO_ARG).set_help("Stop after configuring packages.");
        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(     "max-depth",  max_depth,     GetOpt::REQUIRED_ARG).set_help("Show up to NUM levels in analysis..", "NUM");
+       getopt.add_option(     "prefix",     prfx,          GetOpt::REQUIRED_ARG).set_help("Install things to DIR.", "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");
        }
@@ -183,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");
@@ -245,8 +263,6 @@ int Builder::main()
                }
        }
 
-       main_pkg->configure(cmdline_options, conf_all?2:1);
-
        if(help)
        {
                usage(0, "builder", false);
@@ -258,18 +274,24 @@ int Builder::main()
        if(conf_only)
                return 0;
 
-       if(create_targets())
+       if(!prepare_build())
                return 1;
 
        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;
        for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i)
        {
-               if(!i->second || !i->second->is_configured())
+               if(!i->second || !i->second->is_prepared())
                        continue;
 
                string line = i->second->get_name();
@@ -331,20 +353,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));
@@ -387,7 +395,7 @@ int Builder::load_build_file(const FS::Path &fn)
        return 0;
 }
 
-int Builder::create_targets()
+bool Builder::prepare_build()
 {
        Target *world = new VirtualTarget(*this, "world");
 
@@ -400,10 +408,7 @@ int Builder::create_targets()
        Target *tarballs = new VirtualTarget(*this, "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)
-               if(i->second && i->second->is_configured())
-                       i->second->create_targets();
+       main_pkg->prepare();
 
        // Make the cmdline target depend on all targets mentioned on the command line
        Target *cmdline = new VirtualTarget(*this, "cmdline");
@@ -417,7 +422,7 @@ int Builder::create_targets()
                if(!tgt)
                {
                        IO::print("I don't know anything about %s\n", *i);
-                       return -1;
+                       return false;
                }
 
                cmdline->add_depend(*tgt);
@@ -432,7 +437,7 @@ int Builder::create_targets()
                if(!tgt)
                {
                        IO::print(IO::cerr, "Unknown what-if target %s\n", *i);
-                       return -1;
+                       return false;
                }
                tgt->touch();
        }
@@ -446,11 +451,12 @@ int Builder::create_targets()
 
        if(!dry_run)
        {
+               const PackageManager::PackageMap &packages = package_manager.get_packages();
                for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i)
                        i->second->save_caches();
        }
 
-       return 0;
+       return true;
 }
 
 int Builder::do_build()
@@ -603,6 +609,7 @@ Builder::Loader::Loader(Builder &b, const FS::Path &s):
 {
        add("architecture", &Loader::architecture);
        add("binary_package", &Loader::binpkg);
+       add("build_type", &Loader::build_type);
        add("profile", &Loader::profile);
        add("package", &Loader::package);
 }
@@ -619,12 +626,18 @@ void Builder::Loader::binpkg(const string &n)
        load_sub(*pkg);
 }
 
-void Builder::Loader::profile(const string &n)
+void Builder::Loader::build_type(const string &n)
 {
-       StringMap prf;
-       ProfileLoader ldr(prf);
-       load_sub_with(ldr);
-       obj.profile_tmpl.insert(ProfileTemplateMap::value_type(n, prf));
+       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 &)
+{
+       IO::print("Profiles are deprecated\n");
 }
 
 void Builder::Loader::package(const string &n)
@@ -633,17 +646,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);
 }