diff options
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/buildfile | 4 | ||||
-rw-r--r-- | libbuild2/cc/compile-rule.cxx | 14 | ||||
-rw-r--r-- | libbuild2/cc/guess.cxx | 44 | ||||
-rw-r--r-- | libbuild2/cc/link-rule.cxx | 70 | ||||
-rw-r--r-- | libbuild2/config.hxx.in | 2 | ||||
-rw-r--r-- | libbuild2/functions-filesystem.cxx | 51 | ||||
-rw-r--r-- | libbuild2/utility.hxx | 28 | ||||
-rw-r--r-- | libbuild2/utility.txx | 21 | ||||
-rw-r--r-- | libbuild2/variable.cxx | 6 |
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. |