diff options
Diffstat (limited to 'bpkg/bpkg.cxx')
-rw-r--r-- | bpkg/bpkg.cxx | 142 |
1 files changed, 112 insertions, 30 deletions
diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx index 2a9fb6d..b5eaf7d 100644 --- a/bpkg/bpkg.cxx +++ b/bpkg/bpkg.cxx @@ -1,7 +1,11 @@ // file : bpkg/bpkg.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file +#include <bpkg/bpkg.hxx> + #include <limits> +#include <cstdlib> // getenv() +#include <cstring> // strcmp() #include <iostream> #include <exception> // set_terminate(), terminate_handler #include <type_traits> // enable_if, is_base_of @@ -13,9 +17,6 @@ #include <libbuild2/types.hxx> #include <libbuild2/utility.hxx> #include <libbuild2/module.hxx> -#include <libbuild2/context.hxx> -#include <libbuild2/scheduler.hxx> -#include <libbuild2/file-cache.hxx> #include <libbuild2/b-options.hxx> #include <libbuild2/b-cmdline.hxx> @@ -32,6 +33,9 @@ #include <libbuild2/cxx/init.hxx> #include <libbuild2/version/init.hxx> +#include <libbuild2/bash/init.hxx> +#include <libbuild2/cli/init.hxx> + #include <bpkg/types.hxx> #include <bpkg/utility.hxx> @@ -47,6 +51,7 @@ #include <bpkg/cfg-link.hxx> #include <bpkg/cfg-unlink.hxx> +#include <bpkg/pkg-bindist.hxx> #include <bpkg/pkg-build.hxx> #include <bpkg/pkg-checkout.hxx> #include <bpkg/pkg-clean.hxx> @@ -106,8 +111,6 @@ namespace bpkg static const char* build2_argv0; - // Use build2_sched.started() to check if already initialized. - // void build2_init (const common_options& co) { @@ -155,26 +158,39 @@ namespace bpkg if (bo.help () || bo.version ()) fail << "--help or --version specified with --build-option"; + + // Make sure someone didn't specify a non-global override with + // --build-option, which messes our global/package-specific config + // variable split. + // + for (const string& v: bc.cmd_vars) + { + if (v[0] != '!') + fail << "non-global configuration variable '" << v + << "' specified with --build-option"; + } } build2_cmd_vars = move (bc.cmd_vars); init_diag (bc.verbosity, bo.silent (), - (bc.progress ? bc.progress : - co.progress () ? optional<bool> (true) : - co.no_progress () ? optional<bool> (false) : nullopt), + (bc.progress ? bc.progress : + co.progress () ? optional<bool> (true) : + co.no_progress () ? optional<bool> (false) : nullopt), + (bc.diag_color ? bc.diag_color : + co.diag_color () ? optional<bool> (true) : + co.no_diag_color () ? optional<bool> (false) : nullopt), bo.no_line (), bo.no_column (), - bpkg::stderr_term); + bpkg::stderr_term.has_value ()); - // Note that we pretend to be in the serial-stop mode even though we may - // build build system modules in parallel in order to get better - // diagnostics for the common case. + // Also note that we now use this in pkg_configure(), but serial-stop + // is good for it as well. // init (&build2_terminate, build2_argv0, - true /* serial_stop */, + false /* serial_stop */, bc.mtime_check, bc.config_sub, bc.config_guess); @@ -191,6 +207,9 @@ namespace bpkg load_builtin_module (&build2::version::build2_version_load); load_builtin_module (&build2::in::build2_in_load); + load_builtin_module (&build2::bash::build2_bash_load); + load_builtin_module (&build2::cli::build2_cli_load); + // Note that while all we need is serial execution (all we do is load), // in the process we may need to update some build system modules (while // we only support built-in and standard pre-installed modules here, we @@ -200,6 +219,10 @@ namespace bpkg // serial execution, which is relatively cheap. The module building // logic will then re-tune it to parallel if and when necessary. // + // Note that we now also use this in pkg_configure() where we re-tune + // the scheduler (it may already have been initialized as part of the + // package skeleton work). + // build2_sched.startup (1 /* max_active */, 1 /* init_active */, bc.max_jobs, @@ -212,7 +235,7 @@ namespace bpkg } catch (const build2::failed&) { - throw failed (); // Assume the diagnostics has already been issued. + throw bpkg::failed (); // Assume the diagnostics has already been issued. } } @@ -441,8 +464,25 @@ init (const common_options& co, { optional<dir_path> extra; if (o.default_options_specified ()) + { extra = o.default_options (); + // Note that load_default_options() expects absolute and normalized + // directory. + // + try + { + if (extra->relative ()) + extra->complete (); + + extra->normalize (); + } + catch (const invalid_path& e) + { + fail << "invalid --default-options value " << e.path; + } + } + default_options<O> dos ( load_default_options<O, cli::argv_file_scanner, cli::unknown_mode> ( nullopt /* sys_dir */, @@ -465,31 +505,48 @@ init (const common_options& co, // Verify common options. // - // Also merge the --progress/--no-progress options, overriding a less - // specific flag with a more specific. + // Also merge the --*/--no-* options, overriding a less specific flag with + // a more specific. + // // - optional<bool> progress; - auto merge_progress = [&progress] - (const O& o, - const default_options_entry<O>* e = nullptr) + optional<bool> progress, diag_color; + auto merge_no = [&progress, &diag_color] ( + const O& o, + const default_options_entry<O>* e = nullptr) { - if (o.progress () && o.no_progress ()) { - diag_record dr; - (e != nullptr ? dr << fail (e->file) : dr << fail) + if (o.progress () && o.no_progress ()) + { + diag_record dr; + (e != nullptr ? dr << fail (e->file) : dr << fail) << "both --progress and --no-progress specified"; + } + + if (o.progress ()) + progress = true; + else if (o.no_progress ()) + progress = false; } - if (o.progress ()) - progress = true; - else if (o.no_progress ()) - progress = false; + { + if (o.diag_color () && o.no_diag_color ()) + { + diag_record dr; + (e != nullptr ? dr << fail (e->file) : dr << fail) + << "both --diag-color and --no-diag-color specified"; + } + + if (o.diag_color ()) + diag_color = true; + else if (o.no_diag_color ()) + diag_color = false; + } }; for (const default_options_entry<O>& e: dos) - merge_progress (e.options, &e); + merge_no (e.options, &e); - merge_progress (o); + merge_no (o); o = merge_options (dos, o); @@ -498,6 +555,12 @@ init (const common_options& co, o.progress (*progress); o.no_progress (!*progress); } + + if (diag_color) + { + o.diag_color (*diag_color); + o.no_diag_color (!*diag_color); + } } catch (const invalid_argument& e) { @@ -544,7 +607,24 @@ try default_terminate = set_terminate (custom_terminate); - stderr_term = fdterm (stderr_fd ()); + if (fdterm (stderr_fd ())) + { + stderr_term = std::getenv ("TERM"); + + stderr_term_color = +#ifdef _WIN32 + // For now we disable color on Windows since it's unclear if/where/how + // it is supported. Maybe one day someone will figure this out. + // + false +#else + // This test was lifted from GCC (Emacs shell sets TERM=dumb). + // + *stderr_term != nullptr && strcmp (*stderr_term, "dumb") != 0 +#endif + ; + } + exec_dir = path (argv[0]).directory (); build2_argv0 = argv[0]; @@ -566,6 +646,7 @@ try cout << "bpkg " << BPKG_VERSION_ID << endl << "libbpkg " << LIBBPKG_VERSION_ID << endl << "libbutl " << LIBBUTL_VERSION_ID << endl + << "host " << host_triplet << endl << "Copyright (c) " << BPKG_COPYRIGHT << "." << endl << "This is free software released under the MIT license." << endl; return 0; @@ -704,6 +785,7 @@ try // These commands need the '--' separator to be kept in args. // + PKG_COMMAND (bindist, true, true); PKG_COMMAND (build, true, false); PKG_COMMAND (clean, true, true); PKG_COMMAND (configure, true, true); |