aboutsummaryrefslogtreecommitdiff
path: root/build2/algorithm.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-29 19:31:16 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-29 19:31:16 +0200
commit2720b45ef0ca9fd58c11fd9b4f000e1cf3a0819d (patch)
tree4505f65e4f997889e01d4b69bdf94257223d3dc6 /build2/algorithm.cxx
parent47e89b188ac71627f43e0bb8c47ffe08f6c1b919 (diff)
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
Diffstat (limited to 'build2/algorithm.cxx')
-rw-r--r--build2/algorithm.cxx102
1 files changed, 63 insertions, 39 deletions
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<const char*> es)
+ clean_extra (action a,
+ file& ft,
+ initializer_list<initializer_list<const char*>> 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<const char*> 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<dir_path> (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<dir_path> (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<file&> (t), {});
+ return clean_extra (a, dynamic_cast<file&> (t), {nullptr});
}
target_state