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);
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'];
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()
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);
return 1;
}
- default_pkg->create_build_info();
+ if(conf_only)
+ return 0;
if(create_targets())
return 1;
" -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";
}
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;
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.
*/