]> git.tdb.fi Git - builder.git/blobdiff - source/sourcepackage.cpp
Evaluate conditions at load time to allow more flexibility
[builder.git] / source / sourcepackage.cpp
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")