Optionally allow Bazel to pass JVM options containing spaces directly through to the JVM instead of (almost certainly incorrectly) splitting the options along spaces.
This allows us to pass non-quote-delimited strings to the JVM, which is necessary for things like -XX:OnOutOfMemoryError="kill -3 %p" (normally bash strips those quotes, but they're not stripped when passed via --host_jvm_args).
--
MOS_MIGRATED_REVID=107820087
diff --git a/site/docs/bazel-user-manual.html b/site/docs/bazel-user-manual.html
index 1460d8a..9eb7d00 100644
--- a/site/docs/bazel-user-manual.html
+++ b/site/docs/bazel-user-manual.html
@@ -3282,16 +3282,17 @@
<h4 id='flag--host_jvm_args'><code class='flag'>--host_jvm_args=<var>string</var></code></h4>
<p>
- Specifies a space-separated list of startup options to be passed to
- the Java virtual machine in which <i>Bazel itself</i> runs. This
- can be used to set the stack size, for example:
+ Specifies a startup option to be passed to the Java virtual machine in which <i>Bazel itself</i>
+ runs. This can be used to set the stack size, for example:
</p>
<pre>
% bazel --host_jvm_args="-Xss256K" build //foo
</pre>
<p>
This option can be used multiple times with individual arguments. Note that
- setting this flag should rarely be needed.
+ setting this flag should rarely be needed. You can also pass a space-separated list of strings,
+ each of which will be interpreted as a separate JVM argument, but this feature will soon be
+ deprecated.
</p>
<p>
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index 911bd3d..ae8af0d 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -261,8 +261,25 @@
vector<string> user_options;
- blaze_util::SplitQuotedStringUsing(globals->options.host_jvm_args, ' ',
- &user_options);
+ if (globals->options.preserve_spaces_in_host_jvm_args) {
+ user_options.insert(user_options.begin(),
+ globals->options.host_jvm_args.begin(),
+ globals->options.host_jvm_args.end());
+ } else {
+ for (const auto &arg : globals->options.host_jvm_args) {
+ // int num_segments =
+ blaze_util::SplitQuotedStringUsing(arg, ' ', &user_options);
+ // TODO(janakr): Enable this warning when users have been migrated.
+ // if (num_segments > 1) {
+ // fprintf(stderr, "WARNING: You are passing multiple jvm options"
+ // " under a single --host_jvm_args option: %s. This will stop
+ // working "
+ // "soon. Instead, pass each option under its own
+ // --host_jvm_args "
+ // "option.\n", arg);
+ //
+ }
+ }
// Add JVM arguments particular to building blaze64 and particular JVM
// versions.
@@ -350,8 +367,13 @@
if (!globals->options.host_jvm_profile.empty()) {
result.push_back("--host_jvm_profile=" + globals->options.host_jvm_profile);
}
+ if (globals->options.preserve_spaces_in_host_jvm_args) {
+ result.push_back("--experimental_preserve_spaces_in_host_jvm_args");
+ }
if (!globals->options.host_jvm_args.empty()) {
- result.push_back("--host_jvm_args=" + globals->options.host_jvm_args);
+ for (const auto &arg : globals->options.host_jvm_args) {
+ result.push_back("--host_jvm_args=" + arg);
+ }
}
if (globals->options.invocation_policy != NULL &&
diff --git a/src/main/cpp/blaze_startup_options.h b/src/main/cpp/blaze_startup_options.h
index f29ab3f..e61af4b 100644
--- a/src/main/cpp/blaze_startup_options.h
+++ b/src/main/cpp/blaze_startup_options.h
@@ -126,7 +126,9 @@
string host_jvm_profile;
- string host_jvm_args;
+ bool preserve_spaces_in_host_jvm_args;
+
+ std::vector<string> host_jvm_args;
bool batch;
diff --git a/src/main/cpp/blaze_startup_options_common.cc b/src/main/cpp/blaze_startup_options_common.cc
index 914f7ab..8a5f6f1 100644
--- a/src/main/cpp/blaze_startup_options_common.cc
+++ b/src/main/cpp/blaze_startup_options_common.cc
@@ -41,6 +41,8 @@
block_for_lock = true;
host_jvm_debug = false;
host_javabase = "";
+ // TODO(janakr): change this to true when ready, then delete it.
+ preserve_spaces_in_host_jvm_args = false;
batch = false;
batch_cpu_scheduling = false;
blaze_cpu = false;
@@ -73,6 +75,7 @@
lhs->host_jvm_debug = rhs.host_jvm_debug;
lhs->host_jvm_profile = rhs.host_jvm_profile;
lhs->host_javabase = rhs.host_javabase;
+ lhs->preserve_spaces_in_host_jvm_args = rhs.preserve_spaces_in_host_jvm_args;
lhs->host_jvm_args = rhs.host_jvm_args;
lhs->batch = rhs.batch;
lhs->batch_cpu_scheduling = rhs.batch_cpu_scheduling;
@@ -126,13 +129,13 @@
// and re-execing.
host_javabase = MakeAbsolute(value);
option_sources["host_javabase"] = rcfile;
+ } else if (GetNullaryOption(
+ arg, "--experimental_preserve_spaces_in_host_jvm_args")) {
+ preserve_spaces_in_host_jvm_args = true;
+ option_sources["preserve_spaces_in_host_jvm_args"] = rcfile;
} else if ((value = GetUnaryOption(arg, next_arg,
"--host_jvm_args")) != NULL) {
- if (host_jvm_args.empty()) {
- host_jvm_args = value;
- } else {
- host_jvm_args = host_jvm_args + " " + value;
- }
+ host_jvm_args.push_back(value);
option_sources["host_jvm_args"] = rcfile; // NB: This is incorrect
} else if ((value = GetUnaryOption(arg, next_arg, "--blaze_cpu")) != NULL) {
blaze_cpu = true;
diff --git a/src/main/cpp/util/strings.cc b/src/main/cpp/util/strings.cc
index 214f887..3df0b9e 100644
--- a/src/main/cpp/util/strings.cc
+++ b/src/main/cpp/util/strings.cc
@@ -128,11 +128,12 @@
}
}
-void SplitQuotedStringUsing(const string &contents, const char delimeter,
- std::vector<string> *output) {
+size_t SplitQuotedStringUsing(const string &contents, const char delimeter,
+ std::vector<string> *output) {
size_t len = contents.length();
size_t start = 0;
size_t quote = string::npos; // quote position
+ size_t num_segments = 0;
for (size_t pos = 0; pos < len; ++pos) {
if (start == pos && contents[start] == delimeter) {
@@ -147,13 +148,16 @@
} else if (quote == string::npos && contents[pos] == delimeter) {
output->push_back(string(contents, start, pos - start));
start = pos + 1;
+ num_segments++;
}
}
// A trailing element
if (start < len) {
output->push_back(string(contents, start));
+ num_segments++;
}
+ return num_segments;
}
void Replace(const string &oldsub, const string &newsub, string *str) {
diff --git a/src/main/cpp/util/strings.h b/src/main/cpp/util/strings.h
index 18d53b1..0dca219 100644
--- a/src/main/cpp/util/strings.h
+++ b/src/main/cpp/util/strings.h
@@ -80,9 +80,9 @@
void SplitStringUsing(
const string &contents, const char delimeter, std::vector<string> *output);
-// Same as above, but adds results to output.
-void SplitQuotedStringUsing(const string &contents, const char delimeter,
- std::vector<string> *output);
+// Same as above, but adds results to output. Returns number of elements added.
+size_t SplitQuotedStringUsing(const string &contents, const char delimeter,
+ std::vector<string> *output);
// Global replace of oldsub with newsub.
void Replace(const string &oldsub, const string &newsub, string *str);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
index 69d69da..2621a53 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
@@ -213,6 +213,16 @@
help = "Unused.")
public String unusedSkyframe;
+ @Option(
+ name = "experimental_preserve_spaces_in_host_jvm_args",
+ defaultValue = "false",
+ category = "undocumented",
+ help =
+ "If this option is true, each argument to --host_jvm_args is considered a single JVM "
+ + "flag, even if it has spaces in it."
+ )
+ public boolean unusedPreserveSpacesInHostJvmArgs;
+
@Option(name = "fatal_event_bus_exceptions",
defaultValue = "false", // NOTE: purely decorative!
category = "undocumented",