]> git.tdb.fi Git - builder.git/commitdiff
Implement help
authorMikko Rasa <tdb@tdb.fi>
Fri, 20 Oct 2006 15:29:06 +0000 (15:29 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 20 Oct 2006 15:29:06 +0000 (15:29 +0000)
Support for package paths (for non-pkgconfig packages)

source/builder.cpp
source/builder.h
source/config.h
source/package.cpp
source/package.h

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):
index 077d7e3cf7de6e8b914081fd8dad9cf484199098..3dba62920a48d1821f242c3d915e550e041aa843 100644 (file)
@@ -24,8 +24,11 @@ public:
        Target   *get_target(const std::string &);
        Target   *get_header(const std::string &, const std::string &, const std::list<std::string> &);
        Target   *get_library(const std::string &, const std::list<std::string> &);
+       const Msp::Path::Path &get_cwd() const { return cwd; }
        int      main();
        ~Builder();
+
+       static void usage(const char *, bool);
 private:
        class Loader: public Msp::Parser::Loader
        {
@@ -66,6 +69,7 @@ private:
        bool        chrome;
        bool        conf_all;
        bool        build_all;
+       bool        help;
 
        int load_build_file(const Msp::Path::Path &);
        int create_targets();
@@ -73,6 +77,7 @@ private:
        void add_target(Target *);
        void update_hash(std::string &, const std::string &);
        int build();
+       void package_help();
        
        static Msp::Application::RegApp<Builder> reg;
 };
index 9a73880ac887f331e9eae93d0ccbd48892aff7fd..9747d99aae0ee339a1878a8be3e72c7d60489e09 100644 (file)
@@ -26,6 +26,7 @@ public:
 
        void add_option(const std::string &, const std::string &, const std::string &);
        const Option &get_option(const std::string &) const;
+       const OptionMap &get_options() const          { return options; }
        const Msp::Time::TimeStamp &get_mtime() const { return mtime; }
        bool is_option(const std::string &) const;
        bool process(const RawOptionMap &);
index c55e5f47272122951c2e370bc6c6d632e156eb40..d4022f5f3fae7b0f045ddea2087828d5eb987ad9 100644 (file)
@@ -7,6 +7,8 @@
 using namespace std;
 using namespace Msp;
 
+#include <iostream>
+
 Package::Package(Builder &b, const string &n, const Path::Path &s):
        builder(b),
        name(n),
@@ -19,7 +21,7 @@ Package::Package(Builder &b, const string &n, const vector<string> &info):
        builder(b),
        name(n),
        buildable(false),
-       build_info_ready(true)
+       build_info_ready(false)
 {
        for(vector<string>::const_iterator i=info.begin(); i!=info.end(); ++i)
        {
@@ -34,6 +36,11 @@ Package::Package(Builder &b, const string &n, const vector<string> &info):
        }
 }
 
+void Package::set_path(const Msp::Path::Path &p)
+{
+       path=builder.get_cwd()/p;
+}
+
 void Package::resolve_refs()
 {
        for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
@@ -47,53 +54,69 @@ void Package::create_build_info()
        if(build_info_ready)
                return;
        
-       for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+       if(buildable)
        {
-               if(!i->get_package())
-                       continue;
-               i->get_package()->create_build_info();
-               build_info.add(i->get_package()->get_exported_binfo());
-       }
+               for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+               {
+                       Package *pkg=i->get_package();
+                       if(!pkg)
+                               continue;
+                       if(pkg->get_need_path())
+                               pkg->set_path(config.get_option(pkg->get_name()+"_path").value);
+                       pkg->create_build_info();
+                       build_info.add(pkg->get_exported_binfo());
+                       export_binfo.add(pkg->get_exported_binfo());
+               }
        
-       build_info.cflags.push_back("-Wall");
-       build_info.cflags.push_back("-Wshadow");
-       build_info.cflags.push_back("-Wextra");
-       build_info.cflags.push_back("-Wpointer-arith");
-       build_info.cflags.push_back("-Wconversion");
-       build_info.cflags.push_back("-Werror");
+               build_info.cflags.push_back("-Wall");
+               build_info.cflags.push_back("-Wshadow");
+               build_info.cflags.push_back("-Wextra");
+               build_info.cflags.push_back("-Wpointer-arith");
+               build_info.cflags.push_back("-Wconversion");
+               build_info.cflags.push_back("-Werror");
+
+               unsigned flags=get_install_flags();
+
+               if(flags&INCLUDE)
+                       export_binfo.incpath.push_back((Path::Path(config.get_option("prefix").value)/"include").str());
+               if(flags&LIB)
+                       export_binfo.libpath.push_back((Path::Path(config.get_option("prefix").value)/"lib").str());
+
+               string optimize=config.get_option("optimize").value;
+               if(strtol(optimize))
+               {
+                       build_info.cflags.push_back("-O"+optimize);
+                       string cpu=config.get_option("cpu").value;
+                       if(cpu!="auto")
+                               build_info.cflags.push_back("-march="+cpu);
+               }
 
-       unsigned flags=get_install_flags();
+               if(strtobool(config.get_option("debug").value))
+               {
+                       build_info.cflags.push_back("-ggdb");
+                       build_info.defines.push_back("DEBUG");
+               }
 
-       if(flags&INCLUDE)
-               export_binfo.incpath.push_back((Path::Path(config.get_option("prefix").value)/"include").str());
-       if(flags&LIB)
-               export_binfo.libpath.push_back((Path::Path(config.get_option("prefix").value)/"lib").str());
+               build_info.unique();
 
-       string optimize=config.get_option("optimize").value;
-       if(strtol(optimize))
-       {
-               build_info.cflags.push_back("-O"+optimize);
-               string cpu=config.get_option("cpu").value;
-               if(cpu!="auto")
-                       build_info.cflags.push_back("-march="+cpu);
+               for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
+               {
+                       i->create_build_info();
+                       if(i->get_type()==Component::LIBRARY)
+                               export_binfo.libs.push_back(i->get_name());
+               }
        }
-
-       if(strtobool(config.get_option("debug").value))
+       else if(name=="fmod4")
        {
-               build_info.cflags.push_back("-ggdb");
-               build_info.defines.push_back("DEBUG");
+               export_binfo.libs.push_back("fmodex");
+               if(!path.empty())
+               {
+                       export_binfo.libpath.push_back((path/"api"/"lib").str());
+                       export_binfo.incpath.push_back((path/"api"/"inc").str());
+               }
        }
-
-       build_info.unique();
        export_binfo.unique();
 
-       for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
-       {
-               i->create_build_info();
-               if(i->get_type()==Component::LIBRARY)
-                       export_binfo.libs.push_back(i->get_name());
-       }
-
        build_info_ready=true;
 }
 
@@ -113,6 +136,7 @@ Package *Package::create(Builder &b, const string &name)
        argv.push_back(name);
        vector<string> info=split(run_command(argv));
        
+       bool need_path=false;
        if(info.empty())
        {
                if(name=="opengl")
@@ -121,11 +145,14 @@ Package *Package::create(Builder &b, const string &name)
                        info.push_back("-lpthread");
                else if(name=="gmpxx")
                        info.push_back("-lgmpxx");
+               else if(name=="fmod4")
+                       need_path=true;
                else
                        return 0;
        }
        
        Package *pkg=new Package(b, name, info);
+       pkg->need_path=need_path;
        return pkg;
 }
 
@@ -152,6 +179,9 @@ void Package::init_buildable()
        if(flags&DATA)
                config.add_option("includedir", "$prefix/share",   "Data installation directory");*/
 
+       for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+               config.add_option(i->get_name()+"_path", "", "Path for "+i->get_name());
+
        config.load(source/".options.cache");
 }
 
index bb2c41322c7dbd6185257159a1f7fff03ada4461..a1a9859136f7f262543f232391e480e6de2e915e 100644 (file)
@@ -32,6 +32,7 @@ public:
 
        Package(Builder &, const std::string &, const Msp::Path::Path &);
        Package(Builder &, const std::string &, const std::vector<std::string> &);
+       void                set_path(const Msp::Path::Path &);
        const std::string   &get_name() const       { return name; }
        const Msp::Path::Path &get_source() const   { return source; }
        const ComponentList &get_components() const { return components; }
@@ -41,6 +42,7 @@ public:
        const BuildInfo     &get_build_info() const { return build_info; }
        const BuildInfo     &get_exported_binfo() const { return export_binfo; }
        Builder             &get_builder() const    { return builder; }
+       bool                get_need_path() const   { return need_path; }
        void                resolve_refs();
        void                create_build_info();
        void                process_options(const RawOptionMap &);
@@ -67,6 +69,8 @@ private:
        ComponentList components;
        Config        config;
        bool          build_info_ready;
+       bool          need_path;
+       Msp::Path::Path path;
 
        void init_buildable();
        unsigned get_install_flags();