aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/link-rule.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-10-09 12:08:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-10-09 12:08:45 +0200
commit66de0d06e5b6c002cbc7d18e18685e3ea44d3848 (patch)
tree34688ee9d0c4d00de0f58e2f6f017f026a23abe6 /libbuild2/cc/link-rule.cxx
parent09e0cf71552d7f6e4f864b997db9913b9e9ae187 (diff)
Prepend pattern search paths to PATH when running binutils
This way any dependent tools (such as mt.exe that is invoked by link.exe) are first search for in there.
Diffstat (limited to 'libbuild2/cc/link-rule.cxx')
-rw-r--r--libbuild2/cc/link-rule.cxx70
1 files changed, 66 insertions, 4 deletions
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx
index cd31058..8aedcad 100644
--- a/libbuild2/cc/link-rule.cxx
+++ b/libbuild2/cc/link-rule.cxx
@@ -19,6 +19,7 @@
#include <libbuild2/diagnostics.hxx>
#include <libbuild2/bin/target.hxx>
+#include <libbuild2/bin/utility.hxx>
#include <libbuild2/cc/target.hxx> // c, pc*
#include <libbuild2/cc/utility.hxx>
@@ -37,7 +38,7 @@ namespace build2
link_rule::
link_rule (data&& d)
: common (move (d)),
- rule_id (string (x) += ".link 1")
+ rule_id (string (x) += ".link 2")
{
static_assert (sizeof (match_data) <= target::data_size,
"insufficient space");
@@ -1939,6 +1940,47 @@ namespace build2
//
depdb dd (tp + ".d");
+ // Adjust the environment.
+ //
+ using environment = small_vector<string, 1>;
+ environment env;
+ sha256 env_cs;
+
+ // If we have the search paths in the binutils pattern, prepend them to
+ // the PATH environment variable so that any dependent tools (such as
+ // mt.exe that is invoked by link.exe) are first search for in there.
+ //
+ {
+ bin::pattern_paths pat (bin::lookup_pattern (rs));
+
+ if (pat.paths != nullptr)
+ {
+ string v ("PATH=");
+ v += pat.paths;
+
+ env_cs.append (v); // Hash only what we are adding.
+
+ if (optional<string> o = getenv ("PATH"))
+ {
+ v += path::traits_type::path_separator;
+ v += *o;
+ }
+
+ env.push_back (move (v));
+ }
+ }
+
+ // Convert the environment to what's expected by the process API.
+ //
+ small_vector<const char*, environment::small_size + 1> env_ptrs;
+ if (!env.empty ())
+ {
+ for (const string& v: env)
+ env_ptrs.push_back (v.c_str ());
+
+ env_ptrs.push_back (nullptr);
+ }
+
// If targeting Windows, take care of the manifest.
//
path manifest; // Manifest itself (msvc) or compiled object file.
@@ -1989,7 +2031,13 @@ namespace build2
try
{
- process pr (rc, args, -1);
+ process pr (rc,
+ args,
+ -1 /* stdin */,
+ 1 /* stdout */,
+ 2 /* stderr */,
+ nullptr /* cwd */,
+ env_ptrs.empty () ? nullptr : env_ptrs.data ());
try
{
@@ -2090,6 +2138,11 @@ namespace build2
l4 ([&]{trace << "linker mismatch forcing update of " << t;});
}
+ // Hash and compare any changes to the environment.
+ //
+ if (dd.expect (env_cs.string ()) != nullptr)
+ l4 ([&]{trace << "environment mismatch forcing update of " << t;});
+
// Next check the target. While it might be incorporated into the linker
// checksum, it also might not (e.g., VC link.exe).
//
@@ -2905,7 +2958,13 @@ namespace build2
//
bool filter (tsys == "win32-msvc" && !lt.static_library ());
- process pr (*ld, args.data (), 0, (filter ? -1 : 2));
+ process pr (*ld,
+ args.data (),
+ 0 /* stdin */,
+ (filter ? -1 : 2) /* stdout */,
+ 2 /* stderr */,
+ nullptr /* cwd */,
+ env_ptrs.empty () ? nullptr : env_ptrs.data ());
if (filter)
{
@@ -2986,7 +3045,10 @@ namespace build2
print_process (args);
if (!ctx.dry_run)
- run (rl, args);
+ run (rl,
+ args,
+ dir_path () /* cwd */,
+ env_ptrs.empty () ? nullptr : env_ptrs.data ());
}
// For Windows generate (or clean up) rpath-emulating assembly.