From b7f4e6154fa3c07ad3472bbd7c871df28d440a64 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 23 Nov 2020 10:22:48 +0200 Subject: Suppress duplicates when extracting library options (GitHub issue #114) --- libbuild2/cc/functions.cxx | 72 +++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 23 deletions(-) (limited to 'libbuild2/cc/functions.cxx') diff --git a/libbuild2/cc/functions.cxx b/libbuild2/cc/functions.cxx index ca93b63..78ee212 100644 --- a/libbuild2/cc/functions.cxx +++ b/libbuild2/cc/functions.cxx @@ -27,15 +27,16 @@ namespace build2 struct lib_data { const char* x; - void (*f) (strings&, + void (*f) (void*, strings&, const vector_view&, const module&, const scope&, action, const file&, bool, linfo); }; static value - lib_thunk (const scope* bs, - vector_view vs, - const function_overload& f) + lib_thunk_impl (void* ls, + const scope* bs, + vector_view vs, + const function_overload& f) { const lib_data& d (*reinterpret_cast (&f.data)); @@ -114,7 +115,7 @@ namespace build2 (la = (f = t.is_a ())) || ( (f = t.is_a ()))) { - d.f (r, vs, *m, *bs, a, *f, la, li); + d.f (ls, r, vs, *m, *bs, a, *f, la, li); } else fail << t << " is not a library target"; @@ -123,6 +124,16 @@ namespace build2 return value (move (r)); } + template + static value + lib_thunk (const scope* bs, + vector_view vs, + const function_overload& f) + { + L ls; + return lib_thunk_impl (&ls, bs, vs, f); + } + void compile_rule:: functions (function_family& f, const char* x) { @@ -132,19 +143,24 @@ namespace build2 // sources that depend on the specified libraries. The second argument // is the output target type (obje, objs, etc). // - // Note that this function can only be called during execution after all - // the specified library targets have been matched. Normally it is used - // in ad hoc recipes to implement custom compilation. + // Note that passing multiple targets at once is not a mere convenience: + // this also allows for more effective duplicate suppression. + // + // Note also that this function can only be called during execution + // after all the specified library targets have been matched. Normally + // it is used in ad hoc recipes to implement custom compilation. + // // f[".lib_poptions"].insert ( - &lib_thunk, + &lib_thunk, lib_data { x, - [] (strings& r, + [] (void* ls, strings& r, const vector_view&, const module& m, const scope& bs, action a, const file& l, bool la, linfo li) { - m.append_lib_options (r, bs, a, l, la, li); + m.append_library_options ( + *static_cast (ls), r, bs, a, l, la, li); }}); } @@ -164,16 +180,19 @@ namespace build2 // If the last argument is false, then do not return the specified // libraries themselves. // - // Note that this function can only be called during execution after all - // the specified library targets have been matched. Normally it is used - // in ad hoc recipes to implement custom linking. + // Note that passing multiple targets at once is not a mere convenience: + // this also allows for more effective duplicate suppression. + // + // Note also that this function can only be called during execution + // after all the specified library targets have been matched. Normally + // it is used in ad hoc recipes to implement custom linking. // f[".lib_libs"].insert, optional> ( - &lib_thunk, + &lib_thunk, lib_data { x, - [] (strings& r, + [] (void* ls, strings& r, const vector_view& vs, const module& m, const scope& bs, action a, const file& l, bool la, linfo li) { @@ -193,7 +212,9 @@ namespace build2 bool self (vs.size () > 3 ? convert (vs[3]) : true); - m.append_libraries (r, bs, a, l, la, lf, li, self); + m.append_libraries (*static_cast (ls), r, + bs, + a, l, la, lf, li, self); }}); // $.lib_rpaths(, [, [, ]]) @@ -209,22 +230,27 @@ namespace build2 // If the last argument is false, then do not return the options for the // specified libraries themselves. // - // Note that this function can only be called during execution after all - // the specified library targets have been matched. Normally it is used - // in ad hoc recipes to implement custom linking. + // Note that passing multiple targets at once is not a mere convenience: + // this also allows for more effective duplicate suppression. + + // Note also that this function can only be called during execution + // after all the specified library targets have been matched. Normally + // it is used in ad hoc recipes to implement custom linking. // f[".lib_rpaths"].insert, optional> ( - &lib_thunk, + &lib_thunk, lib_data { x, - [] (strings& r, + [] (void* ls, strings& r, const vector_view& vs, const module& m, const scope& bs, action a, const file& l, bool la, linfo li) { bool link (vs.size () > 2 ? convert (vs[2]) : false); bool self (vs.size () > 3 ? convert (vs[3]) : true); - m.rpath_libraries (r, bs, a, l, la, li, link, self); + m.rpath_libraries (*static_cast (ls), r, + bs, + a, l, la, li, link, self); }}); } } -- cgit v1.1