diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-08-12 13:05:54 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-08-12 13:05:54 +0200 |
commit | b01aaa16e5adaa0cc064490535f8756b2ef8d421 (patch) | |
tree | 1afe1a335610def3fa20ba93372bbdb6bf90d025 /libbuild2/cc/functions.cxx | |
parent | 7382e4bf15d11b9200d6220b2a89e1f82b220c5e (diff) |
Add ${c,cxx}.deduplicate_export_libs() function
This function deduplicates interface library dependencies by removing
libraries that are also interface dependencies of the specified
libraries. This can result in significantly better build performance for
heavily interface-interdependent library families (for example, like Boost).
Typical usage:
import intf_libs = ...
import intf_libs += ...
...
import intf_libs += ...
intf_libs = $cxx.deduplicate_export_libs($intf_libs)
Diffstat (limited to 'libbuild2/cc/functions.cxx')
-rw-r--r-- | libbuild2/cc/functions.cxx | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/libbuild2/cc/functions.cxx b/libbuild2/cc/functions.cxx index 7f9a6c2..6d54c49 100644 --- a/libbuild2/cc/functions.cxx +++ b/libbuild2/cc/functions.cxx @@ -399,6 +399,65 @@ namespace build2 fail << t << " is not an object file target"; }}); + // $<module>.deduplicate_export_libs(<names>) + // + // Deduplicate interface library dependencies by removing libraries that + // are also interface dependencies of the specified libraries. This can + // result in significantly better build performance for heavily + // interface-interdependent library families (for example, like Boost). + // Typical usage: + // + // import intf_libs = ... + // import intf_libs += ... + // ... + // import intf_libs += ... + // intf_libs = $cxx.deduplicate_export_libs($intf_libs) + // + // Notes: + // + // 1. We only consider unqualified absolute/normalized target names (the + // idea is that the installed case will already be deduplicated). + // + // 2. We assume all the libraries listed are of the module type and only + // look for cc.export.libs and <module>.export.libs. + // + // 3. No member/group selection/linkup: we resolve *.export.libs on + // whatever is listed. + // + // Note that this function is not pure. + // + f.insert (".deduplicate_export_libs", false). + insert<const char*, names> ( + [] (const scope* bs, + vector_view<value> vs, + const function_overload& f) -> value + { + const char* x (*reinterpret_cast<const char* const*> (&f.data)); + + if (bs == nullptr) + fail << f.name << " called out of scope"; + + const scope* rs (bs->root_scope ()); + + if (rs == nullptr) + fail << f.name << " called out of project"; + + const module* m (rs->find_module<module> (x)); + + if (m == nullptr) + fail << f.name << " called without " << x << " module loaded"; + + // We can assume the argument is present due to function's types + // signature. + // + names& r (vs[0].as<names> ()); + m->deduplicate_export_libs (*bs, + vector<name> (r.begin (), r.end ()), + r); + return value (move (r)); + }, + x); + // $<module>.find_system_library(<name>) // // Return the library path if the specified library exists in one of the |