From 53eb43126e562a43f4e8f2247af10da5c4c3c87f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 12 Aug 2016 16:39:13 +0200 Subject: Rename module to init --- build2/cli/init | 28 ++++++ build2/cli/init.cxx | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++ build2/cli/module | 28 ------ build2/cli/module.cxx | 265 -------------------------------------------------- 4 files changed, 293 insertions(+), 293 deletions(-) create mode 100644 build2/cli/init create mode 100644 build2/cli/init.cxx delete mode 100644 build2/cli/module delete mode 100644 build2/cli/module.cxx (limited to 'build2/cli') diff --git a/build2/cli/init b/build2/cli/init new file mode 100644 index 0000000..917ab35 --- /dev/null +++ b/build2/cli/init @@ -0,0 +1,28 @@ +// file : build2/cli/init -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD2_CLI_INIT +#define BUILD2_CLI_INIT + +#include +#include + +#include + +namespace build2 +{ + namespace cli + { + bool + init (scope&, + scope&, + const location&, + unique_ptr&, + bool, + bool, + const variable_map&); + } +} + +#endif // BUILD2_CLI_INIT diff --git a/build2/cli/init.cxx b/build2/cli/init.cxx new file mode 100644 index 0000000..467cf82 --- /dev/null +++ b/build2/cli/init.cxx @@ -0,0 +1,265 @@ +// file : build2/cli/init.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +using namespace std; +using namespace butl; + +namespace build2 +{ + namespace cli + { + static compile compile_; + + bool + init (scope& rs, + scope& bs, + const location& loc, + unique_ptr&, + bool first, + bool optional, + const variable_map& config_hints) + { + tracer trace ("cli::init"); + l5 ([&]{trace << "for " << bs.out_path ();}); + + assert (config_hints.empty ()); // We don't known any hints. + + // Make sure the cxx module has been loaded since we need its targets + // types (?xx{}). Note that we don't try to load it ourselves because of + // the non-trivial variable merging semantics. So it is better to let + // the user load cxx explicitly. + // + if (!cast_false (bs["cxx.loaded"])) + fail (loc) << "cxx module must be loaded before cli"; + + // Enter module variables. + // + if (first) + { + auto& v (var_pool); + + // Note: some overridable, some not. + // + v.insert ("config.cli", true); + v.insert ("config.cli.options", true); + + v.insert ("cli.options"); + } + + // Register target types. + // + { + auto& t (bs.target_types); + + t.insert (); + t.insert (); + } + + // Configure. + // + // The plan is as follows: try to configure the module. If this fails, + // we are using default values, and the module is optional, leave it + // unconfigured. + // + + // We will only honor optional if the user didn't specify any cli + // configuration explicitly. + // + optional = optional && !config::specified (rs, "config.cli"); + + // If the configuration says we are unconfigured, then we don't need to + // re-run tests, etc. But we may still need to print the config report. + // + bool unconf (optional && config::unconfigured (rs, "config.cli")); + + if (first) + { + // config.cli + // + + // Return version or empty string if unable to execute (e.g., the cli + // executable is not found). + // + auto test = [optional] (const path& cli) -> string + { + const char* args[] = {cli.string ().c_str (), "--version", nullptr}; + + if (verb >= 3) + print_process (args); + + try + { + process pr (args, 0, -1); // Open pipe to stdout. + + try + { + ifdstream is (pr.in_ofd, fdstream_mode::skip); + + // The version should be the last word on the first line. + // + string ver; + getline (is, ver); + auto p (ver.rfind (' ')); + if (p != string::npos) + ver = string (ver, p + 1); + + is.close (); // Don't block the other end. + + if (pr.wait ()) + { + if (ver.empty ()) + fail << "unexpected output from " << cli; + + return ver; + } + + // Presumably issued diagnostics. Fall through. + } + catch (const ifdstream::failure&) + { + pr.wait (); + + // Fall through. + } + + // Fall through. + } + catch (const process_error& e) + { + // In some cases this is not enough (e.g., the runtime linker + // will print scary errors if some shared libraries are not + // found). So it would be good to redirect child's STDERR. + // + if (!optional) + error << "unable to execute " << cli << ": " << e.what (); + + if (e.child ()) + exit (1); + + // Fall through. + } + + return string (); // Not found. + }; + + // Adjust module priority (code generator). + // + config::save_module (rs, "cli", 150); + + string ver; // Empty means unconfigured. + path cli ("cli"); // Default. + bool nv (false); // New value. + + if (optional) + { + // Test the default value before setting any config.cli.* values + // so that if we fail to configure, nothing will be written to + // config.build. + // + if (!unconf) + { + ver = test (cli); + + if (ver.empty ()) + { + // Note that we are unconfigured so that we don't keep + // re-testing this on each run. + // + config::unconfigured (rs, "config.cli", true); + unconf = true; + } + else + { + auto p (config::required (rs, "config.cli", cli)); + assert (p.second && cast (p.first) == cli); + } + + nv = true; + } + } + else + { + auto p (config::required (rs, "config.cli", cli)); + + cli = cast (p.first); + ver = test (cli); + + if (ver.empty ()) + throw failed (); // Diagnostics already issued. + + nv = p.second; + } + + // If this is a new value (e.g., we are configuring), then print the + // report at verbosity level 2 and up (-v). + // + if (verb >= (nv ? 2 : 3)) + { + diag_record dr (text); + dr << "cli " << project (rs) << '@' << rs.out_path () << '\n'; + + if (unconf) + dr << " cli " << "not found, leaving unconfigured"; + else + dr << " cli " << cli << '\n' + << " version " << ver; + } + } + + // Nothing else to do if we are unconfigured. + // + if (unconf) + return false; + + // config.cli.options + // + // This one is optional. We also merge it into the corresponding + // cli.* variables. See the cxx module for more information on + // this merging semantics and some of its tricky aspects. + // + bs.assign ("cli.options") += cast_null ( + config::optional (rs, "config.cli.options")); + + // Register our rules. + // + { + auto& r (bs.rules); + + r.insert (perform_update_id, "cli.compile", compile_); + r.insert (perform_clean_id, "cli.compile", compile_); + + r.insert (perform_update_id, "cli.compile", compile_); + r.insert (perform_clean_id, "cli.compile", compile_); + + r.insert (perform_update_id, "cli.compile", compile_); + r.insert (perform_clean_id, "cli.compile", compile_); + + r.insert (perform_update_id, "cli.compile", compile_); + r.insert (perform_clean_id, "cli.compile", compile_); + + // Other rules (e.g., cxx::compile) may need to have the group + // members resolved. Looks like a general pattern: groups should + // resolve on configure(update). + // + r.insert (configure_update_id, "cli.compile", compile_); + } + + return true; + } + } +} diff --git a/build2/cli/module b/build2/cli/module deleted file mode 100644 index 50d07ef..0000000 --- a/build2/cli/module +++ /dev/null @@ -1,28 +0,0 @@ -// file : build2/cli/module -*- C++ -*- -// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD2_CLI_MODULE -#define BUILD2_CLI_MODULE - -#include -#include - -#include - -namespace build2 -{ - namespace cli - { - bool - init (scope&, - scope&, - const location&, - unique_ptr&, - bool, - bool, - const variable_map&); - } -} - -#endif // BUILD2_CLI_MODULE diff --git a/build2/cli/module.cxx b/build2/cli/module.cxx deleted file mode 100644 index ef9c2f8..0000000 --- a/build2/cli/module.cxx +++ /dev/null @@ -1,265 +0,0 @@ -// file : build2/cli/module.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -using namespace std; -using namespace butl; - -namespace build2 -{ - namespace cli - { - static compile compile_; - - bool - init (scope& rs, - scope& bs, - const location& loc, - unique_ptr&, - bool first, - bool optional, - const variable_map& config_hints) - { - tracer trace ("cli::init"); - l5 ([&]{trace << "for " << bs.out_path ();}); - - assert (config_hints.empty ()); // We don't known any hints. - - // Make sure the cxx module has been loaded since we need its targets - // types (?xx{}). Note that we don't try to load it ourselves because of - // the non-trivial variable merging semantics. So it is better to let - // the user load cxx explicitly. - // - if (!cast_false (bs["cxx.loaded"])) - fail (loc) << "cxx module must be loaded before cli"; - - // Enter module variables. - // - if (first) - { - auto& v (var_pool); - - // Note: some overridable, some not. - // - v.insert ("config.cli", true); - v.insert ("config.cli.options", true); - - v.insert ("cli.options"); - } - - // Register target types. - // - { - auto& t (bs.target_types); - - t.insert (); - t.insert (); - } - - // Configure. - // - // The plan is as follows: try to configure the module. If this fails, - // we are using default values, and the module is optional, leave it - // unconfigured. - // - - // We will only honor optional if the user didn't specify any cli - // configuration explicitly. - // - optional = optional && !config::specified (rs, "config.cli"); - - // If the configuration says we are unconfigured, then we don't need to - // re-run tests, etc. But we may still need to print the config report. - // - bool unconf (optional && config::unconfigured (rs, "config.cli")); - - if (first) - { - // config.cli - // - - // Return version or empty string if unable to execute (e.g., the cli - // executable is not found). - // - auto test = [optional] (const path& cli) -> string - { - const char* args[] = {cli.string ().c_str (), "--version", nullptr}; - - if (verb >= 3) - print_process (args); - - try - { - process pr (args, 0, -1); // Open pipe to stdout. - - try - { - ifdstream is (pr.in_ofd, fdstream_mode::skip); - - // The version should be the last word on the first line. - // - string ver; - getline (is, ver); - auto p (ver.rfind (' ')); - if (p != string::npos) - ver = string (ver, p + 1); - - is.close (); // Don't block the other end. - - if (pr.wait ()) - { - if (ver.empty ()) - fail << "unexpected output from " << cli; - - return ver; - } - - // Presumably issued diagnostics. Fall through. - } - catch (const ifdstream::failure&) - { - pr.wait (); - - // Fall through. - } - - // Fall through. - } - catch (const process_error& e) - { - // In some cases this is not enough (e.g., the runtime linker - // will print scary errors if some shared libraries are not - // found). So it would be good to redirect child's STDERR. - // - if (!optional) - error << "unable to execute " << cli << ": " << e.what (); - - if (e.child ()) - exit (1); - - // Fall through. - } - - return string (); // Not found. - }; - - // Adjust module priority (code generator). - // - config::save_module (rs, "cli", 150); - - string ver; // Empty means unconfigured. - path cli ("cli"); // Default. - bool nv (false); // New value. - - if (optional) - { - // Test the default value before setting any config.cli.* values - // so that if we fail to configure, nothing will be written to - // config.build. - // - if (!unconf) - { - ver = test (cli); - - if (ver.empty ()) - { - // Note that we are unconfigured so that we don't keep - // re-testing this on each run. - // - config::unconfigured (rs, "config.cli", true); - unconf = true; - } - else - { - auto p (config::required (rs, "config.cli", cli)); - assert (p.second && cast (p.first) == cli); - } - - nv = true; - } - } - else - { - auto p (config::required (rs, "config.cli", cli)); - - cli = cast (p.first); - ver = test (cli); - - if (ver.empty ()) - throw failed (); // Diagnostics already issued. - - nv = p.second; - } - - // If this is a new value (e.g., we are configuring), then print the - // report at verbosity level 2 and up (-v). - // - if (verb >= (nv ? 2 : 3)) - { - diag_record dr (text); - dr << "cli " << project (rs) << '@' << rs.out_path () << '\n'; - - if (unconf) - dr << " cli " << "not found, leaving unconfigured"; - else - dr << " cli " << cli << '\n' - << " version " << ver; - } - } - - // Nothing else to do if we are unconfigured. - // - if (unconf) - return false; - - // config.cli.options - // - // This one is optional. We also merge it into the corresponding - // cli.* variables. See the cxx module for more information on - // this merging semantics and some of its tricky aspects. - // - bs.assign ("cli.options") += cast_null ( - config::optional (rs, "config.cli.options")); - - // Register our rules. - // - { - auto& r (bs.rules); - - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); - - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); - - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); - - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); - - // Other rules (e.g., cxx::compile) may need to have the group - // members resolved. Looks like a general pattern: groups should - // resolve on configure(update). - // - r.insert (configure_update_id, "cli.compile", compile_); - } - - return true; - } - } -} -- cgit v1.1