]> git.tdb.fi Git - builder.git/commitdiff
Replace the overly generic configuration profiles with something more purposeful
authorMikko Rasa <tdb@tdb.fi>
Sun, 15 Jul 2012 13:56:14 +0000 (16:56 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 15 Jul 2012 14:05:48 +0000 (17:05 +0300)
builderrc
source/builder.cpp
source/builder.h
source/buildtype.cpp [new file with mode: 0644]
source/buildtype.h [new file with mode: 0644]
source/component.cpp
source/config.cpp
source/config.h
source/sourcepackage.cpp
source/sourcepackage.h

index cb2cd6b197918acc28a3fa18efac71f7aa73fbc1..55010157c052bee9d39837daaac6a746a81b89f2 100644 (file)
--- a/builderrc
+++ b/builderrc
@@ -86,15 +86,29 @@ architecture "windows"
        prefix "i586-mingw32msvc";
 };
 
-profile "debug"
+build_type "debug"
 {
-       option "debug" "yes";
-       option "outdir" "$profile";
+       build_info
+       {
+               debug true;
+               define "DEBUG" "1";
+       };
+};
+
+build_type "optimized_debug"
+{
+       build_info
+       {
+               debug true;
+               optimize 2;
+       };
 };
 
-profile "release"
+build_type "release"
 {
-       option "optimize" "3";
-       option "strip" "yes";
-       option "outdir" "$profile";
+       build_info
+       {
+               optimize 3;
+               strip true;
+       };
 };
index 927b3026c93b7e40755924bc5d99da927d34f23f..c0574e924d51512ba5af04ff11e14517e78bebf0 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),
@@ -62,6 +63,7 @@ Builder::Builder(int argc, char **argv):
        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 +75,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.");
@@ -184,6 +187,14 @@ Builder::Builder(int argc, char **argv):
        else
                prefix = FS::getcwd()/prfx;
 
+       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");
@@ -265,6 +276,8 @@ 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(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;
@@ -332,20 +345,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));
@@ -604,6 +603,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);
 }
@@ -620,12 +620,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)
@@ -635,16 +641,6 @@ void Builder::Loader::package(const string &n)
                obj.main_pkg = pkg;
 
        load_sub(*pkg);
-}
-
-
-Builder::ProfileLoader::ProfileLoader(StringMap &p):
-       profile(p)
-{
-       add("option", &ProfileLoader::option);
-}
-
-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);
 }
index 4192fe767a7dfdc788a050298d6ead0dbbaad2e9..4b0bee33494636b2d5bb6392a001f458f728f4a8 100644 (file)
@@ -8,6 +8,7 @@
 #include <msp/datafile/loader.h>
 #include <msp/fs/path.h>
 #include "architecture.h"
+#include "buildtype.h"
 #include "config.h"
 #include "logger.h"
 #include "misc.h"
@@ -39,26 +40,16 @@ private:
        private:
                void architecture(const std::string &);
                void binpkg(const std::string &);
+               void build_type(const std::string &);
                void profile(const std::string &);
                void package(const std::string &);
        };
 
-       class ProfileLoader: public Msp::DataFile::Loader
-       {
-       private:
-               StringMap &profile;
-
-       public:
-               ProfileLoader(StringMap &);
-       private:
-               void option(const std::string &, const std::string &);
-       };
-
 public:
        typedef std::map<std::string, Target *> TargetMap;
 
 private:
-       typedef std::map<std::string, StringMap> ProfileTemplateMap;
+       typedef std::map<std::string, BuildType> BuildTypeMap;
 
        StringList cmdline_targets;
        StringMap cmdline_options;
@@ -71,7 +62,8 @@ private:
 
        Architecture native_arch;
        Architecture *current_arch;
-       ProfileTemplateMap profile_tmpl;
+       BuildTypeMap build_types;
+       BuildType *build_type;
        Toolchain toolchain;
        VirtualFileSystem vfs;
        Logger logger;
@@ -116,7 +108,6 @@ public:
        const Architecture &get_native_arch() const { return native_arch; }
        const Msp::FS::Path &get_prefix() const { return prefix; }
        const StringList &get_warnings() const { return warnings; }
-       void apply_profile_template(Config &, const std::string &) const;
 
        const Toolchain &get_toolchain() const { return toolchain; }
        VirtualFileSystem &get_vfs() { return vfs; }
diff --git a/source/buildtype.cpp b/source/buildtype.cpp
new file mode 100644 (file)
index 0000000..fbfe6a0
--- /dev/null
@@ -0,0 +1,20 @@
+#include "buildtype.h"
+
+using namespace std;
+using namespace Msp;
+
+BuildType::BuildType(const string &n):
+       name(n)
+{ }
+
+
+BuildType::Loader::Loader(BuildType &b):
+       DataFile::ObjectLoader<BuildType>(b)
+{
+       add("build_info", &Loader::build_info);
+}
+
+void BuildType::Loader::build_info()
+{
+       load_sub(obj.build_info);
+}
diff --git a/source/buildtype.h b/source/buildtype.h
new file mode 100644 (file)
index 0000000..8fcd6a2
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef BUILDTYPE_H_
+#define BUILDTYPE_H_
+
+#include <string>
+#include <msp/datafile/objectloader.h>
+#include "buildinfo.h"
+
+class BuildType
+{
+public:
+       class Loader: public Msp::DataFile::ObjectLoader<BuildType>
+       {
+       public:
+               Loader(BuildType &);
+
+       private:
+               void build_info();
+       };
+
+private:
+       std::string name;
+       BuildInfo build_info;
+
+public:
+       BuildType(const std::string &);
+
+       const std::string &get_name() const { return name; }
+       const BuildInfo &get_build_info() const { return build_info; }
+};
+
+#endif
index 708293e7575da7e4ef67ca3e9fc0217f9ea7ab7a..3c8749ecb3459defeff2e7fa734d5a8f3e8faebd 100644 (file)
@@ -74,9 +74,6 @@ void Component::create_build_info()
                        build_info.libpath.insert(build_info.libpath.end(), ebi.libpath.begin(), ebi.libpath.end());
                }
        }
-
-       if(type==PROGRAM)
-               build_info.strip = lexical_cast<bool>(pkg.get_config().get_option("strip").value);
 }
 
 void Component::create_targets() const
index 1ab70c8a8af3431e983b9f6bdc38f9642ba4af24..194bf0d184f7a2922ee2c172fc49ec480fe7f7d0 100644 (file)
@@ -13,7 +13,6 @@ using namespace Msp;
 
 Config::Config(SourcePackage &p):
        package(p),
-       freeze_mtime(false),
        changed(false)
 { }
 
@@ -32,35 +31,6 @@ bool Config::is_option(const string &name) const
        return options.count(name);
 }
 
-void Config::select_last_profile()
-{
-       FS::Path profile_cache_fn = package.get_source()/".profile";
-       if(FS::exists(profile_cache_fn))
-       {
-               IO::BufferedFile in(profile_cache_fn.str());
-               string profile;
-               in.getline(profile);
-               set_option("profile", profile);
-       }
-
-       freeze_mtime = true;
-       package.get_builder().apply_profile_template(*this, get_option("profile").value);
-       freeze_mtime = false;
-
-       load();
-}
-
-void Config::select_profile(const string &profile)
-{
-       set_option("profile", profile);
-
-       freeze_mtime = true;
-       package.get_builder().apply_profile_template(*this, profile);
-       freeze_mtime = false;
-
-       load();
-}
-
 bool Config::update(const StringMap &opts)
 {
        bool changed_now = false;
@@ -70,7 +40,7 @@ bool Config::update(const StringMap &opts)
                        changed_now = true;
        }
 
-       if(changed_now && !freeze_mtime)
+       if(changed_now)
        {
                mtime = Time::now();
                changed = true;
@@ -90,20 +60,11 @@ void Config::save() const
        if(!changed)
                return;
 
-       FS::Path fn = package.get_source()/".options";
-
-       OptionMap::const_iterator i = options.find("profile");
-       if(i!=options.end())
-       {
-               fn = package.get_source()/(".options."+i->second.value);
-
-               IO::BufferedFile profile_out((package.get_source()/".profile").str(), IO::M_WRITE);
-               IO::print(profile_out, "%s\n", i->second.value);
-       }
+       FS::Path fn = package.get_source()/".config";
 
        IO::BufferedFile out(fn.str(), IO::M_WRITE);
 
-       for(i=options.begin(); i!=options.end(); ++i)
+       for(OptionMap::const_iterator i=options.begin(); i!=options.end(); ++i)
                IO::print(out, "option \"%s\" \"%s\";\n", i->second.name, i->second.value);
 }
 
@@ -124,7 +85,7 @@ bool Config::set_option(const string &opt, const string &val)
 
 void Config::load()
 {
-       FS::Path fn = package.get_source()/(".options."+get_option("profile").value);
+       FS::Path fn = package.get_source()/".config";
 
        FS::Stat stat = FS::stat(fn);
        if(stat)
index 5c87eedf98d78644d3bf742f4791be7b697b6832..f18487bfeeb61493bc5ab0459f81903deff13ddf 100644 (file)
@@ -42,7 +42,6 @@ private:
        SourcePackage &package;
        OptionMap options;
        Msp::Time::TimeStamp mtime;
-       bool freeze_mtime;
        bool changed;
 
 public:
@@ -60,13 +59,6 @@ public:
        /** Checks whether an option exists. */
        bool is_option(const std::string &) const;
 
-       /** Selects the last profile used.  If the profile cache file is not
-       present, the default profile is assumed. */
-       void select_last_profile();
-
-       /** Selects a profile. */
-       void select_profile(const std::string &);
-
        /** Processes options from the given raw option map.  Nonexistent options
        are ignored.  If any options were changed, the mtime of the configuration is
        updated to the current time.  Return value indicates whether any options
@@ -79,6 +71,7 @@ public:
        void save() const;
 private:
        bool set_option(const std::string &, const std::string &);
+public:
        void load();
 };
 
index 02e9152a7b3ef52abcf5042bcf41d56516b7ac0a..1de15ef86781ae2696fa114eb7b3c8c0d6e344ef 100644 (file)
@@ -23,25 +23,37 @@ bool component_sort(const Component &c1, const Component &c2)
 SourcePackage::SourcePackage(Builder &b, const string &n, const FS::Path &s):
        Package(b, n),
        source(s),
+       build_type(0),
        config(*this),
        deps_cache(*this)
 {
        components.push_back(Component(*this, Component::TARBALL, "@src"));
 }
 
+void SourcePackage::set_build_type(const BuildType &t)
+{
+       build_type = &t;
+}
+
 FS::Path SourcePackage::get_temp_dir() const
 {
-       string subdir = format("%s.%s", builder.get_current_arch().get_name(), config.get_option("profile").value);
+       string subdir = builder.get_current_arch().get_name();
+       if(build_type)
+       {
+               subdir += '.';
+               subdir += build_type->get_name();
+       }
        return source/config.get_option("tempdir").value/subdir;
 }
 
 FS::Path SourcePackage::get_out_dir() const
 {
        const Architecture &arch = builder.get_current_arch();
+       string detail = (build_type ? build_type->get_name() : string());
        if(arch.is_native())
-               return source/config.get_option("outdir").value;
+               return source/detail;
        else
-               return source/arch.get_name()/config.get_option("outdir").value;
+               return source/arch.get_name()/detail;
 }
 
 LibMode SourcePackage::get_library_mode() const
@@ -105,11 +117,7 @@ void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
 {
        init_config();
 
-       StringMap::const_iterator prof = opts.find("profile");
-       if(prof!=opts.end() && flag)
-               config.select_profile(prof->second);
-       else
-               config.select_last_profile();
+       config.load();
 
        if(flag && config.update(opts))
                builder.get_logger().log("configure", format("Configuration of %s changed", name));
@@ -140,12 +148,7 @@ void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
 
 void SourcePackage::init_config()
 {
-       config.add_option("profile",    "default", "Configuration profile");
        config.add_option("tempdir",    "temp",    "Directory for storing temporary files");
-       config.add_option("outdir",     ".",       "Directory to put build results in");
-       config.add_option("optimize",   "0",       "Compiler optimization level");
-       config.add_option("strip",      "no",      "Strip symbols from programs");
-       config.add_option("debug",      "no",      "Produce debugging symbols");
        config.add_option("staticlibs", "local",   "Use static libraries");
 
        for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
@@ -161,6 +164,9 @@ void SourcePackage::init_config()
 
 void SourcePackage::create_build_info()
 {
+       if(build_type)
+               build_info.update_from(build_type->get_build_info());
+
        // XXX Currently, a package-specific settings will override cmdline.  This might or might not be desirable.
        const StringList &warnings = builder.get_warnings();
        build_info.warnings.insert(build_info.warnings.begin(), warnings.begin(), warnings.end());
@@ -178,21 +184,6 @@ void SourcePackage::create_build_info()
                export_binfo.libpath.push_back((builder.get_prefix()/"lib").str());
        }
 
-       string optimize = config.get_option("optimize").value;
-       if(!optimize.empty() && optimize!="0")
-       {
-               if(optimize=="s" || optimize=="size")
-                       build_info.optimize = -1;
-               else
-                       build_info.optimize = lexical_cast<unsigned>(optimize);
-       }
-
-       if(lexical_cast<bool>(config.get_option("debug").value))
-       {
-               build_info.debug = true;
-               build_info.defines["DEBUG"] = "1";
-       }
-
        for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
                if(lexical_cast<bool>(config.get_option("with_"+i->name).value))
                        build_info.defines["WITH_"+toupper(i->name)] = "1";
index cd576fef26a03cd8c9f4463668e1984670441109..e5f6d9d460433a718bf2eca654ff11a92b9e244c 100644 (file)
@@ -12,6 +12,7 @@
 #include "package.h"
 
 class Builder;
+class BuildType;
 
 class bad_expansion: public std::runtime_error
 {
@@ -50,6 +51,7 @@ private:
        std::string description;
 
        Msp::FS::Path source;
+       const BuildType *build_type;
        FeatureList features;
        BuildInfo build_info;
        ConditionList conditions;
@@ -66,6 +68,7 @@ public:
        Msp::FS::Path get_out_dir() const;
        const ComponentList &get_components() const { return components; }
        const Config &get_config() const { return config; }
+       void set_build_type(const BuildType &);
        const BuildInfo &get_build_info() const { return build_info; }
        Builder &get_builder() const { return builder; }