diff options
Diffstat (limited to 'libbuild2/cc')
-rw-r--r-- | libbuild2/cc/common.cxx | 68 | ||||
-rw-r--r-- | libbuild2/cc/compile-rule.cxx | 55 | ||||
-rw-r--r-- | libbuild2/cc/functions.cxx | 8 | ||||
-rw-r--r-- | libbuild2/cc/init.cxx | 2 | ||||
-rw-r--r-- | libbuild2/cc/install-rule.cxx | 2 | ||||
-rw-r--r-- | libbuild2/cc/link-rule.cxx | 4 | ||||
-rw-r--r-- | libbuild2/cc/msvc.cxx | 4 | ||||
-rw-r--r-- | libbuild2/cc/pkgconfig.cxx | 1 |
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") || |