From 7d50db8924b8ce4faf05cde737bce9114df58f0d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 25 Mar 2022 09:59:49 +0200 Subject: Store bin.whole flag in pkg-config files --- libbuild2/cc/pkgconfig.cxx | 59 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) (limited to 'libbuild2/cc/pkgconfig.cxx') diff --git a/libbuild2/cc/pkgconfig.cxx b/libbuild2/cc/pkgconfig.cxx index 617834e..29d9155 100644 --- a/libbuild2/cc/pkgconfig.cxx +++ b/libbuild2/cc/pkgconfig.cxx @@ -134,10 +134,10 @@ namespace build2 strings libs (bool stat) const; - string + optional variable (const char*) const; - string + optional variable (const string& s) const {return variable (s.c_str ());} private: @@ -437,14 +437,14 @@ namespace build2 return to_strings (f, 'L', client_->filter_libdirs); } - string pkgconf:: + optional pkgconf:: variable (const char* name) const { assert (client_ != nullptr); // Must not be empty. mlock l (pkgconf_mutex); const char* r (pkgconf_tuple_find (client_, &pkg_->vars, name)); - return r != nullptr ? string (r) : string (); + return r != nullptr ? optional (r) : nullopt; } #endif @@ -1170,10 +1170,13 @@ namespace build2 &next, &s, <] (const pkgconf& pc, prerequisites& ps) { - string val (pc.variable ("cxx_modules")); + optional val (pc.variable ("cxx_modules")); + + if (!val) + return; string m; - for (size_t b (0), e (0); !(m = next (val, b, e)).empty (); ) + for (size_t b (0), e (0); !(m = next (*val, b, e)).empty (); ) { // The format is = with `..` used as a partition // separator (see pkgconfig_save() for details). @@ -1182,7 +1185,7 @@ namespace build2 if (p == string::npos || p == 0 || // Empty name. p == m.size () - 1) // Empty path. - fail << "invalid module information in '" << val << "'" << + fail << "invalid module information in '" << *val << "'" << info << "while parsing pkg-config --variable=cxx_modules " << pc.path; @@ -1192,8 +1195,8 @@ namespace build2 // Extract module properties, if any. // - string pp (pc.variable ("cxx_module_preprocessed." + mn)); - string se (pc.variable ("cxx_module_symexport." + mn)); + optional pp (pc.variable ("cxx_module_preprocessed." + mn)); + optional se (pc.variable ("cxx_module_symexport." + mn)); // Replace the partition separator. // @@ -1238,11 +1241,12 @@ namespace build2 // { value& v (mt.vars.assign (x_preprocessed)); // NULL - if (!pp.empty ()) v = move (pp); + if (pp) + v = move (*pp); } { - mt.vars.assign (x_symexport) = (se == "true"); + mt.vars.assign (x_symexport) = (se && *se == "true"); } tl.second.unlock (); @@ -1270,10 +1274,13 @@ namespace build2 prerequisites& ps) { string var (string (lang) + "_importable_headers"); - string val (pc.variable (var)); + optional val (pc.variable (var)); + + if (!val) + return; string h; - for (size_t b (0), e (0); !(h = next (val, b, e)).empty (); ) + for (size_t b (0), e (0); !(h = next (*val, b, e)).empty (); ) { path hp (move (h)); path hf (hp.leaf ()); @@ -1374,6 +1381,20 @@ namespace build2 if (ps) parse_cflags (*st, spc, false); + // Load the bin.whole flag (whole archive). + // + if (at != nullptr) + { + // Note that if unspecified we leave it unset letting the consumer + // override it, if necessary (see the bin.lib lookup semantics for + // details). + // + if (optional v = (pa ? apc : spc).variable ("bin.whole")) + { + at->vars.assign ("bin.whole") = (*v == "true"); + } + } + // For now we assume static and shared variants export the same set of // modules/importable headers. While technically possible, having // different sets will most likely lead to all sorts of complications @@ -1800,6 +1821,18 @@ namespace build2 for (const string& a: args) os << ' ' << a; os << endl; + + // Save the bin.whole (whole archive) flag (see the link rule for + // details on the lookup semantics). + // + if (cast_false ( + l.lookup_original (ctx.var_pool["bin.whole"], + true /* target_only */).first)) + { + os << endl + << "bin.whole = true" + << endl; + } } } -- cgit v1.1