]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Implement help
[builder.git] / source / builder.cpp
index 274b153e70c566a2fa2dff2147918cc2d2474a37..0b1d1bf55163b3a8c44d2a767bcb4e790a0b7b7a 100644 (file)
@@ -26,7 +26,6 @@ using namespace Msp;
 
 Builder::Builder(int argc, char **argv):
        verbose(1),
-       cwd(Path::getcwd()),
        build_file("Build"),
        do_build(true),
        analyzer(0),
@@ -34,21 +33,21 @@ Builder::Builder(int argc, char **argv):
        chrome(false)
 {
        GetOpt getopt;
-       getopt.add_option(GetOpt::Option('v', "verbose", GetOpt::NONE));
        getopt.add_option(GetOpt::Option('a', "analyze", GetOpt::REQUIRED));
        getopt.add_option(GetOpt::Option('b', "build", GetOpt::NONE));
-       getopt.add_option(GetOpt::Option("max-depth", GetOpt::REQUIRED));
+       getopt.add_option(GetOpt::Option('c', "clean", GetOpt::NONE));
+       getopt.add_option(GetOpt::Option('f', "file", GetOpt::REQUIRED, "Build"));
+       getopt.add_option(GetOpt::Option('h', "help", GetOpt::NONE));
+       getopt.add_option(GetOpt::Option('j', "jobs", GetOpt::REQUIRED, "1"));
        getopt.add_option(GetOpt::Option('n', "dry-run", GetOpt::NONE));
-       getopt.add_option(GetOpt::Option('W', "what-if", GetOpt::REQUIRED));
+       getopt.add_option(GetOpt::Option('v', "verbose", GetOpt::NONE));
+       getopt.add_option(GetOpt::Option('A', "conf-all", GetOpt::NONE));
        getopt.add_option(GetOpt::Option('B', "build-all", GetOpt::NONE));
        getopt.add_option(GetOpt::Option('C', "chdir", GetOpt::REQUIRED));
-       getopt.add_option(GetOpt::Option('j', "jobs", GetOpt::REQUIRED, "1"));
-       getopt.add_option(GetOpt::Option('h', "help", GetOpt::NONE));
-       getopt.add_option(GetOpt::Option('c', "clean", GetOpt::NONE));
-       getopt.add_option(GetOpt::Option('f', "file", GetOpt::REQUIRED, "Build"));
+       getopt.add_option(GetOpt::Option('W', "what-if", GetOpt::REQUIRED));
        getopt.add_option(GetOpt::Option("chrome", GetOpt::NONE));
        getopt.add_option(GetOpt::Option("full-paths", GetOpt::NONE));
-       getopt.add_option(GetOpt::Option('A', "conf-all", GetOpt::NONE));
+       getopt.add_option(GetOpt::Option("max-depth", GetOpt::REQUIRED));
        int index=getopt(argc, argv);
 
        verbose+=getopt['v'].count();
@@ -83,6 +82,7 @@ Builder::Builder(int argc, char **argv):
        conf_all=getopt['A'];
        build_file=getopt['f'].arg();
        build_all=getopt['B'];
+       help=getopt['h'];
 
        if(getopt['C'])
                chdir(getopt['C'].arg().c_str());
@@ -102,6 +102,8 @@ Builder::Builder(int argc, char **argv):
 
        if(getopt['W'])
                what_if.push_back(getopt['W'].arg());
+
+       cwd=Path::getcwd();
 }
 
 /**
@@ -191,7 +193,7 @@ Target *Builder::get_header(const string &include, const string &from, const lis
        if((tgt=check_header(Path::Path("/usr/include/c++/4.1.2")/fn)))
                return tgt;
        for(list<string>::const_iterator j=path.begin(); j!=path.end(); ++j)
-               if((tgt=check_header(Path::getcwd()/ *j/fn)))
+               if((tgt=check_header(cwd/ *j/fn)))
                        return tgt;
        
        return 0;
@@ -211,7 +213,7 @@ Target *Builder::get_library(const string &lib, const list<string> &path)
        string basename="lib"+lib+".so";
        for(list<string>::const_iterator j=path.begin(); j!=path.end(); ++j)
        {
-               string full=(Path::getcwd()/ *j/basename).str();
+               string full=(cwd/ *j/basename).str();
                Target *tgt=get_target(full);
                if(tgt) return tgt;
                
@@ -244,6 +246,14 @@ int Builder::main()
                pkg->resolve_refs();
        }
 
+       if(help)
+       {
+               usage("builder", false);
+               cout<<'\n';
+               package_help();
+               return 0;
+       }
+
        std::list<std::string> missing;
        for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
                if(!i->second)
@@ -286,8 +296,9 @@ int Builder::main()
                                cout<<" ("<<count<<" targets";
                                if(ood_count)
                                        cout<<", "<<ood_count<<" out-of-date";
-                               cout<<")\n";
+                               cout<<')';
                        }
+                       cout<<'\n';
                }
        }
 
@@ -309,6 +320,34 @@ Builder::~Builder()
        delete analyzer;
 }
 
+void Builder::usage(const char *argv0, bool brief)
+{
+       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] [--full-paths] [--max-depth NUM] [<target> ...]";
+       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"
+                       "  -W, --what-if FILE  Pretend that FILE has changed.\n"
+                       "  --chrome            Use extra chrome to print status.\n"
+                       "  --full-paths        Output full paths in analysis.\n"
+                       "  --max-depth NUM     Maximum depth to show in analysis.\n";
+       }
+}
+
 int Builder::load_build_file(const Path::Path &fn)
 {
        ifstream in(fn.str().c_str());
@@ -569,6 +608,28 @@ int Builder::build()
        return fail?-1:0;
 }
 
+void Builder::package_help()
+{
+       const Config &config=default_pkg->get_config();
+       const Config::OptionMap &options=config.get_options();
+
+       cout<<"Required packages:\n  ";
+       const list<PackageRef> &requires=default_pkg->get_requires();
+       for(list<PackageRef>::const_iterator i=requires.begin(); i!=requires.end(); ++i)
+       {
+               if(i!=requires.begin())
+                       cout<<", ";
+               cout<<i->get_name();
+       }
+       cout<<"\n\n";
+       cout<<"Package configuration:\n";
+       for(Config::OptionMap::const_iterator i=options.begin(); i!=options.end(); ++i)
+       {
+               const Config::Option &opt=i->second;
+               cout<<"  "<<opt.name<<": "<<opt.descr<<" ("<<opt.value<<") ["<<opt.defv<<"]\n";
+       }
+}
+
 Application::RegApp<Builder> Builder::reg;
 
 Builder::Loader::Loader(Builder &b, const Path::Path &s):