aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/buildfile4
-rw-r--r--libbuild2/cc/compile-rule.cxx14
-rw-r--r--libbuild2/cc/guess.cxx44
-rw-r--r--libbuild2/cc/link-rule.cxx70
-rw-r--r--libbuild2/config.hxx.in2
-rw-r--r--libbuild2/functions-filesystem.cxx51
-rw-r--r--libbuild2/utility.hxx28
-rw-r--r--libbuild2/utility.txx21
-rw-r--r--libbuild2/variable.cxx6
9 files changed, 190 insertions, 50 deletions
diff --git a/libbuild2/buildfile b/libbuild2/buildfile
index 3518d93..d9711e6 100644
--- a/libbuild2/buildfile
+++ b/libbuild2/buildfile
@@ -293,7 +293,7 @@ if ($install.root != [null])
if ($cxx.target.class != 'windows')
{
- libul{build2}: cxx.libs += -lpthread
+ libul{build2}: cxx.libs += -pthread
# Note: only linking libdl in shared build.
#
@@ -323,7 +323,7 @@ lib{build2}:
# needed for some std::thread implementations (like libstdc++).
#
if ($cxx.target.class != 'windows')
- lib{build2}: cxx.export.libs += -lpthread
+ lib{build2}: cxx.export.libs += -pthread
liba{build2}: cxx.export.poptions += -DLIBBUILD2_STATIC
libs{build2}: cxx.export.poptions += -DLIBBUILD2_SHARED
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index 7629ed5..95ba89f 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -3213,7 +3213,21 @@ namespace build2
if (f != nullptr)
{
//cache_cls.fetch_add (1, memory_order_relaxed);
+
+#if 0
assert (r.first == f);
+#else
+ if (r.first != f)
+ {
+ info << "inconsistent header cache content" <<
+ info << "encountered: " << *f <<
+ info << "expected: " << *r.first <<
+ info << "please report at "
+ << "https://github.com/build2/build2/issues/390";
+
+ assert (r.first == f);
+ }
+#endif
}
}
diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx
index d7e9c63..5ae6fb2 100644
--- a/libbuild2/cc/guess.cxx
+++ b/libbuild2/cc/guess.cxx
@@ -2580,27 +2580,29 @@ namespace build2
//
// Note that this is Apple Clang version and not XCode version.
//
- // 4.2 -> 3.2svn
- // 5.0 -> 3.3svn
- // 5.1 -> 3.4svn
- // 6.0 -> 3.5svn
- // 6.1.0 -> 3.6svn
- // 7.0.0 -> 3.7
- // 7.3.0 -> 3.8
- // 8.0.0 -> 3.9
- // 8.1.0 -> ?
- // 9.0.0 -> 4.0
- // 9.1.0 -> 5.0
- // 10.0.0 -> 6.0
- // 11.0.0 -> 7.0
- // 11.0.3 -> 8.0 (yes, seriously!)
- // 12.0.0 -> 9.0
- // 12.0.5 -> 10.0 (yes, seriously!)
- // 13.0.0 -> 11.0
- // 13.1.6 -> 12.0
- // 14.0.0 -> 12.0 (_LIBCPP_VERSION=130000)
- // 14.0.3 -> 15.0 (_LIBCPP_VERSION=150006)
- // 15.0.0 -> 16.0 (_LIBCPP_VERSION=160002)
+ // 4.2 -> 3.2svn
+ // 5.0 -> 3.3svn
+ // 5.1 -> 3.4svn
+ // 6.0 -> 3.5svn
+ // 6.1.0 -> 3.6svn
+ // 7.0.0 -> 3.7
+ // 7.3.0 -> 3.8
+ // 8.0.0 -> 3.9
+ // 8.1.0 -> ?
+ // 9.0.0 -> 4.0
+ // 9.1.0 -> 5.0
+ // 10.0.0 -> 6.0
+ // 11.0.0 -> 7.0
+ // 11.0.3 -> 8.0 (yes, seriously!)
+ // 12.0.0 -> 9.0
+ // 12.0.5 -> 10.0 (yes, seriously!)
+ // 13.0.0 -> 11.0
+ // 13.1.6 -> 12.0
+ // 14.0.0 -> 12.0 (_LIBCPP_VERSION=130000)
+ // 14.0.3 -> 15.0 (_LIBCPP_VERSION=150006)
+ // 15.0.0.0 -> 16.0 (_LIBCPP_VERSION=160002)
+ // 15.0.0.1 -> 16.0 (_LIBCPP_VERSION=160006)
+ // 15.0.0.3 -> 16.0 (_LIBCPP_VERSION=170006)
//
uint64_t mj (var_ver->major);
uint64_t mi (var_ver->minor);
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx
index 08a60b9..417cba5 100644
--- a/libbuild2/cc/link-rule.cxx
+++ b/libbuild2/cc/link-rule.cxx
@@ -2585,6 +2585,24 @@ namespace build2
// We don't rpath system libraries. Why, you may ask? There are many
// good reasons and I have them written on a napkin somewhere...
//
+ // Well, the main reason is that we naturally assume the dynamic
+ // linker searches there by default and so there is no need for rpath.
+ // Plus, rpath would prevent "overriding" distribution-system
+ // (/usr/lib) libraries with user-system (/usr/local/lib).
+ //
+ // Note, however, that some operating systems don't search in
+ // /usr/local/lib by default (for example, Fedora, RHEL, Mac OS since
+ // version 13). In a sense, on these platforms /usr/local is
+ // "half-system" in that the system compiler by default searches in
+ // /usr/local/include and/or /usr/local/lib (see config_module::init()
+ // for background) but the dynamic linker does not. While we could
+ // hack this test for such platforms and add rpath for /usr/local/lib,
+ // this is still feels wrong (the user can always "fix" such an
+ // operating system by instructing the dynamic linker to search in
+ // /usr/local/lib, as many, including ourselves, do). So for now we
+ // are not going to do anything. In the end, the user can always add
+ // an rpath for /usr/local/lib manually.
+ //
// We also assume system libraries can only depend on other system
// libraries and so can prune the traversal.
//
@@ -2596,18 +2614,26 @@ namespace build2
size_t p (path::traits_type::rfind_separator (f));
assert (p != string::npos);
+ // For good measure, also suppress duplicates at the options level.
+ // This will take care of different libraries built in the same
+ // directory, system-installed, etc.
+
if (d.rpath)
{
string o ("-Wl,-rpath,");
o.append (f, 0, (p != 0 ? p : 1)); // Don't include trailing slash.
- d.args.push_back (move (o));
+
+ if (find (d.args.begin (), d.args.end (), o) == d.args.end ())
+ d.args.push_back (move (o));
}
if (d.rpath_link)
{
string o ("-Wl,-rpath-link,");
o.append (f, 0, (p != 0 ? p : 1));
- d.args.push_back (move (o));
+
+ if (find (d.args.begin (), d.args.end (), o) == d.args.end ())
+ d.args.push_back (move (o));
}
};
@@ -2660,7 +2686,9 @@ namespace build2
if ((c
? f.compare (p, string::npos, e)
: icasecmp (f.c_str () + p, e)) == 0)
+ {
append (f);
+ }
}
}
@@ -2671,13 +2699,22 @@ namespace build2
{
// Top-level shared library dependency.
//
+ // As above, suppress duplicates.
+ //
+ if (find (d.ls.begin (), d.ls.end (), &l) != d.ls.end ())
+ return;
+
if (!l.path ().empty ()) // Not binless.
{
// It is either matched or imported so should be a cc library.
//
if (!cast_false<bool> (l.vars[c_system]))
{
- args.push_back ("-Wl,-rpath," + l.path ().directory ().string ());
+ string o ("-Wl,-rpath," + l.path ().directory ().string ());
+
+ if (find (args.begin (), args.end (), o) == args.end ())
+ args.push_back (move (o));
+
ls.push_back (&l);
}
}
@@ -3332,6 +3369,9 @@ namespace build2
origin = p.directory ();
}
+ // Note: suppress duplicates at the options level, similar to
+ // rpath_libraries().
+
bool origin_used (false);
for (const dir_path& p: cast<dir_paths> (l))
{
@@ -3368,7 +3408,8 @@ namespace build2
else
o += p.string ();
- sargs.push_back (move (o));
+ if (find (sargs.begin (), sargs.end (), o) == sargs.end ())
+ sargs.push_back (move (o));
}
// According to the Internet, `-Wl,-z,origin` is not needed except
@@ -3386,7 +3427,12 @@ namespace build2
fail << ctgt << " does not support rpath-link";
for (const dir_path& p: cast<dir_paths> (l))
- sargs.push_back ("-Wl,-rpath-link," + p.string ());
+ {
+ string o ("-Wl,-rpath-link," + p.string ());
+
+ if (find (sargs.begin (), sargs.end (), o) == sargs.end ())
+ sargs.push_back (move (o));
+ }
}
}
@@ -3433,13 +3479,19 @@ namespace build2
append_args (sargs1);
}
- else
+ else if (b != x)
{
- append_option_values (
- args,
+ // Use the more canonical combined form (-L/usr/local/lib) even
+ // though it's less efficient (the split one is just too much of an
+ // eye-sore in the logs).
+ //
+ append_combined_option_values (
+ sargs1,
"-L",
b, x,
- [] (const dir_path& d) {return d.string ().c_str ();});
+ [] (const dir_path& d) -> const string& {return d.string ();});
+
+ append_args (sargs1);
}
}
diff --git a/libbuild2/config.hxx.in b/libbuild2/config.hxx.in
index 9a2e01f..17ca6cc 100644
--- a/libbuild2/config.hxx.in
+++ b/libbuild2/config.hxx.in
@@ -18,7 +18,7 @@
// toolchain. Bootstrap will be a problem though. (Maybe set it to nullptr and
// say that it shall not be queried?)
//
-#define LIBBUILD2_STAGE true
+#define LIBBUILD2_STAGE false
// Modification time sanity checks are by default only enabled for the staged
// version unless we are on Windows (which is known not to guarantee
diff --git a/libbuild2/functions-filesystem.cxx b/libbuild2/functions-filesystem.cxx
index 665a0f3..340c2bc 100644
--- a/libbuild2/functions-filesystem.cxx
+++ b/libbuild2/functions-filesystem.cxx
@@ -5,6 +5,7 @@
#include <libbuild2/function.hxx>
#include <libbuild2/variable.hxx>
+#include <libbuild2/filesystem.hxx>
using namespace std;
using namespace butl;
@@ -95,14 +96,60 @@ namespace build2
return r;
}
+ static bool
+ file_exists (path&& f)
+ {
+ if (f.relative () && path_traits::thread_current_directory () != nullptr)
+ f.complete ();
+
+ return exists (f);
+ }
+
+ static bool
+ directory_exists (dir_path&& d)
+ {
+ if (d.relative () && path_traits::thread_current_directory () != nullptr)
+ d.complete ();
+
+ return exists (d);
+ }
+
void
filesystem_functions (function_map& m)
{
- // @@ Maybe we should have the ability to mark the whole family as not
- // pure?
+ // NOTE: anything that depends on relative path must handle the
+ // thread-specific curren directory override explicitly.
function_family f (m, "filesystem");
+ // $file_exists(<path>)
+ //
+ // Return true if a filesystem entry at the specified path exists and is a
+ // regular file (or is a symlink to a regular file) and false otherwise.
+ //
+ // Note that this function is not pure.
+ //
+ {
+ auto e (f.insert ("file_exists", false));
+
+ e += [](path f) {return file_exists (move (f));};
+ e += [](names ns) {return file_exists (convert<path> (move (ns)));};
+ }
+
+ // $directory_exists(<path>)
+ //
+ // Return true if a filesystem entry at the specified path exists and is a
+ // directory (or is a symlink to a directory) and false otherwise.
+ //
+ // Note that this function is not pure.
+ //
+ {
+ auto e (f.insert ("directory_exists", false));
+
+ e += [](path f) {return directory_exists (path_cast<dir_path> (move (f)));};
+ e += [](names ns) {return directory_exists (convert<dir_path> (move (ns)));};
+ }
+
// $path_search(<pattern>[, <start-dir>])
//
// Return filesystem paths that match the shell-like wildcard pattern. If
diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx
index b534f41..151b409 100644
--- a/libbuild2/utility.hxx
+++ b/libbuild2/utility.hxx
@@ -877,17 +877,29 @@ namespace build2
//
template <typename I, typename F>
void
- append_option_values (cstrings&,
- const char* opt,
- I begin, I end,
- F&& get = [] (const string& s) {return s.c_str ();});
+ append_option_values (
+ cstrings&,
+ const char* opt,
+ I begin, I end,
+ F&& get = [] (const string& s) {return s.c_str ();});
template <typename I, typename F>
void
- append_option_values (sha256&,
- const char* opt,
- I begin, I end,
- F&& get = [] (const string& s) {return s;});
+ append_option_values (
+ sha256&,
+ const char* opt,
+ I begin, I end,
+ F&& get = [] (const string& s) -> const string& {return s;});
+
+ // As above but in a combined form (e.g., -L/usr/local/lib).
+ //
+ template <typename I, typename F>
+ void
+ append_combined_option_values (
+ strings&,
+ const char* opt,
+ I begin, I end,
+ F&& get = [] (const string& s) -> const string& {return s;});
// As above but append a single option (used for append/hash uniformity).
//
diff --git a/libbuild2/utility.txx b/libbuild2/utility.txx
index d2fc29c..cdf510f 100644
--- a/libbuild2/utility.txx
+++ b/libbuild2/utility.txx
@@ -5,16 +5,16 @@ namespace build2
{
template <typename I, typename F>
void
- append_option_values (cstrings& args, const char* o, I b, I e, F&& get)
+ append_option_values (cstrings& ss, const char* o, I b, I e, F&& get)
{
if (b != e)
{
- args.reserve (args.size () + (e - b));
+ ss.reserve (ss.size () + (e - b));
for (; b != e; ++b)
{
- args.push_back (o);
- args.push_back (get (*b));
+ ss.push_back (o);
+ ss.push_back (get (*b));
}
}
}
@@ -30,6 +30,19 @@ namespace build2
}
}
+ template <typename I, typename F>
+ void
+ append_combined_option_values (strings& ss, const char* o, I b, I e, F&& get)
+ {
+ if (b != e)
+ {
+ ss.reserve (ss.size () + (e - b));
+
+ for (; b != e; ++b)
+ ss.push_back (string (o) += get (*b));
+ }
+ }
+
template <typename K>
basic_path<char, K>
relative (const basic_path<char, K>& p)
diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx
index 078c13a..fb9e840 100644
--- a/libbuild2/variable.cxx
+++ b/libbuild2/variable.cxx
@@ -510,7 +510,7 @@ namespace build2
&simple_append<bool>, // Prepend same as append.
&simple_reverse<bool>,
nullptr, // No cast (cast data_ directly).
- nullptr, // No compare (compare as POD).
+ &simple_compare<bool>,
nullptr, // Never empty.
nullptr, // Subscript.
nullptr // Iterate.
@@ -570,7 +570,7 @@ namespace build2
&simple_append<int64_t>, // Prepend same as append.
&simple_reverse<int64_t>,
nullptr, // No cast (cast data_ directly).
- nullptr, // No compare (compare as POD).
+ &simple_compare<int64_t>,
nullptr, // Never empty.
nullptr, // Subscript.
nullptr // Iterate.
@@ -632,7 +632,7 @@ namespace build2
&simple_append<uint64_t>, // Prepend same as append.
&simple_reverse<uint64_t>,
nullptr, // No cast (cast data_ directly).
- nullptr, // No compare (compare as POD).
+ &simple_compare<uint64_t>,
nullptr, // Never empty.
nullptr, // Subscript.
nullptr // Iterate.