aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-08-15 09:57:42 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-08-15 09:57:42 +0200
commitd33558b7335a469942e204f73de6faed81f8041f (patch)
tree9e7bbddc59d5528b2c818a06c6700a932bc19856
parent05c5e65dc69bdda66b9b73a10a107b901abf3bc3 (diff)
Add support for bin.lib.load_suffix
This allow the creation of yet another symlink to the shared library that is meant to be used for dynamic loading. For example, we may want to embed the main program interface number into its plugins to make sure that we only load compatible versions.
-rw-r--r--build2/bin/init.cxx7
-rw-r--r--build2/cc/install-rule.cxx4
-rw-r--r--build2/cc/link-rule.cxx29
-rw-r--r--build2/cc/link-rule.hxx9
4 files changed, 39 insertions, 10 deletions
diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx
index e9063fc..b46d643 100644
--- a/build2/bin/init.cxx
+++ b/build2/bin/init.cxx
@@ -118,10 +118,13 @@ namespace build2
//
vp.insert<bool> ("bin.whole", false, variable_visibility::target);
- vp.insert<string> ("bin.lib.prefix");
- vp.insert<string> ("bin.lib.suffix");
vp.insert<string> ("bin.exe.prefix");
vp.insert<string> ("bin.exe.suffix");
+ vp.insert<string> ("bin.lib.prefix");
+ vp.insert<string> ("bin.lib.suffix");
+
+ vp.insert<string> ("bin.lib.load_suffix",
+ variable_visibility::project);
vp.insert<map<string, string>> ("bin.lib.version",
variable_visibility::project);
diff --git a/build2/cc/install-rule.cxx b/build2/cc/install-rule.cxx
index f8058d7..a3a8253 100644
--- a/build2/cc/install-rule.cxx
+++ b/build2/cc/install-rule.cxx
@@ -216,6 +216,7 @@ namespace build2
};
const path& lk (lp.link);
+ const path& ld (lp.load);
const path& so (lp.soname);
const path& in (lp.interm);
@@ -223,6 +224,7 @@ namespace build2
if (!in.empty ()) {r = ln (*f, in) || r; f = &in;}
if (!so.empty ()) {r = ln (*f, so) || r; f = &so;}
+ if (!ld.empty ()) {r = ln (*f, ld) || r; f = &ld;}
if (!lk.empty ()) {r = ln (*f, lk) || r; }
}
@@ -247,10 +249,12 @@ namespace build2
};
const path& lk (lp.link);
+ const path& ld (lp.load);
const path& so (lp.soname);
const path& in (lp.interm);
if (!lk.empty ()) r = rm (lk) || r;
+ if (!ld.empty ()) r = rm (ld) || r;
if (!so.empty ()) r = rm (so) || r;
if (!in.empty ()) r = rm (in) || r;
}
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index 5ca7865..acc5b7e 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -365,7 +365,7 @@ namespace build2
// Now determine the paths.
//
- path lk, so, in;
+ path lk, ld, so, in;
// We start with the basic path.
//
@@ -418,12 +418,25 @@ namespace build2
append_ext (lk);
}
+ // See if we need the load name.
+ //
+ if (const string* s = cast_null<string> (ls["bin.lib.load_suffix"]))
+ {
+ if (!s->empty ())
+ {
+ b += *s;
+ ld = b;
+ append_ext (ld);
+ }
+ }
+
if (!v.empty ())
b += v;
const path& re (ls.derive_path (move (b)));
- return libs_paths {move (lk), move (so), move (in), &re, move (cp)};
+ return libs_paths {
+ move (lk), move (ld), move (so), move (in), &re, move (cp)};
}
// Look for binary-full utility library recursively until we hit a
@@ -2553,10 +2566,11 @@ namespace build2
return s.empty () || m.string ().compare (0, s.size (), s) != 0;
};
- if (test (*paths.real) &&
- test (paths.interm) &&
- test (paths.soname) &&
- test (paths.link))
+ if (test (*paths.real) &&
+ test ( paths.interm) &&
+ test ( paths.soname) &&
+ test ( paths.load) &&
+ test ( paths.link))
{
try_rmfile (m);
try_rmfile (m + ".d");
@@ -2863,6 +2877,7 @@ namespace build2
const libs_paths& paths (md.libs_data);
const path& lk (paths.link);
+ const path& ld (paths.load);
const path& so (paths.soname);
const path& in (paths.interm);
@@ -2870,6 +2885,7 @@ namespace build2
if (!in.empty ()) {ln (f->leaf (), in); f = &in;}
if (!so.empty ()) {ln (f->leaf (), so); f = &so;}
+ if (!ld.empty ()) {ln (f->leaf (), ld); f = &ld;}
if (!lk.empty ()) {ln (f->leaf (), lk);}
}
else if (lt.static_library ())
@@ -2978,6 +2994,7 @@ namespace build2
};
add (lp.link);
+ add (lp.load);
add (lp.soname);
add (lp.interm);
}
diff --git a/build2/cc/link-rule.hxx b/build2/cc/link-rule.hxx
index 14c6fa1..3c51121 100644
--- a/build2/cc/link-rule.hxx
+++ b/build2/cc/link-rule.hxx
@@ -57,13 +57,18 @@ namespace build2
struct libs_paths
{
// If any (except real) is empty, then it is the same as the next
- // one. Except for intermediate, for which empty indicates that it is
- // not used.
+ // one. Except for load and intermediate, for which empty indicates
+ // that it is not used.
+ //
+ // Note that the paths must form a "hierarchy" with subsequent paths
+ // adding extra information as suffixes. This is relied upon by the
+ // clean pattern (see below).
//
// The libs{} path is always the real path. On Windows what we link
// to is the import library and the link path is empty.
//
path link; // What we link: libfoo.so
+ path load; // What we load (with dlopen() or similar)
path soname; // SONAME: libfoo-1.so, libfoo.so.1
path interm; // Intermediate: libfoo.so.1.2
const path* real; // Real: libfoo.so.1.2.3