aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2018-04-30 07:53:13 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-30 07:57:30 -0700
commit3e50e3565b1d39a8ab82d817bca9bc2eb3ca8fc1 (patch)
treecc3f392f17e4fb59adafc133ef683f8f38e8d59b /src/tools
parentb083de868ff2dab43ef2fed111aa860aed0f73c8 (diff)
Make runfiles usage on Windows more flexible to support remote execution.
When trying to find a runfile on Windows: 1. First look for the runfiles MANIFEST and find runfile locations using this if it exists (current behavior). 2. If no MANIFEST file exists, look for runfiles in the runfiles directory (new behavior). As part of this, remove setting RUNFILES_MANIFEST_ONLY for the benefit of test-setup.sh. Instead of telling it what to do, it decides what to do based on the observed state of the world. Launchers still set RUNFILES_MANIFEST_ONLY for the benefit of launched programs, since some may depend on this. Fixes https://github.com/bazelbuild/bazel/issues/4962. RELNOTES: Remote execution works for Windows binaries with launchers. PiperOrigin-RevId: 194785440
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/launcher/launcher.cc43
-rw-r--r--src/tools/launcher/launcher.h7
2 files changed, 43 insertions, 7 deletions
diff --git a/src/tools/launcher/launcher.cc b/src/tools/launcher/launcher.cc
index d26506e1b1..515733814f 100644
--- a/src/tools/launcher/launcher.cc
+++ b/src/tools/launcher/launcher.cc
@@ -33,15 +33,33 @@ using std::string;
using std::unordered_map;
using std::vector;
+static std::string GetRunfilesDir(const char* argv0) {
+ string runfiles_dir;
+ // If RUNFILES_DIR is already set (probably we are either in a test or in a
+ // data dependency) then use it.
+ if (GetEnv("RUNFILES_DIR", &runfiles_dir)) {
+ return runfiles_dir;
+ }
+ // Otherwise this is probably a top-level non-test binary (e.g. a genrule
+ // tool) and should look for its runfiles beside the executable.
+ return GetBinaryPathWithExtension(argv0) + ".runfiles";
+}
+
BinaryLauncherBase::BinaryLauncherBase(
const LaunchDataParser::LaunchInfo& _launch_info, int argc, char* argv[])
: launch_info(_launch_info),
manifest_file(FindManifestFile(argv[0])),
+ runfiles_dir(GetRunfilesDir(argv[0])),
workspace_name(GetLaunchInfoByKey(WORKSPACE_NAME)) {
for (int i = 0; i < argc; i++) {
- this->commandline_arguments.push_back(argv[i]);
+ commandline_arguments.push_back(argv[i]);
+ }
+ // Prefer to use the runfiles manifest, if it exists, but otherwise the
+ // runfiles directory will be used by default. On Windows, the manifest is
+ // used locally, and the runfiles directory is used remotely.
+ if (manifest_file != "") {
+ ParseManifestFile(&manifest_file_map, manifest_file);
}
- ParseManifestFile(&this->manifest_file_map, this->manifest_file);
}
static bool FindManifestFileImpl(const char* argv0, string* result) {
@@ -80,7 +98,7 @@ static bool FindManifestFileImpl(const char* argv0, string* result) {
string BinaryLauncherBase::FindManifestFile(const char* argv0) {
string manifest_file;
if (!FindManifestFileImpl(argv0, &manifest_file)) {
- die("Couldn't find runfiles manifest file.");
+ return "";
}
// The path will be set as the RUNFILES_MANIFEST_FILE envvar and used by the
// shell script, so let's convert backslashes to forward slashes.
@@ -117,6 +135,17 @@ void BinaryLauncherBase::ParseManifestFile(ManifestFileMap* manifest_file_map,
string BinaryLauncherBase::Rlocation(const string& path,
bool need_workspace_name) const {
+ // If the manifest file map is empty, then we're using the runfiles directory
+ // instead.
+ if (manifest_file_map.empty()) {
+ string query_path = runfiles_dir;
+ if (need_workspace_name) {
+ query_path += "/" + this->workspace_name;
+ }
+ query_path += "/" + path;
+ return query_path;
+ }
+
string query_path = path;
if (need_workspace_name) {
query_path = this->workspace_name + "/" + path;
@@ -182,8 +211,12 @@ ExitCode BinaryLauncherBase::LaunchProcess(const string& executable,
if (PrintLauncherCommandLine(executable, arguments)) {
return 0;
}
- SetEnv("RUNFILES_MANIFEST_ONLY", "1");
- SetEnv("RUNFILES_MANIFEST_FILE", manifest_file);
+ if (manifest_file != "") {
+ SetEnv("RUNFILES_MANIFEST_ONLY", "1");
+ SetEnv("RUNFILES_MANIFEST_FILE", manifest_file);
+ } else {
+ SetEnv("RUNFILES_DIR", runfiles_dir);
+ }
CmdLine cmdline;
CreateCommandLine(&cmdline, executable, arguments);
PROCESS_INFORMATION processInfo = {0};
diff --git a/src/tools/launcher/launcher.h b/src/tools/launcher/launcher.h
index 088bd5d740..4dca6e000d 100644
--- a/src/tools/launcher/launcher.h
+++ b/src/tools/launcher/launcher.h
@@ -82,9 +82,12 @@ class BinaryLauncherBase {
// A map to store all the launch information.
const LaunchDataParser::LaunchInfo& launch_info;
- // Absolute path to the runfiles manifest file.
+ // Absolute path to the runfiles manifest file, if one exists.
const std::string manifest_file;
+ // Path to the runfiles directory, if one exists.
+ const std::string runfiles_dir;
+
// The commandline arguments recieved.
// The first argument is the path of this launcher itself.
std::vector<std::string> commandline_arguments;
@@ -111,7 +114,7 @@ class BinaryLauncherBase {
void CreateCommandLine(CmdLine* result, const std::string& executable,
const std::vector<std::string>& arguments) const;
- // Find manifest file of the binary
+ // Find manifest file of the binary.
//
// Expect the manifest file to be at
// 1. <path>/<to>/<binary>/<target_name>.runfiles/MANIFEST