X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbuilder.cpp;h=63ae0613a737fc2939dec7e36e86113458777841;hb=43bd25ffcb0b4f7882773f4676b209a99cb73c04;hp=76522ad1aaa446f0f305f97881e0d2216491b694;hpb=04c316da6d5d90e43cba262f54d90ca231f703bf;p=builder.git diff --git a/source/builder.cpp b/source/builder.cpp index 76522ad..63ae061 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -1,24 +1,14 @@ -/* $Id$ - -This file is part of builder -Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - #include #include -#include -#include #include #include #include #include #include #include -#include #include #include -#include +#include #include #include #include @@ -54,6 +44,7 @@ void update_hash(string &hash, const string &value) Builder::Builder(int argc, char **argv): main_pkg(0), + native_arch(*this, string()), analyzer(0), build(false), clean(0), @@ -85,6 +76,7 @@ Builder::Builder(int argc, char **argv): getopt.add_option('j', "jobs", jobs, GetOpt::REQUIRED_ARG).set_help("Run NUM commands at once, whenever possible.", "NUM"); getopt.add_option('n', "dry-run", dry_run, GetOpt::NO_ARG).set_help("Don't actually do anything, only show what would be done."); getopt.add_option('v', "verbose", verbose, GetOpt::NO_ARG).set_help("Print more information about what's going on."); + getopt.add_option('x', "no-externals", no_externals, GetOpt::NO_ARG).set_help("Do not load external source packages."); getopt.add_option('A', "conf-all", conf_all, GetOpt::NO_ARG).set_help("Apply configuration to all packages."); getopt.add_option('B', "build-all", build_all, GetOpt::NO_ARG).set_help("Build all targets unconditionally."); getopt.add_option('C', "chdir", work_dir, GetOpt::REQUIRED_ARG).set_help("Change to DIR before doing anything else.", "DIR"); @@ -113,7 +105,7 @@ Builder::Builder(int argc, char **argv): else if(analyze_mode=="rdeps") analyzer->set_mode(Analyzer::RDEPS); else - throw UsageError("Invalid analyze mode"); + throw usage_error("Invalid analyze mode"); analyzer->set_max_depth(max_depth); analyzer->set_full_paths(full_paths); @@ -139,25 +131,29 @@ Builder::Builder(int argc, char **argv): cwd = FS::getcwd(); - utsname un; - string sysname = "native"; - if(uname(&un)==0) - sysname = tolower(un.sysname); - - native_arch = &archs.insert(ArchMap::value_type(sysname, Architecture(*this, sysname, true))).first->second; - native_arch->set_tool("CC", "gcc"); - native_arch->set_tool("CXX", "g++"); - native_arch->set_tool("LD", "gcc"); - native_arch->set_tool("LXX", "g++"); - native_arch->set_tool("AR", "ar"); + native_arch.set_tool("CC", "gcc"); + native_arch.set_tool("CXX", "g++"); + native_arch.set_tool("LD", "gcc"); + native_arch.set_tool("LXX", "g++"); + native_arch.set_tool("AR", "ar"); load_build_file((FS::get_sys_data_dir(argv[0], "builder")/"builderrc").str()); load_build_file((FS::get_user_data_dir("builder")/"rc").str()); if(arch.empty()) - current_arch = native_arch; + current_arch = &native_arch; else - current_arch = &get_architecture(arch); + current_arch = new Architecture(*this, arch); + + if(!current_arch->is_native()) + { + for(StringMap::const_iterator i=cross_prefixes.begin(); i!=cross_prefixes.end(); ++i) + if(current_arch->match_name(i->first)) + { + current_arch->set_cross_prefix(i->second); + break; + } + } if(prfx.empty()) { @@ -238,29 +234,42 @@ int Builder::main() return 0; } - if(!conf_only && create_targets()) - return 1; - - PackageList all_reqs = main_pkg->collect_requires(); - if(conf_only) return 0; + if(create_targets()) + return 1; + if(verbose>=2) - IO::print("Building on %s, for %s\n", native_arch->get_name(), current_arch->get_name()); + { + IO::print("Building on %s, for %s%s\n", native_arch.get_name(), + current_arch->get_name(), (current_arch->is_native() ? " (native)" : "")); + IO::print("Prefix is %s\n", prefix); + } + if(verbose>=1) - IO::print("%d active packages, %d targets\n", all_reqs.size(), targets.size()); + { + unsigned n_packages = 0; + for(PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) + if(i->second && i->second->is_configured()) + ++n_packages; + IO::print("%d active packages, %d targets\n", n_packages, targets.size()); + } + if(verbose>=2) { - for(PackageList::const_iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i) + for(PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) { - IO::print(" %s", (*i)->get_name()); - if(dynamic_cast(*i)) + if(!i->second->is_configured()) + continue; + + IO::print(" %s", i->second->get_name()); + if(dynamic_cast(i->second)) IO::print("*"); unsigned count = 0; unsigned to_be_built = 0; for(TargetMap::iterator j=targets.begin(); j!=targets.end(); ++j) - if(j->second->get_package()==*i) + if(j->second->get_package()==i->second) { ++count; if(j->second->get_rebuild()) @@ -319,25 +328,28 @@ string Builder::run_pkgconfig(const string &pkg, const string &what) int status; string res = run_command(argv, &status); if(status) - throw Exception(format("pkg-config for package %s failed", pkg)); + throw runtime_error(format("pkg-config for package %s failed", pkg)); return res; } Package *Builder::get_package(const string &name) { - PackageMap::iterator i = packages.find(format("%s/%s", name, current_arch->get_name())); + PackageMap::iterator i = packages.find(format("%s/%s", name, current_arch->get_system())); if(i==packages.end()) i = packages.find(name); if(i!=packages.end()) return i->second; - FS::Path path = get_package_location(name); - if(!path.empty() && !load_build_file(path/"Build")) + if(!no_externals) { - i = packages.find(name); - if(i!=packages.end()) - return i->second; + FS::Path path = get_package_location(name); + if(!path.empty() && !load_build_file(path/"Build")) + { + i = packages.find(name); + if(i!=packages.end()) + return i->second; + } } Package *pkg = 0; @@ -409,7 +421,7 @@ Target *Builder::get_header(const string &include, const FS::Path &from, const l if(current_arch->is_native()) syspath.push_back("/usr/include"); else - syspath.push_back("/usr/"+current_arch->get_prefix()+"/include"); + syspath.push_back("/usr/"+current_arch->get_cross_prefix()+"/include"); if(cxx_ver!="-") syspath.push_back((FS::Path("/usr/include/c++/")/cxx_ver).str()); @@ -442,9 +454,13 @@ Target *Builder::get_library(const string &lib, const list &path, LibMod { syspath.push_back("/lib"); syspath.push_back("/usr/lib"); + if(current_arch->match_name("pc-32-linux")) + syspath.push_back("/usr/lib/i386-linux-gnu"); + else if(current_arch->match_name("pc-64-linux")) + syspath.push_back("/usr/lib/x86_64-linux-gnu"); } else - syspath.push_back("/usr/"+current_arch->get_prefix()+"/lib"); + syspath.push_back("/usr/"+current_arch->get_cross_prefix()+"/lib"); if(verbose>=5) IO::print("Looking for library %s with path %s\n", lib, join(path.begin(), path.end())); @@ -460,15 +476,6 @@ Target *Builder::get_library(const string &lib, const list &path, LibMod return tgt; } -const Architecture &Builder::get_architecture(const string &arch) const -{ - ArchMap::const_iterator i = archs.find(arch); - if(i==archs.end()) - throw KeyError("Unknown architecture", arch); - - return i->second; -} - void Builder::apply_profile_template(Config &config, const string &pt) const { vector parts = split(pt, '-'); @@ -488,7 +495,13 @@ void Builder::problem(const string &p, const string &d) problems.push_back(Problem(p, d)); } -void Builder::add_target(Target *t) +void Builder::add_target(FileTarget *t) +{ + targets.insert(TargetMap::value_type(t->get_path().str(), t)); + new_tgts.push_back(t); +} + +void Builder::add_target(VirtualTarget *t) { targets.insert(TargetMap::value_type(t->get_name(), t)); new_tgts.push_back(t); @@ -569,7 +582,7 @@ int Builder::load_build_file(const FS::Path &fn) Loader loader(*this, fn.subpath(0, fn.size()-1)); loader.load(parser); } - catch(const IO::FileNotFound &) + catch(const IO::file_not_found &) { return -1; } @@ -590,10 +603,12 @@ int Builder::create_targets() Target *tarballs = new VirtualTarget(*this, "tarballs"); world->add_depend(tarballs); - PackageList all_reqs = main_pkg->collect_requires(); - for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i) + for(PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) { - SourcePackage *spkg = dynamic_cast(*i); + if(!i->second || !i->second->is_configured()) + continue; + + SourcePackage *spkg = dynamic_cast(i->second); if(!spkg) continue; @@ -621,7 +636,7 @@ int Builder::create_targets() // Apply what-ifs for(StringList::iterator i=what_if.begin(); i!=what_if.end(); ++i) { - Target *tgt = get_target((cwd/ *i).str()); + FileTarget *tgt = dynamic_cast(get_target((cwd/ *i).str())); if(!tgt) { IO::print(IO::cerr, "Unknown what-if target %s\n", *i); @@ -632,7 +647,6 @@ int Builder::create_targets() // Make the cmdline target depend on all targets mentioned on the command line Target *cmdline = new VirtualTarget(*this, "cmdline"); - bool build_world = false; for(list::iterator i=cmdline_targets.begin(); i!=cmdline_targets.end(); ++i) { Target *tgt = get_target(*i); @@ -643,8 +657,7 @@ int Builder::create_targets() IO::print("I don't know anything about %s\n", *i); return -1; } - if(tgt==world) - build_world = true; + cmdline->add_depend(tgt); } @@ -677,7 +690,8 @@ Target *Builder::get_library(const string &lib, const FS::Path &path, LibMode mo if(mode!=ALL_STATIC) { - if(current_arch->get_name()=="win32") + // XXX Should probably let the Architecture populate the list + if(current_arch->get_system()=="windows") { candidates.push_back("lib"+lib+".dll"); candidates.push_back(lib+".dll"); @@ -689,7 +703,7 @@ Target *Builder::get_library(const string &lib, const FS::Path &path, LibMode mo /* Static libraries are always considered, since sometimes shared versions may not be available */ candidates.push_back("lib"+lib+".a"); - if(current_arch->get_name()=="win32") + if(current_arch->get_system()=="windows") candidates.push_back("lib"+lib+".dll.a"); for(StringList::iterator i=candidates.begin(); i!=candidates.end(); ++i) @@ -699,9 +713,7 @@ Target *Builder::get_library(const string &lib, const FS::Path &path, LibMode mo if(tgt) { - Target *real_tgt = tgt; - if(Install *inst = dynamic_cast(tgt)) - real_tgt = &inst->get_source(); + Target *real_tgt = tgt->get_real_target(); /* Ignore dynamic libraries from local packages unless library mode is DYNAMIC */ @@ -850,7 +862,6 @@ void Builder::package_help() } } -Application::RegApp Builder::reg; string Builder::usagemsg; string Builder::helpmsg; @@ -859,19 +870,12 @@ Builder::Loader::Loader(Builder &b, const FS::Path &s): bld(b), src(s) { - add("architecture", &Loader::architecture); add("binary_package", &Loader::binpkg); + add("cross_prefix", &Loader::cross_prefix); add("profile", &Loader::profile); add("package", &Loader::package); } -void Builder::Loader::architecture(const string &n) -{ - Architecture arch(bld, n); - load_sub(arch); - bld.archs.insert(ArchMap::value_type(n, arch)); -} - void Builder::Loader::binpkg(const string &n) { BinaryPackage *pkg = new BinaryPackage(bld, n); @@ -879,6 +883,11 @@ void Builder::Loader::binpkg(const string &n) bld.packages.insert(PackageMap::value_type(n, pkg)); } +void Builder::Loader::cross_prefix(const string &a, const string &p) +{ + bld.cross_prefixes[a] = p; +} + void Builder::Loader::profile(const string &n) { StringMap prf;