aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/b.cxx1
-rw-r--r--build2/bin/module9
-rw-r--r--build2/bin/module.cxx170
-rw-r--r--build2/cxx/module.cxx64
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);
}