diff options
-rw-r--r-- | build2/b.cxx | 1 | ||||
-rw-r--r-- | build2/bin/module | 9 | ||||
-rw-r--r-- | build2/bin/module.cxx | 170 | ||||
-rw-r--r-- | build2/cxx/module.cxx | 64 |
4 files changed, 154 insertions, 90 deletions
diff --git a/build2/b.cxx b/build2/b.cxx index 8c488df..3cd8793 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -189,6 +189,7 @@ main (int argc, char* argv[]) &install::init}; builtin_modules["bin"] = module_functions {nullptr, &bin::init}; + builtin_modules["bin.ar"] = module_functions {nullptr, &bin::ar_init}; builtin_modules["bin.ld"] = module_functions {nullptr, &bin::ld_init}; builtin_modules["bin.rc"] = module_functions {nullptr, &bin::rc_init}; builtin_modules["cxx"] = module_functions {nullptr, &cxx::init}; diff --git a/build2/bin/module b/build2/bin/module index 668e4d8..8fb9274 100644 --- a/build2/bin/module +++ b/build2/bin/module @@ -24,6 +24,15 @@ namespace build2 const variable_map&); bool + ar_init (scope&, + scope&, + const location&, + unique_ptr<module_base>&, + bool, + bool, + const variable_map&); + + bool ld_init (scope&, scope&, const location&, diff --git a/build2/bin/module.cxx b/build2/bin/module.cxx index 194b409..c796c84 100644 --- a/build2/bin/module.cxx +++ b/build2/bin/module.cxx @@ -76,9 +76,6 @@ namespace build2 v.insert<string> ("config.bin.target", true); v.insert<string> ("config.bin.pattern", true); - v.insert<path> ("config.bin.ar", true); - v.insert<path> ("config.bin.ranlib", true); - v.insert<string> ("config.bin.lib", true); v.insert<strings> ("config.bin.exe.lib", true); v.insert<strings> ("config.bin.liba.lib", true); @@ -277,71 +274,6 @@ namespace build2 dr << '\n' << " pattern " << cast<string> (l); } - - // config.bin.ar - // config.bin.ranlib - // - // For config.bin.ar we have the default (plus the pattern) while - // ranlib should be explicitly specified by the user in order for us - // to use it (all targets that we currently care to support have the - // ar -s option but if that changes we can always force the use of - // ranlib for certain targets). - // - // Another idea is to refuse to use default 'ar' (without the pattern) - // if the host/build targets don't match. On the other hand, a cross- - // toolchain can be target-unprefixed. Also, without canonicalization, - // comparing targets will be unreliable. - // - auto pattern (r["bin.pattern"]); - - // Use the target to decide on the default binutils program names. - // - const string& tsys (cast<string> (r["bin.target.system"])); - const char* ar_d (tsys == "win32-msvc" ? "lib" : "ar"); - - auto p (required (r, "config.bin.ar", path (apply (pattern, ar_d)))); - auto& v (optional (r, "config.bin.ranlib")); - - const path& ar (cast<path> (p.first)); - const path& ranlib (v ? cast<path> (v) : path ()); - - ar_info ari (guess_ar (ar, ranlib)); - - // If this is a new value (e.g., we are configuring), then print the - // report at verbosity level 2 and up (-v). - // - if (verb >= (p.second ? 2 : 3)) - { - //@@ Print project out root or name? See cxx. - - text << "bin.ar\n" - << " exe " << ar << '\n' - << " id " << ari.ar_id << '\n' - << " signature " << ari.ar_signature << '\n' - << " checksum " << ari.ar_checksum; - - if (!ranlib.empty ()) - { - text << "bin.ranlib\n" - << " exe " << ranlib << '\n' - << " id " << ari.ranlib_id << '\n' - << " signature " << ari.ranlib_signature << '\n' - << " checksum " << ari.ranlib_checksum; - } - } - - r.assign<string> ("bin.ar.id") = move (ari.ar_id); - r.assign<string> ("bin.ar.signature") = move (ari.ar_signature); - r.assign<string> ("bin.ar.checksum") = move (ari.ar_checksum); - - if (!ranlib.empty ()) - { - r.assign<string> ("bin.ranlib.id") = move (ari.ranlib_id); - r.assign<string> ("bin.ranlib.signature") = - move (ari.ranlib_signature); - r.assign<string> ("bin.ranlib.checksum") = - move (ari.ranlib_checksum); - } } // Cache some config values we will be needing below. @@ -432,6 +364,108 @@ namespace build2 } bool + ar_init (scope& r, + scope& b, + const location& loc, + unique_ptr<module_base>&, + bool first, + bool, + const variable_map& config_hints) + { + tracer trace ("bin::ar_init"); + l5 ([&]{trace << "for " << b.out_path ();}); + + // Make sure the bin core is loaded. + // + if (!cast_false<bool> (b["bin.loaded"])) + load_module ("bin", r, b, loc, false, config_hints); + + // Enter module variables. + // + if (first) + { + auto& v (var_pool); + + v.insert<path> ("config.bin.ar", true); + v.insert<path> ("config.bin.ranlib", true); + } + + // Configure. + // + if (first) + { + // config.bin.ar + // config.bin.ranlib + // + // For config.bin.ar we have the default (plus the pattern) while + // ranlib should be explicitly specified by the user in order for us + // to use it (all targets that we currently care to support have the + // ar -s option but if that changes we can always force the use of + // ranlib for certain targets). + // + // Another idea is to refuse to use default 'ar' (without the pattern) + // if the host/build targets don't match. On the other hand, a cross- + // toolchain can be target-unprefixed. Also, without canonicalization, + // comparing targets will be unreliable. + // + auto pattern (r["bin.pattern"]); + + // Use the target to decide on the default binutils program names. + // + const string& tsys (cast<string> (r["bin.target.system"])); + const char* ar_d (tsys == "win32-msvc" ? "lib" : "ar"); + + auto p (config::required (r, + "config.bin.ar", + path (apply (pattern, ar_d)))); + auto& v (config::optional (r, "config.bin.ranlib")); + + const path& ar (cast<path> (p.first)); + const path& ranlib (v ? cast<path> (v) : path ()); + + ar_info ari (guess_ar (ar, ranlib)); + + // If this is a new value (e.g., we are configuring), then print the + // report at verbosity level 2 and up (-v). + // + if (verb >= (p.second ? 2 : 3)) + { + //@@ Print project out root or name? See cxx. + + text << "bin.ar\n" + << " exe " << ar << '\n' + << " id " << ari.ar_id << '\n' + << " signature " << ari.ar_signature << '\n' + << " checksum " << ari.ar_checksum; + + if (!ranlib.empty ()) + { + text << "bin.ranlib\n" + << " exe " << ranlib << '\n' + << " id " << ari.ranlib_id << '\n' + << " signature " << ari.ranlib_signature << '\n' + << " checksum " << ari.ranlib_checksum; + } + } + + r.assign<string> ("bin.ar.id") = move (ari.ar_id); + r.assign<string> ("bin.ar.signature") = move (ari.ar_signature); + r.assign<string> ("bin.ar.checksum") = move (ari.ar_checksum); + + if (!ranlib.empty ()) + { + r.assign<string> ("bin.ranlib.id") = move (ari.ranlib_id); + r.assign<string> ("bin.ranlib.signature") = + move (ari.ranlib_signature); + r.assign<string> ("bin.ranlib.checksum") = + move (ari.ranlib_checksum); + } + } + + return true; + } + + bool ld_init (scope& r, scope& b, const location& loc, diff --git a/build2/cxx/module.cxx b/build2/cxx/module.cxx index 8972bf9..6ae7882 100644 --- a/build2/cxx/module.cxx +++ b/build2/cxx/module.cxx @@ -277,7 +277,20 @@ namespace build2 info << "cxx.target is " << ct; } - // In the VC world you link things directly with link.exe. + // Load the bin.ar module unless we were asked to only build shared + // libraries. + // + if (auto l = r["config.bin.lib"]) + { + if (cast<string> (l) != "shared") + { + if (!cast_false<bool> (b["bin.ar.loaded"])) + load_module ("bin.ar", r, b, loc, false, bin_hints); + } + } + + // In the VC world you link things directly with link.exe so load the + // bin.ld module. // if (cid == "msvc") { @@ -315,39 +328,46 @@ namespace build2 auto& r (b.rules); + // We register for configure so that we detect unresolved imports + // during configuration rather that later, e.g., during update. + // + // @@ Should we check if install module was loaded (see bin)? + // + r.insert<obje> (perform_update_id, "cxx.compile", compile::instance); r.insert<obje> (perform_clean_id, "cxx.compile", compile::instance); - - r.insert<obja> (perform_update_id, "cxx.compile", compile::instance); - r.insert<obja> (perform_clean_id, "cxx.compile", compile::instance); - - r.insert<objs> (perform_update_id, "cxx.compile", compile::instance); - r.insert<objs> (perform_clean_id, "cxx.compile", compile::instance); + r.insert<obje> (configure_update_id, "cxx.compile", compile::instance); r.insert<exe> (perform_update_id, "cxx.link", link::instance); r.insert<exe> (perform_clean_id, "cxx.link", link::instance); + r.insert<exe> (configure_update_id, "cxx.link", link::instance); - r.insert<liba> (perform_update_id, "cxx.link", link::instance); - r.insert<liba> (perform_clean_id, "cxx.link", link::instance); - - r.insert<libs> (perform_update_id, "cxx.link", link::instance); - r.insert<libs> (perform_clean_id, "cxx.link", link::instance); + r.insert<exe> (perform_install_id, "cxx.install", install::instance); - // Register for configure so that we detect unresolved imports during - // configuration rather that later, e.g., during update. + // Only register static object/library rules if the bin.ar module is + // loaded (by us or by the user). // - r.insert<obje> (configure_update_id, "cxx.compile", compile::instance); - r.insert<obja> (configure_update_id, "cxx.compile", compile::instance); + if (cast_false<bool> (b["bin.ar.loaded"])) + { + r.insert<obja> (perform_update_id, "cxx.compile", compile::instance); + r.insert<obja> (perform_clean_id, "cxx.compile", compile::instance); + r.insert<obja> (configure_update_id, "cxx.compile", compile::instance); + + r.insert<liba> (perform_update_id, "cxx.link", link::instance); + r.insert<liba> (perform_clean_id, "cxx.link", link::instance); + r.insert<liba> (configure_update_id, "cxx.link", link::instance); + + r.insert<liba> (perform_install_id, "cxx.install", install::instance); + } + + r.insert<objs> (perform_update_id, "cxx.compile", compile::instance); + r.insert<objs> (perform_clean_id, "cxx.compile", compile::instance); r.insert<objs> (configure_update_id, "cxx.compile", compile::instance); - r.insert<exe> (configure_update_id, "cxx.link", link::instance); - r.insert<liba> (configure_update_id, "cxx.link", link::instance); + r.insert<libs> (perform_update_id, "cxx.link", link::instance); + r.insert<libs> (perform_clean_id, "cxx.link", link::instance); r.insert<libs> (configure_update_id, "cxx.link", link::instance); - //@@ Should we check if install module was loaded (see bin)? - // - r.insert<exe> (perform_install_id, "cxx.install", install::instance); - r.insert<liba> (perform_install_id, "cxx.install", install::instance); r.insert<libs> (perform_install_id, "cxx.install", install::instance); } |