+ PackageMap::iterator i = packages.find(format("%s/%s", name, current_arch->get_system()));
+ if(i==packages.end())
+ i = packages.find(name);
+ if(i!=packages.end())
+ return i->second;
+
+ if(!no_externals)
+ {
+ FS::Path path = get_package_location(name);
+ if(!path.empty() && !load_build_file(path/"Build"))
+ {
+ i = packages.find(name);
+ if(i!=packages.end())
+ return i->second;
+ }
+ }
+
+ Package *pkg = 0;
+ try
+ {
+ // Package source not found - create a binary package
+ pkg = BinaryPackage::from_pkgconfig(*this, name);
+ }
+ catch(...)
+ {
+ problem(name, "not found");
+ }
+
+ packages.insert(PackageMap::value_type(name, pkg));
+
+ return pkg;
+}
+
+Target *Builder::get_target(const string &n) const
+{
+ TargetMap::const_iterator i = targets.find(n);
+ if(i!=targets.end())
+ return i->second;
+ 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));
+}
+
+void Builder::add_target(Target *t)
+{
+ targets.insert(TargetMap::value_type(t->get_name(), t));
+ new_tgts.push_back(t);
+}
+
+void Builder::usage(const char *reason, const char *argv0, bool brief)
+{
+ if(reason)
+ IO::print(IO::cerr, "%s\n", reason);
+
+ if(brief)
+ IO::print(IO::cerr, "Usage: %s\n", usagemsg);
+ else
+ {
+ IO::print(IO::cerr, "Builder 1.0\n\n");
+ IO::print(IO::cerr, "Usage: %s [options] [<target> ...]\n\n", argv0);
+ IO::print(IO::cerr, "Options:\n");
+ IO::print(IO::cerr, helpmsg);
+ }
+}
+
+FS::Path Builder::get_package_location(const string &name)
+{
+ if(verbose>=3)
+ IO::print("Looking for package %s\n", name);
+
+ try
+ {
+ // Try to get source directory with pkgconfig
+ string srcdir = strip(run_pkgconfig(name, "source"));
+ if(!srcdir.empty())
+ return srcdir;
+ }
+ catch(...)
+ { }
+
+ if(pkg_dirs.empty())
+ {
+ for(list<FS::Path>::const_iterator i=pkg_path.begin(); i!=pkg_path.end(); ++i)
+ {
+ list<string> files = list_files(*i);
+ for(list<string>::const_iterator j=files.begin(); j!=files.end(); ++j)
+ {
+ FS::Path full = *i / *j;
+ if(FS::exists(full/"Build"))
+ pkg_dirs.push_back(full);
+ }
+ }
+ if(verbose>=3)
+ IO::print("%d packages found in path\n", pkg_dirs.size());
+ }
+
+ bool msp = !name.compare(0, 3, "msp");
+ for(list<FS::Path>::const_iterator i=pkg_dirs.begin(); i!=pkg_dirs.end(); ++i)
+ {
+ string base = basename(*i);
+ unsigned dash = base.rfind('-');
+
+ if(!base.compare(0, dash, name))
+ return *i;
+ else if(msp && !base.compare(0, dash-3, name, 3, string::npos))
+ return *i;
+ }
+
+ return FS::Path();
+}
+
+int Builder::load_build_file(const FS::Path &fn)
+{
+ if(!FS::exists(fn))