]> git.tdb.fi Git - builder.git/blobdiff - source/builder.cpp
Refactor package configuration
[builder.git] / source / builder.cpp
index c271c2bb56cf81b211efd8013e4ade5de0e92b59..38fbc1703f2d3bd7c68e17dc1dc9770a832284a3 100644 (file)
@@ -48,6 +48,7 @@ Builder::Builder(int argc, char **argv):
        getopt.add_option(GetOpt::Option('C', "chdir", GetOpt::REQUIRED));
        getopt.add_option(GetOpt::Option('W', "what-if", GetOpt::REQUIRED));
        getopt.add_option(GetOpt::Option("chrome", GetOpt::NONE));
+       getopt.add_option(GetOpt::Option("conf-only", GetOpt::NONE));
        getopt.add_option(GetOpt::Option("full-paths", GetOpt::NONE));
        getopt.add_option(GetOpt::Option("max-depth", GetOpt::REQUIRED));
        int index=getopt(argc, argv);
@@ -82,6 +83,7 @@ Builder::Builder(int argc, char **argv):
        jobs=max(strtol(getopt['j'].arg()), 1L);
        chrome=getopt["chrome"];
        conf_all=getopt['A'];
+       conf_only=getopt["conf-only"];
        build_file=getopt['f'].arg();
        build_all=getopt['B'];
        help=getopt['h'];
@@ -189,51 +191,62 @@ Target *Builder::get_header(const string &include, const string &from, const lis
 
        string fn=include.substr(1);
        Target *tgt=0;
-       if(include[0]=='"' && (tgt=check_header(Path::Path(from)/fn)))
-               return tgt;
-       if((tgt=check_header(Path::Path("/usr/include")/fn)))
-               return tgt;
+       if(include[0]=='"' && (tgt=get_header(Path::Path(from)/fn)))
+               ;
+       else if((tgt=get_header(Path::Path("/usr/include")/fn)))
+               ;
        //XXX Determine the C++ header location dynamically
-       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(cwd/ *j/fn)))
-                       return tgt;
+       else if((tgt=get_header(Path::Path("/usr/include/c++/4.1.2")/fn)))
+               ;
+       else
+       {
+               for(list<string>::const_iterator j=path.begin(); (j!=path.end() && !tgt); ++j)
+                       tgt=get_header(cwd/ *j/fn);
+       }
+
+       includes.insert(TargetMap::value_type(id, tgt));
        
-       return 0;
+       return tgt;
 }
 
 /**
 Tries to locate a library with the given library path.  Considers known targets
 as well as existing files.  If a matching target is not found but a file exists,
 a new SystemLibrary target will be created and returned.
+
+@param   lib   Name of the library to get (without "lib" prefix or extension)
+@param   path  List of paths to search for the library
+@param   mode  Shared / shared mode - 0: always shared, 1: static for buildable
+               packages, otherwise shared, 2: always static
+
+@return  Some kind of library target, if a match was found
 */
-Target *Builder::get_library(const string &lib, const list<string> &path)
+Target *Builder::get_library(const string &lib, const list<string> &path, unsigned mode)
 {
        string hash(8, 0);
        for(list<string>::const_iterator i=path.begin(); i!=path.end(); ++i)
                update_hash(hash, *i);
 
+       //XXX Incorporate mode into id
        string id=hash+lib;
        TargetMap::iterator i=libraries.find(id);
        if(i!=libraries.end())
                return i->second;
 
-       string basename="lib"+lib+".so";
-       for(list<string>::const_iterator j=path.begin(); j!=path.end(); ++j)
+       Target *tgt=0;
+       if((tgt=get_library(lib, "/lib", mode)))
+               ;
+       else if((tgt=get_library(lib, "/usr/lib", mode)))
+               ;
+       else
        {
-               string full=(cwd/ *j/basename).str();
-               Target *tgt=get_target(full);
-               if(tgt) return tgt;
-               
-               if(Path::exists(full))
-               {
-                       add_target(tgt=new SystemLibrary(*this, full));
-                       return tgt;
-               }
+               for(list<string>::const_iterator j=path.begin(); (j!=path.end() && !tgt); ++j)
+                       tgt=get_library(lib, cwd/ *j, mode);
        }
 
-       return 0;
+       libraries.insert(TargetMap::value_type(id, tgt));
+
+       return tgt;
 }
 
 int Builder::main()
@@ -249,12 +262,12 @@ int Builder::main()
        while(!new_pkgs.empty())
        {
                Package *pkg=new_pkgs.front();
-               if(pkg==default_pkg || conf_all)
-                       pkg->process_options(cmdline_options);
                new_pkgs.erase(new_pkgs.begin());
                pkg->resolve_refs();
        }
 
+       default_pkg->configure(cmdline_options, conf_all?2:1);
+
        if(help)
        {
                usage("builder", false);
@@ -278,7 +291,8 @@ int Builder::main()
                return 1;
        }
 
-       default_pkg->create_build_info();
+       if(conf_only)
+               return 0;
 
        if(create_targets())
                return 1;
@@ -352,6 +366,7 @@ void Builder::usage(const char *argv0, bool brief)
                        "  -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"
+                       "  --conf-only         Stop after configuring packages.\n"
                        "  --full-paths        Output full paths in analysis.\n"
                        "  --max-depth NUM     Maximum depth to show in analysis.\n";
        }
@@ -562,7 +577,7 @@ int Builder::create_targets()
 Check if a header exists, either as a target or a file.  Either an existing
 target or a new SystemHeader target will be returned.
 */
-Target *Builder::check_header(const Msp::Path::Path &fn)
+Target *Builder::get_header(const Msp::Path::Path &fn)
 {
        Target *tgt=get_target(fn.str());
        if(tgt) return tgt;
@@ -575,6 +590,33 @@ Target *Builder::check_header(const Msp::Path::Path &fn)
        return 0;
 }
 
+Target *Builder::get_library(const string &lib, const Path::Path &path, unsigned mode)
+{
+       string full;
+       if(mode>=1)
+       {
+               full=(path/("lib"+lib+".a")).str();
+               Target *tgt=get_target(full);
+               // Targets can only be associated with buildable packages (or no package at all)
+               if(tgt && (tgt->get_package() || mode==2)) return tgt;
+       }
+       if(mode<=1)
+       {
+               full=(path/("lib"+lib+".so")).str();
+               Target *tgt=get_target(full);
+               if(tgt) return tgt;
+       }
+
+       if(Path::exists(full))
+       {
+               Target *tgt=new SystemLibrary(*this, full);
+               add_target(tgt);
+               return tgt;
+       }
+
+       return 0;
+}
+
 /**
 Adds a target to both the target map and the new target queue.
 */