+ if(brief)
+ cerr<<"Usage: "<<argv0<<" [-a|--analyze MODE] [-b|--build] [-c|--clean] [-f|--file FILE] [-h|--help] [-j|--jobs NUM] [-n||--dry-run] [-v|--verbose] [-A|--conf-all] [-B|--build-all] [-C|--chdir DIRECTORY] [-W|--what-if FILE] [--chrome] [--conf-only] [--full-paths] [--max-depth NUM] [<target> ...]\n";
+ else
+ {
+ cerr<<
+ "Usage: "<<argv0<<" [options] [<target> ...]\n"
+ "\n"
+ "Options:\n"
+ " -a, --analyze MODE Perform analysis. MODE can be deps, alldeps or rebuild.\n"
+ " -b, --build Perform build even if doing analysis.\n"
+ " -c, --clean Clean buildable targets.\n"
+ " -f, --file FILE Read info from FILE instead of Build.\n"
+ " -h, --help Print this message.\n"
+ " -j, --jobs NUM Run NUM commands at once, whenever possible.\n"
+ " -n, --dry-run Don't actually do anything, only show what would be done.\n"
+ " -v, --verbose Print more information about what's going on.\n"
+ " -A, --conf-all Apply configuration to all packages.\n"
+ " -B, --build-all Build all targets unconditionally.\n"
+ " -C, --chdir DIR Change to DIR before doing anything else.\n"
+ " -P, --progress Display progress while building.\n"
+ " -W, --what-if FILE Pretend that FILE has changed.\n"
+ " --arch ARCH Architecture to build for.\n"
+ " --conf-only Stop after configuring packages.\n"
+ " --full-paths Output full paths in analysis.\n"
+ //" --makefile Create a makefile for this package.\n"
+ " --max-depth NUM Maximum depth to show in analysis.\n"
+ " --prefix DIR Directory to install things to.\n"
+ " --warnings LIST Compiler warnings to use.\n";
+ }
+}
+
+/**
+Determines the source directory of a package. pkg-config is consulted first,
+and if it fails, the package path is searched for matches.
+*/
+FS::Path Builder::get_package_location(const string &name)
+{
+ // Try to get source directory with pkgconfig
+ list<string> argv;
+ argv.push_back("pkg-config");
+ argv.push_back("--variable=source");
+ argv.push_back(name);
+ if(verbose>=4)
+ cout<<"Running "<<join(argv.begin(), argv.end())<<'\n';
+ string srcdir=strip(run_command(argv));
+ if(!srcdir.empty())
+ return srcdir;
+
+ 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);
+ }
+ }
+ }
+
+ 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();
+}
+
+/**
+Loads the given build file.
+
+@param fn Path to the file
+
+@return 0 on success, -1 if the file could not be opened
+*/
+int Builder::load_build_file(const FS::Path &fn)
+{
+ try
+ {
+ IO::File inf(fn.str());
+ IO::Buffered in(inf);
+
+ if(verbose>=3)
+ cout<<"Reading "<<fn<<'\n';
+
+ DataFile::Parser parser(in, fn.str());
+ Loader loader(*this, fn.subpath(0, fn.size()-1));
+ loader.load(parser);
+ }
+ catch(const IO::FileNotFound &)
+ {
+ return -1;
+ }