From 2720b45ef0ca9fd58c11fd9b4f000e1cf3a0819d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 29 Aug 2016 19:31:16 +0200 Subject: Implement initial support for library versioning Currently we only support platform-independent versions that get appended to the library name. The magic incantation is this: lib{foo}: bin.lib.version = @-1.2 This will produce libfoo-1.2.so, libfoo-1.2.dll, etc. In the future we will support things like this: lib{foo}: bin.lib.version = linux@1.2.3 freebsd@1.2 windows@1.2 --- build2/algorithm.cxx | 102 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 39 deletions(-) (limited to 'build2/algorithm.cxx') diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index cae6645..6b28232 100644 --- a/build2/algorithm.cxx +++ b/build2/algorithm.cxx @@ -532,7 +532,9 @@ namespace build2 } target_state - clean_extra (action a, file& ft, initializer_list es) + clean_extra (action a, + file& ft, + initializer_list> extra) { // Clean the extras first and don't print the commands at verbosity level // below 3. Note the first extra file/directory that actually got removed @@ -542,58 +544,77 @@ namespace build2 bool ed (false); path ep; - for (const char* e: es) + auto clean = [&er, &ed, &ep] (file& f, initializer_list es) { - if (e == nullptr) - continue; + for (const char* e: es) + { + size_t n; + if (e == nullptr || (n = strlen (e)) == 0) + continue; - bool d (*e == '/'); - if (d) - ++e; + path p; + bool d; - path p (ft.path ()); - for (; *e == '-'; ++e) - p = p.base (); + if (path::traits::absolute (e)) + { + p = path (e); + d = p.to_directory (); + } + else + { + if ((d = (e[n - 1] == '/'))) + --n; - p += e; + p = f.path (); + for (; *e == '-'; ++e) + p = p.base (); - target_state r (target_state::unchanged); + p.append (e, n); + } - if (d) - { - dir_path dp (path_cast (p)); + target_state r (target_state::unchanged); - switch (build2::rmdir_r (dp, true, 3)) + if (d) { - case rmdir_status::success: - { - r = target_state::changed; - break; - } - case rmdir_status::not_empty: + dir_path dp (path_cast (p)); + + switch (build2::rmdir_r (dp, true, 3)) { - if (verb >= 3) - text << dp << " is current working directory, not removing"; + case rmdir_status::success: + { + r = target_state::changed; + break; + } + case rmdir_status::not_empty: + { + if (verb >= 3) + text << dp << " is current working directory, not removing"; + break; + } + case rmdir_status::not_exist: break; } - case rmdir_status::not_exist: - break; } - } - else - { - if (rmfile (p, 3)) - r = target_state::changed; - } + else + { + if (rmfile (p, 3)) + r = target_state::changed; + } - if (r == target_state::changed && ep.empty ()) - { - ed = d; - ep = move (p); + if (r == target_state::changed && ep.empty ()) + { + ed = d; + ep = move (p); + } + + er |= r; } + }; - er |= r; - } + auto ei (extra.begin ()), ee (extra.end ()); + + if (ei != ee) + clean (ft, *ei++); // Now clean the ad hoc group file members, if any. // @@ -604,6 +625,9 @@ namespace build2 if (fm == nullptr || fm->path ().empty ()) continue; + if (ei != ee) + clean (*fm, *ei++); + const path& f (fm->path ()); target_state r (rmfile (f, 3) @@ -659,7 +683,7 @@ namespace build2 target_state perform_clean (action a, target& t) { - return clean_extra (a, dynamic_cast (t), {}); + return clean_extra (a, dynamic_cast (t), {nullptr}); } target_state -- cgit v1.1