From ee0456ed4a5f3f6686fbb0a433161d1f9d8535fe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 4 Jul 2019 07:30:23 +0200 Subject: Remove libu{} target group The semantics provided by libu{} is rarely required and as result was not yet documented. However, if you are using it, the new way to achieve the same result is to use both libue{} and libul{} explicitly, for example: exe{foo}: libue{foo} lib{foo}: libul{foo} {libue libul}{foo}: cxx{*} --- NEWS | 12 ++++++++++++ build2/bin/init.cxx | 5 ++--- build2/bin/target.cxx | 32 ++++++-------------------------- build2/bin/target.hxx | 27 ++++++++++++++++++--------- build2/cc/link-rule.cxx | 31 ++++++++++++------------------- build2/cc/types.hxx | 1 + build2/cc/utility.cxx | 22 ++++++++++------------ build2/cc/utility.hxx | 2 +- tests/cc/libu/testscript | 18 +++++++++--------- 9 files changed, 71 insertions(+), 79 deletions(-) diff --git a/NEWS b/NEWS index f9b71be..1a2f5a7 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,18 @@ Version 0.12.0 LIBBUILD2_ATOMIC_NON_LOCK_FREE + * The libu{} target group has been removed. + + The semantics provided by libu{} is rarely required and as result was not + yet documented. However, if you are using it, the new way to achieve the + same result is to use both libue{} and libul{} explicitly, for example: + + exe{foo}: libue{foo} + lib{foo}: libul{foo} + + {libue libul}{foo}: cxx{*} + + Version 0.11.0 * Initial work on header unit importation and include translation support. diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx index 37fad6b..5932b29 100644 --- a/build2/bin/init.cxx +++ b/build2/bin/init.cxx @@ -439,7 +439,9 @@ namespace build2 t.insert (); t.insert (); +#if 0 t.insert (); +#endif t.insert (); t.insert (); t.insert (); @@ -516,9 +518,6 @@ namespace build2 r.insert (perform_update_id, "bin.hbmi", fail_); r.insert (perform_clean_id, "bin.hbmi", fail_); - r.insert (perform_update_id, "bin.libu", fail_); - r.insert (perform_clean_id, "bin.libu", fail_); - r.insert (perform_update_id, "bin.libul", fail_); r.insert (perform_clean_id, "bin.libul", fail_); diff --git a/build2/bin/target.cxx b/build2/bin/target.cxx index 46f19bd..7c16506 100644 --- a/build2/bin/target.cxx +++ b/build2/bin/target.cxx @@ -215,33 +215,11 @@ namespace build2 false }; - // libu*{} member factory. - // - template - static target* - libux_factory (const target_type&, dir_path dir, dir_path out, string n) - { - const target* g (targets.find (dir, out, n)); - - if (const target* g2 = targets.find (dir, out, n)) - { - if (g != 0) - fail << "both " << *g << " and " << *g2 << " targets declared"; - - g = g2; - } - - M* m (new M (move (dir), move (out), move (n))); - m->group = g; - - return m; - } - const target_type libue::static_type { "libue", &libux::static_type, - &libux_factory, + &target_factory, nullptr, /* fixed_extension */ &target_extension_var, &target_pattern_var, @@ -254,7 +232,7 @@ namespace build2 { "libua", &libux::static_type, - &libux_factory, + &m_factory, nullptr, /* fixed_extension */ &target_extension_var, &target_pattern_var, @@ -267,7 +245,7 @@ namespace build2 { "libus", &libux::static_type, - &libux_factory, + &m_factory, nullptr, /* fixed_extension */ &target_extension_var, &target_pattern_var, @@ -375,11 +353,12 @@ namespace build2 false }; +#if 0 const target_type libu::static_type { "libu", &libx::static_type, - &g_factory, + &target_factory, nullptr, nullptr, nullptr, @@ -387,6 +366,7 @@ namespace build2 &target_search, false }; +#endif // What extensions should we use? At the outset, this is platform- // dependent. And if we consider cross-compilation, is it build or diff --git a/build2/bin/target.hxx b/build2/bin/target.hxx index a56c636..12065bf 100644 --- a/build2/bin/target.hxx +++ b/build2/bin/target.hxx @@ -191,7 +191,7 @@ namespace build2 }; - // Common base for lib{} and libul{}/libu{} groups. + // Common base for lib{} and libul{} groups. // // We use mtime_target as a base for the "trust me it exists" functionality // which we use, for example, to have installed lib{} prerequisites that @@ -206,20 +206,27 @@ namespace build2 static const target_type static_type; }; - // The libul{}/libu{} target groups (utility library). + // The libue{} target, libul{} group and libua{} and libus{} members + // (utility library). // - // All the members are static libraries that differ based on the kind of - // object files they contains. Note that the group is more like obj{} - // rather than lib{} in that one does not build the group directly rather - // picking a suitable member. + // Utility libraries are static libraries that differ based on the kind of + // object files they contains. Note that the libul{} group is more like + // obj{} rather than lib{} in that one does not build the group directly + // rather picking a suitable member. // // libul{} is a "library utility library" in that the choice of members is // libua{} or libus{}, even when linking an executable (normally a unit // test). // - // libu{} is a general utility library with all three types of members. It - // would normally be used when you want to build both a library from - // libua{}/libus{} and an executable from libue{}. + // Note that there is no "general utility library" with all three types of + // members (that would cause member uplink ambiguity). If you need to + // build both a library from libua{}/libus{} and an executable from + // libue{} then you will need to arrange this explicitly, for example: + // + // exe{foo}: libue{foo} + // lib{foo}: libul{foo} + // + // {libue libul}{foo}: cxx{*} // class libux: public file // Common base of all libuX{} static libraries. { @@ -270,6 +277,7 @@ namespace build2 virtual const target_type& dynamic_type () const {return static_type;} }; +#if 0 class libu: public libx { public: @@ -279,6 +287,7 @@ namespace build2 static const target_type static_type; virtual const target_type& dynamic_type () const {return static_type;} }; +#endif // The lib{} target group. // diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx index 6dfcfa9..9caac51 100644 --- a/build2/cc/link-rule.cxx +++ b/build2/cc/link-rule.cxx @@ -108,9 +108,7 @@ namespace build2 r.seen_obj = r.seen_obj || true; } - else if (p.is_a () || - p.is_a () || - p.is_a ()) + else if (p.is_a () || p.is_a ()) { // For a unility library we look at its prerequisites, recursively. // Since these checks are not exactly light-weight, only do them if @@ -136,7 +134,7 @@ namespace build2 const target* pg (nullptr); const target* pt (p.search_existing ()); - if (p.is_a ()) + if (p.is_a ()) { if (pt != nullptr) { @@ -145,7 +143,7 @@ namespace build2 // considering the group's prerequisites. // if (const target* pm = - link_member (pt->as (), + link_member (pt->as (), a, linfo {ot, lorder::a /* unused */}, true /* existing */)) @@ -170,13 +168,11 @@ namespace build2 pt = search_existing (p.prerequisite.key (tt)); } } - else + else if (!p.is_a ()) { // See if we also/instead have a group. // - // @@ Why are we picking libu{} over libul{} (and below)? - // - pg = search_existing (p.prerequisite.key (libu::static_type)); + pg = search_existing (p.prerequisite.key (libul::static_type)); if (pt == nullptr) swap (pt, pg); @@ -187,7 +183,7 @@ namespace build2 // If we are matching a target, use the original output type // since that would be the member that we pick. // - otype pot (pt->is_a () ? ot : link_type (*pt).type); + otype pot (pt->is_a () ? ot : link_type (*pt).type); match_result pr (match (a, *pt, pg, pot, true /* lib */)); // Do we need to propagate any other seen_* values? Hm, that @@ -229,21 +225,20 @@ namespace build2 ltype lt (link_type (t)); - // If this is a library, link-up to our group (this is the target group - // protocol which means this can be done whether we match or not). + // If this is a group member library, link-up to our group (this is the + // target group protocol which means this can be done whether we match + // or not). // // If we are called for the outer operation (see install rules), then // use resolve_group() to delegate to inner. // - if (lt.library ()) + if (lt.member_library ()) { if (a.outer ()) resolve_group (a, t); else if (t.group == nullptr) t.group = &search (t, - // @@ Why are we picking libu{} over libul{} (and above)? - // - lt.utility ? libu::static_type : lib::static_type, + lt.utility ? libul::static_type : lib::static_type, t.dir, t.out, t.name); } @@ -447,9 +442,7 @@ namespace build2 // If this is the libu*{} group, then pick the appropriate member. // - const libx* ul; - if ((ul = pt->is_a ()) || - (ul = pt->is_a ())) + if (const libul* ul = pt->is_a ()) { pf = &link_member (*ul, a, li)->as (); } diff --git a/build2/cc/types.hxx b/build2/cc/types.hxx index 481c3c6..c297b19 100644 --- a/build2/cc/types.hxx +++ b/build2/cc/types.hxx @@ -81,6 +81,7 @@ namespace build2 bool library () const {return type != otype::e || utility;} bool static_library () const {return type == otype::a || utility;} bool shared_library () const {return type == otype::s && !utility;} + bool member_library () const {return type != otype::e;} }; // Compile target types. diff --git a/build2/cc/utility.cxx b/build2/cc/utility.cxx index 2179c14..3271f7c 100644 --- a/build2/cc/utility.cxx +++ b/build2/cc/utility.cxx @@ -46,17 +46,15 @@ namespace build2 const target* link_member (const bin::libx& x, action a, linfo li, bool exist) { - bool ul; - - if ((ul = x.is_a ()) || x.is_a ()) + if (x.is_a ()) { - // If this is a libul{} and we are linking an executable, then the - // member choice should be dictated by the members of lib{} this - // libul{} is "primarily" for. If both are being built, then it seems - // natural to prefer static over shared since it could be faster (but - // I am sure someone will probably want this configurable). + // For libul{} that is linked to an executable the member choice + // should be dictated by the members of lib{} this libul{} is + // "primarily" for. If both are being built, then it seems natural to + // prefer static over shared since it could be faster (but I am sure + // someone will probably want this configurable). // - if (ul && li.type == otype::e) + if (li.type == otype::e) { // Utility libraries are project-local which means the primarily // target should be in the same project as us. @@ -66,9 +64,9 @@ namespace build2 : otype::s; } - const target_type& tt (li.type == otype::a ? libua::static_type : - li.type == otype::s ? libus::static_type : - libue::static_type); + const target_type& tt (li.type == otype::a + ? libua::static_type + : libus::static_type); // Called by the compile rule during execute. // diff --git a/build2/cc/utility.hxx b/build2/cc/utility.hxx index 80ca741..6222b5f 100644 --- a/build2/cc/utility.hxx +++ b/build2/cc/utility.hxx @@ -58,7 +58,7 @@ namespace build2 } // Given the link order return the library member to link. That is, liba{} - // or libs{} for lib{} and libue{}, libua{} or libus{} for libu*{}. + // or libs{} for lib{} and libua{} or libus{} for libul{}. // // If existing is true, then only return the member target if it exists // (currently only used and supported for utility libraries). diff --git a/tests/cc/libu/testscript b/tests/cc/libu/testscript index 578b934..75ccb4d 100644 --- a/tests/cc/libu/testscript +++ b/tests/cc/libu/testscript @@ -53,8 +53,11 @@ EOI ln -s ../foo.hxx ../foo.cxx ../bar.cxx ../driver.cxx ./; $* test clean <