Fixed repository.which() on Windows
Also removed previous workaround in cc_configure.bzl
--
Change-Id: I6dcd039fc5e18af8f2d21969641d6bbd05c8badc
Reviewed-on: https://bazel-review.googlesource.com/#/c/4034
MOS_MIGRATED_REVID=127518922
diff --git a/src/main/cpp/blaze_util_mingw.cc b/src/main/cpp/blaze_util_mingw.cc
index 6f0df54..7dd3b93 100644
--- a/src/main/cpp/blaze_util_mingw.cc
+++ b/src/main/cpp/blaze_util_mingw.cc
@@ -510,6 +510,10 @@
string ListSeparator() { return ";"; }
string ConvertPath(const string& path) {
+ // If the path looks like %USERPROFILE%/foo/bar, don't convert.
+ if (path.empty() || path[0] == '%') {
+ return path;
+ }
char* wpath = static_cast<char*>(cygwin_create_path(
CCP_POSIX_TO_WIN_A, static_cast<const void*>(path.c_str())));
string result(wpath);
@@ -517,6 +521,21 @@
return result;
}
+// Convert a Unix path list to Windows path list
+string ConvertPathList(const string& path_list) {
+ string w_list = "";
+ int start = 0;
+ int pos;
+ while ((pos = path_list.find(":", start)) != string::npos) {
+ w_list += ConvertPath(path_list.substr(start, pos - start)) + ";";
+ start = pos + 1;
+ }
+ if (start < path_list.size()) {
+ w_list += ConvertPath(path_list.substr(start));
+ }
+ return w_list;
+}
+
string ConvertPathToPosix(const string& win_path) {
char* posix_path = static_cast<char*>(cygwin_create_path(
CCP_WIN_A_TO_POSIX, static_cast<const void*>(win_path.c_str())));
diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h
index 71c7a84..c6e1d70 100644
--- a/src/main/cpp/blaze_util_platform.h
+++ b/src/main/cpp/blaze_util_platform.h
@@ -84,6 +84,12 @@
// is Windows path.
std::string ConvertPath(const std::string& path);
+// Convert a path list from Bazel internal form to underlying OS form.
+// On Unixes this is an identity operation.
+// On Windows, Bazel internal form is cygwin path list, and underlying OS form
+// is Windows path list.
+std::string ConvertPathList(const std::string& path_list);
+
// Return a string used to separate paths in a list.
std::string ListSeparator();
diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc
index bc06712..12498c4 100644
--- a/src/main/cpp/blaze_util_posix.cc
+++ b/src/main/cpp/blaze_util_posix.cc
@@ -64,6 +64,8 @@
std::string ConvertPath(const std::string &path) { return path; }
+std::string ConvertPathList(const std::string& path_list) { return path_list; }
+
std::string ListSeparator() { return ":"; }
bool SymlinkDirectories(const string &target, const string &link) {
diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc
index 3e2f662..6079ebf 100644
--- a/src/main/cpp/option_processor.cc
+++ b/src/main/cpp/option_processor.cc
@@ -460,7 +460,17 @@
command_arguments_.push_back("--ignore_client_env");
} else {
for (char** env = environ; *env != NULL; env++) {
- command_arguments_.push_back("--client_env=" + string(*env));
+ string env_str(*env);
+ int pos = env_str.find("=");
+ if (pos != string::npos) {
+ string name = env_str.substr(0, pos);
+ if (name == "PATH" || name == "TMP") {
+ string value = env_str.substr(pos + 1);
+ value = ConvertPathList(value);
+ env_str = name + "=" + value;
+ }
+ }
+ command_arguments_.push_back("--client_env=" + env_str);
}
}
command_arguments_.push_back("--client_cwd=" + blaze::ConvertPath(cwd));
diff --git a/tools/cpp/cc_configure.bzl b/tools/cpp/cc_configure.bzl
index 6eb4c33..feb1583 100644
--- a/tools/cpp/cc_configure.bzl
+++ b/tools/cpp/cc_configure.bzl
@@ -49,24 +49,14 @@
result = repository_ctx.which(cmd)
return default if result == None else str(result)
-# This functions can only be used on Windows
-def _to_windows_path(repository_ctx, path):
- """Convert unix path to windows path, also works for path list."""
- result = repository_ctx.execute(["cygpath", "-w", "-p", path])
- if result.stderr:
- fail(result.stderr)
- return result.stdout.strip()
-# This functions can only be used on Windows
-# This function is a workaround since repository_ctx.which doesn't work on Windows for now.
-# TODO(pcloudy): Remove this function once the skylark implemented which function works.
-def _which_windows(repository_ctx, cmd):
- """run which command to detect a binary location and return a windows path."""
- result = repository_ctx.execute(["which", cmd])
- if result.stderr:
- fail("Cannot find " + cmd + " in PATH.\nPlease make sure "
- + cmd + " is installed.\n" + result.stderr)
- return _to_windows_path(repository_ctx, result.stdout.strip())
+def _which_cmd(repository_ctx, cmd):
+ """Find cmd in PATH using repository_ctx.which() and fail if cannot find it."""
+ result = repository_ctx.which(cmd)
+ if result == None:
+ fail("Cannot find " + cmd + " in PATH=%s.\nPlease make sure "
+ + cmd + " is installed.\n" % repository_ctx.os.environ["PATH"])
+ return str(result)
def _get_tool_paths(repository_ctx, darwin, cc):
"""Compute the path to the various tools."""
@@ -344,7 +334,7 @@
def _find_vs_path(repository_ctx):
"""Find Visual Studio install path."""
- bash_bin = _which_windows(repository_ctx, "bash.exe")
+ bash_bin = _which_cmd(repository_ctx, "bash.exe")
program_files_dir = repository_ctx.os.environ["ProgramFiles(x86)"]
if not program_files_dir:
fail("'ProgramFiles(x86)' environment variable is not set")
@@ -359,9 +349,7 @@
"@echo off\n" +
"call \"" + vsvars + "\" amd64 \n" +
"echo PATH=%PATH%,INCLUDE=%INCLUDE%,LIB=%LIB% \n", True)
- envs = repository_ctx.execute(["wrapper/get_env.bat"], 600,
- # TODO(pcloudy): This should be removed once the environment variable format is fixed
- {"PATH": _to_windows_path(repository_ctx, repository_ctx.os.environ["PATH"].strip())}).stdout.strip().split(",")
+ envs = repository_ctx.execute(["wrapper/get_env.bat"]).stdout.strip().split(",")
env_map = {}
for env in envs:
key, value = env.split("=")
@@ -409,7 +397,7 @@
for f in ["msvc_cl.py", "msvc_link.py"]:
repository_ctx.symlink(msvc_wrapper.get_child(f), "wrapper/bin/pydir/" + f)
- python_binary = _which_windows(repository_ctx, "python.exe")
+ python_binary = _which_cmd(repository_ctx, "python.exe")
_tpl(repository_ctx, "wrapper/bin/call_python.bat", {"%{python_binary}": python_binary})
vs_path = _find_vs_path(repository_ctx)
@@ -418,7 +406,7 @@
include_paths = env["INCLUDE"] + (python_dir + "include")
lib_paths = env["LIB"] + (python_dir + "libs")
_tpl(repository_ctx, "wrapper/bin/pydir/msvc_tools.py", {
- "%{tmp}": _to_windows_path(repository_ctx, repository_ctx.os.environ["TMP"]).replace("\\", "\\\\"),
+ "%{tmp}": repository_ctx.os.environ["TMP"].replace("\\", "\\\\"),
"%{path}": env["PATH"],
"%{include}": include_paths,
"%{lib}": lib_paths,