X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbuilder.cpp;h=63323310c5226d152b2e064b58c1df4ff099069f;hb=3f541fceb5aeb5d685ceb2363ebbca1cb1c3eb84;hp=9548288131e45fe975d548672bf69866b773848b;hpb=8b9f2196ec0a930992614f174b7970c2ed523699;p=builder.git diff --git a/source/builder.cpp b/source/builder.cpp index 9548288..6332331 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -37,20 +37,21 @@ Builder::Builder(int argc, char **argv): package_manager(*this), main_pkg(0), native_arch(*this, string()), + build_type(0), vfs(*this), analyzer(0), build(false), clean(0), dry_run(false), help(false), - verbose(1), show_progress(false), build_file("Build"), jobs(1), conf_all(false), conf_only(false), build_all(false), - create_makefile(false) + create_makefile(false), + tempdir("temp") { string analyze_mode; string work_dir; @@ -58,8 +59,13 @@ Builder::Builder(int argc, char **argv): unsigned max_depth = 5; StringList cmdline_warn; string prfx; + string temp_str; string arch; bool no_externals = false; + unsigned verbose = 1; + bool silent = false; + list log_channels; + string build_type_name; GetOpt getopt; getopt.add_option('a', "analyze", analyze_mode, GetOpt::REQUIRED_ARG).set_help("Perform analysis. MODE can be deps, alldeps or rebuild.", "MODE"); @@ -68,7 +74,10 @@ Builder::Builder(int argc, char **argv): getopt.add_option('f', "file", build_file, GetOpt::REQUIRED_ARG).set_help("Read info from FILE instead of Build.", "FILE"); getopt.add_option('h', "help", help, GetOpt::NO_ARG).set_help("Print this message."); getopt.add_option('j', "jobs", jobs, GetOpt::REQUIRED_ARG).set_help("Run NUM commands at once, whenever possible.", "NUM"); + getopt.add_option('l', "log", log_channels, GetOpt::REQUIRED_ARG).set_help("Set log channels to be displayed.", "LIST"); 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('s', "silent", silent, GetOpt::NO_ARG).set_help("Don't print any messages other than errors."); + getopt.add_option('t', "build-type", build_type_name, GetOpt::REQUIRED_ARG).set_help("Set build type.", "TYPE"); 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."); @@ -81,11 +90,47 @@ Builder::Builder(int argc, char **argv): getopt.add_option( "full-paths", full_paths, GetOpt::NO_ARG).set_help("Output full paths in analysis."); getopt.add_option( "max-depth", max_depth, GetOpt::REQUIRED_ARG).set_help("Maximum depth to show in analysis.", "NUM"); getopt.add_option( "prefix", prfx, GetOpt::REQUIRED_ARG).set_help("Directory to install things to.", "DIR"); + getopt.add_option( "tempdir", temp_str, GetOpt::REQUIRED_ARG).set_help("Store temporary files in DIR.", "DIR"); getopt.add_option( "warnings", cmdline_warn, GetOpt::REQUIRED_ARG).set_help("Compiler warnings to use.", "LIST"); usagemsg = getopt.generate_usage(argv[0])+" [ ...]"; helpmsg = getopt.generate_help(); getopt(argc, argv); + if(silent) + --verbose; + if(verbose>=1) + { + logger.enable_channel("summary"); + logger.enable_channel("tasks"); + } + if(verbose>=2) + { + logger.enable_channel("environment"); + logger.enable_channel("packages"); + logger.enable_channel("commands"); + } + if(verbose>=3) + { + logger.enable_channel("packagemgr"); + logger.enable_channel("configure"); + } + if(verbose>=4) + { + logger.enable_channel("files"); + logger.enable_channel("auxcommands"); + } + if(verbose>=5) + { + logger.enable_channel("tools"); + logger.enable_channel("vfs"); + } + for(list::const_iterator i=log_channels.begin(); i!=log_channels.end(); ++i) + { + vector parts = split(*i, ','); + for(vector::const_iterator j=parts.begin(); j!=parts.end(); ++j) + logger.enable_channel(*j); + } + if(!analyze_mode.empty()) { analyzer = new Analyzer(*this); @@ -127,31 +172,13 @@ Builder::Builder(int argc, char **argv): package_manager.set_no_externals(no_externals); - 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; else 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; - } - } - - toolchain.add_tool(new GnuCCompiler(*this)); - toolchain.add_tool(new GnuCxxCompiler(*this)); - toolchain.add_tool(new GnuLinker(*this)); - toolchain.add_tool(new GnuArchiver(*this)); - toolchain.add_tool(new Copy(*this)); - toolchain.add_tool(new Tar(*this)); - toolchain.add_tool(new PkgConfigGenerator(*this)); + 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(prfx.empty()) { @@ -163,6 +190,17 @@ Builder::Builder(int argc, char **argv): else prefix = FS::getcwd()/prfx; + if(!temp_str.empty()) + tempdir = temp_str; + + if(!build_type_name.empty()) + { + BuildTypeMap::iterator i = build_types.find(build_type_name); + if(i==build_types.end()) + throw usage_error("Unknown build type"); + build_type = &i->second; + } + warnings.push_back("all"); warnings.push_back("extra"); warnings.push_back("shadow"); @@ -173,6 +211,14 @@ Builder::Builder(int argc, char **argv): vector warns = split(*i, ','); warnings.insert(warnings.end(), warns.begin(), warns.end()); } + + toolchain.add_tool(new GnuCCompiler(*this, *current_arch)); + toolchain.add_tool(new GnuCxxCompiler(*this, *current_arch)); + toolchain.add_tool(new GnuLinker(*this, *current_arch)); + toolchain.add_tool(new GnuArchiver(*this, *current_arch)); + toolchain.add_tool(new Copy(*this)); + toolchain.add_tool(new Tar(*this)); + toolchain.add_tool(new PkgConfigGenerator(*this)); } Builder::~Builder() @@ -233,34 +279,28 @@ int Builder::main() if(create_targets()) return 1; - if(verbose>=2) - { - 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); - } + logger.log("environment", format("Building on %s, for %s%s", native_arch.get_name(), + current_arch->get_name(), (current_arch->is_native() ? " (native)" : ""))); + logger.log("environment", format("Prefix is %s", prefix)); + if(tempdir.is_absolute()) + logger.log("environment", format("Temporary directory is %s", tempdir)); + else + logger.log("environment", format("Using per-package temporary directory %s", tempdir)); + if(build_type) + logger.log("environment", format("Build type is %s", build_type->get_name())); - if(verbose>=1) + const PackageManager::PackageMap &packages = package_manager.get_packages(); + list package_details; + for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) { - const PackageManager::PackageMap &packages = package_manager.get_packages(); - unsigned n_packages = 0; - for(PackageManager::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(!i->second || !i->second->is_configured()) + continue; - if(verbose>=2) - { - const PackageManager::PackageMap &packages = package_manager.get_packages(); - for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) + string line = i->second->get_name(); + if(dynamic_cast(i->second)) { - if(!i->second->is_configured()) - continue; + line += '*'; - 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) @@ -272,15 +312,20 @@ int Builder::main() } if(count) { - IO::print(" (%d targets", count); + line += format(" (%d targets", count); if(to_be_built) - IO::print(", %d to be built", to_be_built); - IO::print(")"); + line += format(", %d to be built", to_be_built); + line += ')'; } - IO::print("\n"); } + + package_details.push_back(line); } + logger.log("summary", format("%d active packages, %d targets", package_details.size(), targets.size())); + for(list::const_iterator i=package_details.begin(); i!=package_details.end(); ++i) + logger.log("packages", *i); + if(analyzer) analyzer->analyze(); @@ -310,20 +355,6 @@ Target *Builder::get_target(const string &n) const return 0; } -void Builder::apply_profile_template(Config &config, const string &pt) const -{ - vector parts = split(pt, '-'); - - for(vector::iterator i=parts.begin(); i!=parts.end(); ++i) - { - ProfileTemplateMap::const_iterator j = profile_tmpl.find(*i); - if(j==profile_tmpl.end()) - continue; - - config.update(j->second); - } -} - void Builder::problem(const string &p, const string &d) { problems.push_back(Problem(p, d)); @@ -357,8 +388,7 @@ int Builder::load_build_file(const FS::Path &fn) IO::BufferedFile in(fn.str()); - if(verbose>=3) - IO::print("Reading %s\n", fn); + logger.log("files", format("Reading %s", fn)); DataFile::Parser parser(in, fn.str()); Loader loader(*this, fn.subpath(0, fn.size()-1)); @@ -372,13 +402,13 @@ int Builder::create_targets() Target *world = new VirtualTarget(*this, "world"); Target *def_tgt = new VirtualTarget(*this, "default"); - world->add_depend(def_tgt); + world->add_depend(*def_tgt); Target *install = new VirtualTarget(*this, "install"); - world->add_depend(install); + world->add_depend(*install); Target *tarballs = new VirtualTarget(*this, "tarballs"); - world->add_depend(tarballs); + world->add_depend(*tarballs); const PackageManager::PackageMap &packages = package_manager.get_packages(); for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) @@ -400,7 +430,7 @@ int Builder::create_targets() return -1; } - cmdline->add_depend(tgt); + cmdline->add_depend(*tgt); } cmdline->prepare(); @@ -424,9 +454,11 @@ int Builder::create_targets() i->second->force_rebuild(); } - for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) - if(SourcePackage *spkg = dynamic_cast(i->second)) - spkg->get_deps_cache().save(); + if(!dry_run) + { + for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) + i->second->save_caches(); + } return 0; } @@ -442,11 +474,10 @@ int Builder::do_build() if(!total) { - IO::print("Already up to date\n"); + logger.log("summary", "Already up to date"); return 0; } - if(verbose>=1) - IO::print("Will build %d target%s\n", total, (total!=1 ? "s" : "")); + logger.log("summary", format("Will build %d target%s", total, (total!=1 ? "s" : ""))); vector tasks; @@ -463,12 +494,11 @@ int Builder::do_build() if(tgt) { if(tgt->get_tool()) - IO::print("%-4s %s\n", tgt->get_tool()->get_tag(), tgt->get_name()); + logger.log("tasks", format("%-4s %s", tgt->get_tool()->get_tag(), tgt->get_name())); Task *task = tgt->build(); if(task) { - if(verbose>=2) - IO::print("%s\n", task->get_command()); + logger.log("commands", format("%s", task->get_command())); if(dry_run) { task->signal_finished.emit(true); @@ -512,9 +542,9 @@ int Builder::do_build() if(show_progress) IO::print("\033[K"); if(fail) - IO::print("Build failed\n"); + logger.log("summary", "Build failed"); else if(show_progress) - IO::print("Build complete\n"); + logger.log("summary", "Build complete"); return fail; } @@ -578,51 +608,53 @@ string Builder::helpmsg; Builder::Loader::Loader(Builder &b, const FS::Path &s): - bld(b), + DataFile::ObjectLoader(b), src(s) { + add("architecture", &Loader::architecture); add("binary_package", &Loader::binpkg); - add("cross_prefix", &Loader::cross_prefix); + add("build_type", &Loader::build_type); add("profile", &Loader::profile); add("package", &Loader::package); } +void Builder::Loader::architecture(const string &n) +{ + if(obj.current_arch->match_name(n)) + load_sub(*obj.current_arch); +} + void Builder::Loader::binpkg(const string &n) { - BinaryPackage *pkg = new BinaryPackage(bld, n); + BinaryPackage *pkg = new BinaryPackage(obj, n); load_sub(*pkg); } -void Builder::Loader::cross_prefix(const string &a, const string &p) +void Builder::Loader::build_type(const string &n) { - bld.cross_prefixes[a] = p; + BuildType btype(n); + load_sub(btype); + BuildTypeMap::iterator i = obj.build_types.insert(BuildTypeMap::value_type(n, btype)).first; + if(!obj.build_type) + obj.build_type = &i->second; } -void Builder::Loader::profile(const string &n) +void Builder::Loader::profile(const string &) { - StringMap prf; - ProfileLoader ldr(prf); - load_sub_with(ldr); - bld.profile_tmpl.insert(ProfileTemplateMap::value_type(n, prf)); + IO::print("Profiles are deprecated\n"); } void Builder::Loader::package(const string &n) { - SourcePackage *pkg = new SourcePackage(bld, n, src); - if(!bld.main_pkg) - bld.main_pkg = pkg; - - load_sub(*pkg); -} - + SourcePackage *pkg = new SourcePackage(obj, n, src); + if(!obj.main_pkg) + obj.main_pkg = pkg; -Builder::ProfileLoader::ProfileLoader(StringMap &p): - profile(p) -{ - add("option", &ProfileLoader::option); -} + if(obj.conf_all || pkg==obj.main_pkg) + load_sub(*pkg, obj.cmdline_options); + else + load_sub(*pkg); -void Builder::ProfileLoader::option(const string &o, const string &v) -{ - profile.insert(StringMap::value_type(o, v)); + if(obj.build_type) + pkg->set_build_type(*obj.build_type); }