]> git.tdb.fi Git - builder.git/commitdiff
Evaluate conditions at load time to allow more flexibility
authorMikko Rasa <tdb@tdb.fi>
Mon, 16 Jul 2012 09:13:31 +0000 (12:13 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 16 Jul 2012 19:27:35 +0000 (22:27 +0300)
source/builder.cpp
source/builder.h
source/config.cpp
source/config.h
source/sourcepackage.cpp
source/sourcepackage.h

index 03429cf8ffa0999723a767bbaf074ead6228a5cc..63323310c5226d152b2e064b58c1df4ff099069f 100644 (file)
@@ -650,7 +650,11 @@ void Builder::Loader::package(const string &n)
        if(!obj.main_pkg)
                obj.main_pkg = pkg;
 
-       load_sub(*pkg);
+       if(obj.conf_all || pkg==obj.main_pkg)
+               load_sub(*pkg, obj.cmdline_options);
+       else
+               load_sub(*pkg);
+
        if(obj.build_type)
                pkg->set_build_type(*obj.build_type);
 }
index cdf615d768383d9691371c2c2e186f7dabad5b4c..943c8513cb5a90deb60173f5b29f164756836fb8 100644 (file)
@@ -19,7 +19,6 @@
 #include "virtualfilesystem.h"
 
 class Analyzer;
-class Config;
 class FileTarget;
 class Package;
 class SourcePackage;
@@ -53,7 +52,7 @@ private:
        typedef std::map<std::string, BuildType> BuildTypeMap;
 
        StringList cmdline_targets;
-       StringMap cmdline_options;
+       Config::InputOptions cmdline_options;
        Msp::FS::Path cwd;
 
        PackageManager package_manager;
index 5b43fe3e68e01aef7521f56610e2b98b134ce289..489026329ec4338390badffe13be7b5b6ef08435 100644 (file)
@@ -18,7 +18,10 @@ Config::Config(SourcePackage &p):
 
 void Config::add_option(const string &n, const string &v, const string &d)
 {
-       options.insert(OptionMap::value_type(n, Option(n, v, d)));
+       Option opt(n, v, d);
+       if(pending_options.count(n))
+               opt.value = pending_options[n];
+       options.insert(OptionMap::value_type(n, opt));
 }
 
 const Config::Option &Config::get_option(const string &name) const
@@ -77,7 +80,10 @@ bool Config::set_option(const string &opt, const string &val)
        if(i!=options.end())
        {
                if(i->second.value!=val)
+               {
                        result = true;
+                       changed = true;
+               }
                i->second.value = val;
        }
 
@@ -119,5 +125,8 @@ Config::Loader::Loader(Config &c):
 
 void Config::Loader::option(const string &n, const string &v)
 {
-       obj.set_option(n, v);
+       if(obj.options.count(n))
+               obj.set_option(n, v);
+       else
+               obj.pending_options[n] = v;
 }
index f18487bfeeb61493bc5ab0459f81903deff13ddf..64e42259defb93454237f316a817155218ea31d7 100644 (file)
@@ -29,6 +29,7 @@ public:
        };
 
        typedef std::map<std::string, Option> OptionMap;
+       typedef std::map<std::string, std::string> InputOptions;
 
 private:
        class Loader: public Msp::DataFile::ObjectLoader<Config>
@@ -41,6 +42,7 @@ private:
 
        SourcePackage &package;
        OptionMap options;
+       InputOptions pending_options;
        Msp::Time::TimeStamp mtime;
        bool changed;
 
@@ -69,9 +71,7 @@ public:
        void finish();
 
        void save() const;
-private:
        bool set_option(const std::string &, const std::string &);
-public:
        void load();
 };
 
index 029d5240faecb84541ce70a54421dfbd9c95a27d..bb239b22b7d60cc83e1486aa1860aa4666a37258 100644 (file)
@@ -27,6 +27,8 @@ SourcePackage::SourcePackage(Builder &b, const string &n, const FS::Path &s):
        config(*this),
        deps_cache(*this)
 {
+       config.load();
+
        components.push_back(Component(*this, Component::TARBALL, "@src"));
 }
 
@@ -116,15 +118,6 @@ void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
 
        config.finish();
 
-       for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
-               if(i->eval())
-               {
-                       const StringList &reqs = i->get_requires();
-                       for(StringList::const_iterator j=reqs.begin(); j!=reqs.end(); ++j)
-                               if(Package *pkg = builder.get_package_manager().find_package(*j))
-                                       requires.push_back(pkg);
-               }
-
        for(PackageList::iterator i=requires.begin(); i!=requires.end(); ++i)
        {
                BinaryPackage *bpkg = dynamic_cast<BinaryPackage *>(*i);
@@ -140,9 +133,6 @@ void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
 
 void SourcePackage::init_config()
 {
-       for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
-               config.add_option("with_"+i->name, i->def_value, i->descr);
-
        for(PackageList::const_iterator i=requires.begin(); i!=requires.end(); ++i)
        {
                BinaryPackage *bpkg = dynamic_cast<BinaryPackage *>(*i);
@@ -177,10 +167,6 @@ void SourcePackage::create_build_info()
                if(lexical_cast<bool>(config.get_option("with_"+i->name).value))
                        build_info.defines["WITH_"+toupper(i->name)] = "1";
 
-       for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
-               if(i->eval())
-                       build_info.update_from(i->get_build_info());
-
        for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
        {
                i->create_build_info();
@@ -216,11 +202,25 @@ void SourcePackage::save_caches()
 SourcePackage::Loader::Loader(SourcePackage &p):
        DataFile::DerivedObjectLoader<SourcePackage, Package>(p)
 {
+       init(0);
+}
+
+SourcePackage::Loader::Loader(SourcePackage &p, const Config::InputOptions &o):
+       DataFile::DerivedObjectLoader<SourcePackage, Package>(p)
+{
+       init(&o);
+}
+
+void SourcePackage::Loader::init(const Config::InputOptions *o)
+{
+       options = o;
        add("version",     &SourcePackage::version);
        add("description", &SourcePackage::description);
        add("build_info",  &Loader::build_info);
        add("feature",     &Loader::feature);
        add("if",          &Loader::condition);
+       add("if_arch",     &Loader::if_arch);
+       add("if_feat",     &Loader::if_feature);
        add("program",     &Loader::component<Component::PROGRAM>);
        add("library",     &Loader::component<Component::LIBRARY>);
        add("module",      &Loader::component<Component::MODULE>);
@@ -258,13 +258,22 @@ void SourcePackage::Loader::feature(const string &n, const string &d)
        feat.def_value = "no";
        load_sub(feat);
        obj.features.push_back(feat);
+       string config_key = "with_"+feat.name;
+       obj.config.add_option(config_key, feat.def_value, feat.descr);
+       if(options)
+       {
+               Config::InputOptions::const_iterator i = options->find(config_key);
+               if(i!=options->end())
+                       obj.config.set_option(config_key, i->second);
+       }
 }
 
 void SourcePackage::Loader::condition(const string &c)
 {
+       IO::print("%s: Note: Old-style conditions are deprecated\n", get_source());
        Condition cond(obj, c);
-       load_sub(cond);
-       obj.conditions.push_back(cond);
+       if(cond.eval())
+               load_sub_with(*this);
 }
 
 template<Component::Type t>
@@ -290,6 +299,42 @@ void SourcePackage::Loader::headers(const string &n)
                install_map[*i] = "include/"+comp.get_name();
 }
 
+void SourcePackage::Loader::if_arch(const string &cond)
+{
+       const Architecture &arch = obj.builder.get_current_arch();
+       bool negate = (cond[0]=='!');
+       bool match = (arch.match_name(cond.substr(negate))!=negate);
+       obj.builder.get_logger().log("configure", format("%s: arch %s %smatched", obj.name, cond, (match ? "" : "not ")));
+       if(match)
+               load_sub_with(*this);
+}
+
+void SourcePackage::Loader::if_feature(const string &cond)
+{
+       bool match = false;
+       string::size_type equals = cond.find('=');
+       if(equals!=string::npos)
+       {
+               if(equals==0)
+                       error("No feature name specified");
+               bool negate = cond[equals-1]=='!';
+               string name = cond.substr(0, equals-negate);
+               string value = obj.config.get_option("with_"+name).value;
+               match = (value==cond.substr(equals+1))!=negate;
+               value = cond.substr(equals+1);
+       }
+       else
+       {
+               bool negate = (cond[0]=='!');
+               string name = cond.substr(negate);
+               string value = obj.config.get_option("with_"+name).value;
+               match = lexical_cast<bool>(value)!=negate;
+       }
+       obj.builder.get_logger().log("configure", format("%s: feature %s %smatched", obj.name, cond, (match ? "" : "not ")));
+       if(match)
+               load_sub_with(*this);
+}
+
 void SourcePackage::Loader::tarball(const string &n)
 {
        if(n=="@src")
index 755bdfcb024a57aab643eb6687aab43a7ae5e207..9327f17c4eccc619cfa9e1b2dd5226d93c8ed701 100644 (file)
@@ -30,11 +30,14 @@ public:
        class Loader: public Msp::DataFile::DerivedObjectLoader<SourcePackage, Package>
        {
        private:
+               const Config::InputOptions *options;
                std::map<std::string, std::string> install_map;
 
        public:
                Loader(SourcePackage &);
+               Loader(SourcePackage &, const Config::InputOptions &);
        private:
+               void init(const Config::InputOptions *);
                virtual void finish();
                void feature(const std::string &, const std::string &);
                template<Component::Type>
@@ -42,6 +45,8 @@ public:
                void condition(const std::string &);
                void build_info();
                void headers(const std::string &);
+               void if_arch(const std::string &);
+               void if_feature(const std::string &);
                void tarball(const std::string &);
                void tar_file(const std::string &);
        };
@@ -54,7 +59,6 @@ private:
        const BuildType *build_type;
        FeatureList features;
        BuildInfo build_info;
-       ConditionList conditions;
        ComponentList components;
        Config config;
        mutable DependencyCache deps_cache;