aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/cc')
-rw-r--r--libbuild2/cc/common.cxx68
-rw-r--r--libbuild2/cc/compile-rule.cxx55
-rw-r--r--libbuild2/cc/functions.cxx8
-rw-r--r--libbuild2/cc/init.cxx2
-rw-r--r--libbuild2/cc/install-rule.cxx2
-rw-r--r--libbuild2/cc/link-rule.cxx4
-rw-r--r--libbuild2/cc/msvc.cxx4
-rw-r--r--libbuild2/cc/pkgconfig.cxx1
8 files changed, 89 insertions, 55 deletions
diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx
index 0589c30..dfc78e7 100644
--- a/libbuild2/cc/common.cxx
+++ b/libbuild2/cc/common.cxx
@@ -950,22 +950,35 @@ namespace build2
const prerequisite_key& p,
bool exist) const
{
+ assert (p.scope != nullptr && (!exist || act));
+
tracer trace (x, "search_library");
- assert (p.scope != nullptr && (!exist || act));
+ context& ctx (p.scope->ctx);
+ const scope& rs (*p.scope->root_scope ());
- // Import phase 1 may pass us a user-specified path with a relative
- // directory (same semantics as in lookup_import() below).
+ // Note: since we are searching for a (presumably) installed library,
+ // utility libraries do not apply.
//
- {
- const dir_path& d (*p.tk.dir);
+ bool l (p.is_a<lib> ());
+ const string& name (*p.tk.name);
+ const optional<string>& ext (l ? nullopt : p.tk.ext); // Only liba/libs.
- if (!d.empty ())
- fail << "relative path in imported " << p;
- }
+ // Import phase 1 may pass us a path specified by the user with
+ // config.import.<proj>.<name>.<type>. The possible cases are:
+ //
+ // 1. Empty or relative directory for liba{} and libs{} (absolute would
+ // be taken care of by phase 1 since these tragets are path-based).
+ //
+ // 2. Empty, relative, or absolute directory for lib{} (since it's not a
+ // path-based target).
+ //
+ const dir_path& dir (*p.tk.dir);
- context& ctx (p.scope->ctx);
- const scope& rs (*p.scope->root_scope ());
+ // Same semantics as in lookup_import() below.
+ //
+ if (!dir.empty () && dir.relative ())
+ fail << "relative path in imported " << p;
// Here is the problem: we may be building for two different toolchains
// simultaneously that use the same installed library. But our search is
@@ -977,17 +990,6 @@ namespace build2
? cpath
: cast<process_path> (rs["bin.ld.path"]));
- // @@ This is hairy enough to warrant a separate implementation for
- // Windows.
-
- // Note: since we are searching for a (presumably) installed library,
- // utility libraries do not apply.
- //
- bool l (p.is_a<lib> ());
- const optional<string>& ext (l ? nullopt : p.tk.ext); // Only liba/libs.
-
- const string& name (*p.tk.name);
-
// If this prerequisite is project-qualified do an ad hoc check for
// config.import.<proj>.<name>.{liba,libs} which can be used to specify
// different path (see import_search() for background). Note that for
@@ -1015,7 +1017,10 @@ namespace build2
//
auto lookup_import = [&rs,
&act,
- &name,
+ namev =
+ (p.proj
+ ? sanitize_identifier (name)
+ : string ()),
projv =
(p.proj
? p.proj->variable ()
@@ -1023,7 +1028,9 @@ namespace build2
{
if (!projv.empty ())
{
- string varn ("config.import." + projv + '.' + name + '.' + tt);
+ // Note: we know tt is liba or libs and need not to be sanitized.
+ //
+ string varn ("config.import." + projv + '.' + namev + '.' + tt);
if (config::specified_config (rs, varn, true /* exact */))
{
@@ -1106,14 +1113,16 @@ namespace build2
//
const char* e ("");
+ an = dir; // Empty or absolute.
+
if (tsys == "win32-msvc")
{
- an = path (name);
+ an /= path (name);
e = "lib";
}
else
{
- an = path ("lib" + name);
+ an /= path ("lib" + name);
e = "a";
}
@@ -1142,14 +1151,16 @@ namespace build2
{
const char* e ("");
+ sn = dir;
+
if (tsys == "win32-msvc")
{
- sn = path (name);
+ sn /= path (name);
e = "dll.lib";
}
else
{
- sn = path ("lib" + name);
+ sn /= path ("lib" + name);
if (tsys == "darwin") e = "dylib";
else if (tsys == "mingw32") e = "dll.a"; // See search code below.
@@ -1556,8 +1567,7 @@ namespace build2
//
string d ("-DLIB");
- d += sanitize_identifier (
- ucase (const_cast<const string&> (t.name)));
+ d += sanitize_identifier (ucase (t.name));
d += '_';
d += suffix;
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index 29a26b5..53d38ac 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -1544,8 +1544,20 @@ namespace build2
// to keep re-validating the file on every subsequent dry-run as well
// on the real run).
//
- if (u && dd.reading () && !ctx.dry_run_option)
- dd.touch = timestamp_unknown;
+ if (u && dd.reading ())
+ {
+ // What will happen if dry_run_option is true but we still end up
+ // performing a non-dry-run update due to update during match or
+ // load? In this case the target will become up-to-date and we will
+ // keep re-validating the cache until the depdb will get touched due
+ // to other reasons, which would be bad. So it feels like the least
+ // bad option is to keep re-touching the database on dry-run.
+ //
+#if 0
+ if (!ctx.dry_run_option)
+#endif
+ dd.touch = timestamp_unknown;
+ }
dd.close (false /* mtime_check */);
md.dd = move (dd.path);
@@ -2338,9 +2350,9 @@ namespace build2
if (verb > 2)
{
- diag_record dr;
- dr << error << "header " << f << " not found and no "
- << "rule to generate it";
+ diag_record dr (error);
+ dr << "header " << f << " not found and no rule to "
+ << "generate it";
if (verb < 4)
dr << info << "re-run with --verbose=4 for more information";
@@ -2913,8 +2925,8 @@ namespace build2
if (verb > 2)
{
- diag_record dr;
- dr << error << "header '" << f << "' not found";
+ diag_record dr (error);
+ dr << "header '" << f << "' not found";
if (verb < 4)
dr << info << "re-run with --verbose=4 for more information";
@@ -4042,11 +4054,14 @@ namespace build2
//
auto fail = [&ctx] (const auto& h) -> optional<bool>
{
+ // Note that this test will give a false negative if this target
+ // ends up being updated during load or match. At least it's
+ // conservative.
+ //
bool df (!ctx.match_only && !ctx.dry_run_option);
- diag_record dr;
- dr << error << "header " << h << " not found and no rule to "
- << "generate it";
+ diag_record dr (error);
+ dr << "header " << h << " not found and no rule to generate it";
if (df)
dr << info << "failure deferred to compiler diagnostics";
@@ -4104,7 +4119,6 @@ namespace build2
this] (path hp, path bp, timestamp mt) -> optional<bool>
{
context& ctx (t.ctx);
- bool df (!ctx.match_only && !ctx.dry_run_option);
const file* ht (
enter_header (a, bs, t, li,
@@ -4113,9 +4127,14 @@ namespace build2
if (ht == nullptr) // hp is still valid.
{
- diag_record dr;
- dr << error << "header " << hp << " not found and no rule to "
- << "generate it";
+ // Note that this test will give a false negative if this target
+ // ends up being updated during load or match. At least it's
+ // conservative.
+ //
+ bool df (!ctx.match_only && !ctx.dry_run_option);
+
+ diag_record dr (error);
+ dr << "header " << hp << " not found and no rule to generate it";
if (df)
dr << info << "failure deferred to compiler diagnostics";
@@ -4964,7 +4983,7 @@ namespace build2
if (pr.wait ())
{
{
- diag_record dr;
+ maybe_diag_record dr;
if (bad_error)
dr << fail << "expected error exit status from "
@@ -5072,7 +5091,7 @@ namespace build2
// preprocessed source files).
//
{
- diag_record dr;
+ maybe_diag_record dr;
if (force_gen_skip && *force_gen_skip == skip_count)
{
dr <<
@@ -5080,11 +5099,11 @@ namespace build2
info << "run the following two commands to investigate";
dr << info;
- print_process (dr, args.data ()); // No pipes.
+ print_process (*dr, args.data ()); // No pipes.
init_args ((gen = true));
dr << info << "";
- print_process (dr, args.data ()); // No pipes.
+ print_process (*dr, args.data ()); // No pipes.
}
if (dbuf.is_open ())
diff --git a/libbuild2/cc/functions.cxx b/libbuild2/cc/functions.cxx
index 9d408af..0adcf5f 100644
--- a/libbuild2/cc/functions.cxx
+++ b/libbuild2/cc/functions.cxx
@@ -76,7 +76,9 @@ namespace build2
for (auto i (ts_ns.begin ()); i != ts_ns.end (); ++i)
{
name& n (*i), o;
- const target& t (to_target (*bs, move (n), move (n.pair ? *++i : o)));
+ const target& t (to_target (*bs,
+ move (n), move (n.pair ? *++i : o),
+ true /* in_recipe */));
if (!t.matched (a))
fail << t << " is not matched" <<
@@ -193,7 +195,9 @@ namespace build2
for (auto i (ts_ns.begin ()); i != ts_ns.end (); ++i)
{
name& n (*i), o;
- const target& t (to_target (*bs, move (n), move (n.pair ? *++i : o)));
+ const target& t (to_target (*bs,
+ move (n), move (n.pair ? *++i : o),
+ true /* in_recipe */));
bool la (false);
if (li
diff --git a/libbuild2/cc/init.cxx b/libbuild2/cc/init.cxx
index d691bc5..64c70f8 100644
--- a/libbuild2/cc/init.cxx
+++ b/libbuild2/cc/init.cxx
@@ -764,7 +764,7 @@ namespace build2
perform_update_id,
context::operation_callback {&compiledb_pre, &compiledb_post});
- if (ctx.load_generation > 1)
+ if (!ctx.phase_mutex.unlocked ()) // Interrupting load.
{
action a (ctx.current_action ());
diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx
index 46764a6..c4f924a 100644
--- a/libbuild2/cc/install-rule.cxx
+++ b/libbuild2/cc/install-rule.cxx
@@ -281,7 +281,7 @@ namespace build2
//
if (!*md.for_install)
fail << "incompatible " << t << " build" <<
- info << "target already built not for install";
+ info << "target already updated but not for install";
}
else
md.for_install = true;
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx
index a669f37..d43e7e8 100644
--- a/libbuild2/cc/link-rule.cxx
+++ b/libbuild2/cc/link-rule.cxx
@@ -2598,8 +2598,8 @@ namespace build2
//
if (*md->for_install != *d.for_install)
fail << "incompatible " << *l << " build" <<
- info << "library is built " << (*md->for_install ? "" : "not ")
- << "for install";
+ info << "target is already updated but "
+ << (*md->for_install ? "" : "not ") << "for install";
}
auto newer = [&d, l] ()
diff --git a/libbuild2/cc/msvc.cxx b/libbuild2/cc/msvc.cxx
index 416df36..66223b5 100644
--- a/libbuild2/cc/msvc.cxx
+++ b/libbuild2/cc/msvc.cxx
@@ -511,8 +511,8 @@ namespace build2
if (!run_finish_code (args, pr, s, 2 /* verbosity */) || io)
{
- diag_record dr;
- dr << warn << "unable to detect " << l << " library type, ignoring" <<
+ diag_record dr (warn);
+ dr << "unable to detect " << l << " library type, ignoring" <<
info << "run the following command to investigate" <<
info; print_process (dr, args);
return otype::e;
diff --git a/libbuild2/cc/pkgconfig.cxx b/libbuild2/cc/pkgconfig.cxx
index 79a38ea..d4be03b 100644
--- a/libbuild2/cc/pkgconfig.cxx
+++ b/libbuild2/cc/pkgconfig.cxx
@@ -693,6 +693,7 @@ namespace build2
cmp ("msxml", 5) || // msxml*
cmp ("netapi32") ||
cmp ("normaliz") ||
+ cmp ("ntdll") ||
cmp ("odbc32") ||
cmp ("ole32") ||
cmp ("oleaut32") ||