deflt(true)
{ }
+void Component::configure(const StringMap &opts, unsigned flag)
+{
+ for(StringList::iterator i=sources.begin(); i!=sources.end(); ++i)
+ *i = (pkg.get_source()/pkg.expand_string(*i)).str();
+
+ for(PackageList::const_iterator i=requires.begin(); i!=requires.end(); ++i)
+ (*i)->configure(opts, flag&2);
+}
+
void Component::create_build_info()
{
const PackageList &pkg_reqs = pkg.get_requires();
}
else if(module_host)
{
- const PathList &host_src = module_host->get_sources();
- for(PathList::const_iterator i=host_src.begin(); i!=host_src.end(); ++i)
- build_info.incpath.push_back(i->str());
+ const StringList &host_src = module_host->get_sources();
+ for(StringList::const_iterator i=host_src.begin(); i!=host_src.end(); ++i)
+ build_info.incpath.push_back(*i);
}
build_info.unique();
PathList Component::collect_source_files() const
{
PathList files;
- for(PathList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
+ for(StringList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
{
- if(FS::is_dir(*i))
+ FS::Path path(*i);
+ if(FS::is_dir(path))
{
- list<string> sfiles = list_files(*i);
+ list<string> sfiles = list_files(path);
for(list<string>::iterator j=sfiles.begin(); j!=sfiles.end(); ++j)
- files.push_back(*i / *j);
+ files.push_back(path / *j);
}
else
- files.push_back(*i);
+ files.push_back(path);
}
return files;
void Component::Loader::source(const string &s)
{
- comp.sources.push_back(comp.pkg.get_source()/s);
+ comp.sources.push_back(s);
}
void Component::Loader::require(const string &n)
SourcePackage &pkg;
Type type;
std::string name;
- PathList sources;
+ StringList sources;
bool install;
const Component *module_host;
bool modular;
const SourcePackage &get_package() const { return pkg; }
Type get_type() const { return type; }
const std::string &get_name() const { return name; }
- const PathList &get_sources() const { return sources; }
+ const StringList &get_sources() const { return sources; }
const BuildInfo &get_build_info() const { return build_info; }
bool get_install() const { return install; }
bool is_modular() const { return modular; }
const PackageList &get_requires() const { return requires; }
bool is_default() const { return deflt; }
+ void configure(const StringMap &, unsigned);
+
/** Prepares the build information for building. Pulls build info from the
parent and dependency packages, and adds any component-specific flags. */
void create_build_info();
Distributed under the LGPL
*/
-#include <cstdlib>
#include <msp/core/except.h>
#include <msp/fs/stat.h>
#include <msp/fs/utils.h>
void Config::finish()
{
- for(unsigned n=0; n<20; ++n)
- {
- bool changed = false;
- for(OptionMap::iterator i=options.begin(); i!=options.end(); ++i)
- {
- Option &opt = i->second;
- string::size_type dollar = 0;
- while((dollar = opt.value.find('$', dollar))!=string::npos)
- {
- string::size_type end;
- string var;
- if(opt.value[dollar+1]=='{')
- {
- end = opt.value.find('}', dollar+2);
- if(end==string::npos)
- throw Exception("Unterminated variable reference");
- var = opt.value.substr(dollar+2, end-dollar-2);
- ++end;
- }
- else
- {
- for(end=dollar+1; (isalnum(opt.value[end]) && opt.value[end]!='_'); ++end) ;
- var = opt.value.substr(dollar+1, end-dollar-1);
- }
-
- string value;
- if(is_option(var))
- value = get_option(var).value;
- else if(var=="arch")
- value = package.get_builder().get_current_arch().get_name();
- else if(const char *ptr = getenv(var.c_str()))
- value = ptr;
-
- opt.value.replace(dollar, end-dollar, value);
-
- dollar += value.size();
- changed = true;
- }
- }
-
- if(!changed)
- break;
- }
+ for(OptionMap::iterator i=options.begin(); i!=options.end(); ++i)
+ i->second.value = package.expand_string(i->second.value);
}
void Config::save() const
Distributed under the LGPL
*/
+#include <cstdlib>
#include <msp/io/print.h>
#include <msp/strings/lexicalcast.h>
#include <msp/strings/utils.h>
throw Exception("Unknown library mode");
}
+string SourcePackage::expand_string(const string &str) const
+{
+ string result = str;
+ string::size_type dollar = 0;
+ unsigned n = 0;
+ while((dollar = result.find('$'))!=string::npos)
+ {
+ if(n>1000)
+ throw Exception("Too much variable expansions");
+
+ string::size_type end;
+ string var;
+ if(dollar+1<result.size() && result[dollar+1]=='{')
+ {
+ end = result.find('}', dollar+2);
+ if(end==string::npos)
+ throw Exception("Unterminated variable reference");
+ var = result.substr(dollar+2, end-dollar-2);
+ ++end;
+ }
+ else
+ {
+ for(end=dollar+1; (isalnum(result[end]) || result[end]=='_'); ++end) ;
+ var = result.substr(dollar+1, end-dollar-1);
+ }
+
+ string value;
+ if(config.is_option(var))
+ value = config.get_option(var).value;
+ else if(var=="arch")
+ value = builder.get_current_arch().get_name();
+ else if(var=="system")
+ value = builder.get_current_arch().get_system();
+ else if(const char *ptr = getenv(var.c_str()))
+ value = ptr;
+
+ result.replace(dollar, end-dollar, value);
+
+ ++n;
+ }
+
+ return result;
+}
+
void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
{
init_config();
deps_cache.load();
for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
- {
- const PackageList &reqs = i->get_requires();
- for(PackageList::const_iterator j=reqs.begin(); j!=reqs.end(); ++j)
- (*j)->configure(opts, flag&2);
- }
+ i->configure(opts, flag);
}
void SourcePackage::init_config()
SourcePackage &spkg = static_cast<SourcePackage &>(pkg);
for(ComponentList::iterator i=spkg.components.begin(); i!=spkg.components.end(); ++i)
if(i->get_type()==Component::TARBALL && i->get_name()=="@src")
- const_cast<PathList &>(i->get_sources()).push_back(spkg.source/f);
+ const_cast<StringList &>(i->get_sources()).push_back((spkg.source/f).str());
}
LibMode get_library_mode() const;
DependencyCache &get_deps_cache() const { return deps_cache; }
+ std::string expand_string(const std::string &) const;
private:
virtual void do_configure(const StringMap &, unsigned);