Move the --define command line option from CppConfiguration to BuildConfiguration.
It makes much more sense there because it does *not* specify C++ #defines but BUILD variables. Also rename the getter method to make that clearer.
This allows us to remove BuildConfiguration.Fragment#getCommandLineDefines().
--
MOS_MIGRATED_REVID=129080014
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java
index 5629c83a..21fbab7 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java
@@ -18,7 +18,6 @@
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.syntax.SkylarkDict;
-
import java.util.LinkedHashMap;
import java.util.Map;
@@ -35,7 +34,7 @@
public ConfigurationMakeVariableContext(Package pkg, BuildConfiguration configuration) {
this.pkg = pkg;
- commandLineEnv = configuration.getCommandLineDefines();
+ commandLineEnv = configuration.getCommandLineBuildVariables();
globalEnv = configuration.getGlobalMakeEnvironment();
platform = configuration.getPlatformName();
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index c7a068b..277552a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -68,7 +68,6 @@
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.TriState;
-
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -85,7 +84,6 @@
import java.util.Queue;
import java.util.Set;
import java.util.TreeMap;
-
import javax.annotation.Nullable;
/**
@@ -165,13 +163,6 @@
return implicitLabels;
}
- /*
- * Returns the command-line "Make" variable overrides.
- */
- public ImmutableMap<String, String> getCommandLineDefines() {
- return ImmutableMap.of();
- }
-
/**
* Returns a fragment of the output directory name for this configuration. The output
* directory for the whole configuration contains all the short names by all fragments.
@@ -451,6 +442,16 @@
return cpu;
}
+ @Option(
+ name = "define",
+ converter = Converters.AssignmentConverter.class,
+ defaultValue = "",
+ category = "semantics",
+ allowMultiple = true,
+ help = "Each --define option specifies an assignment for a build variable."
+ )
+ public List<Map.Entry<String, String>> commandLineBuildVariables;
+
@Option(name = "cpu",
defaultValue = "null",
category = "semantics",
@@ -862,6 +863,7 @@
host.compilationMode = CompilationMode.OPT;
host.isHost = true;
host.useDynamicConfigurations = useDynamicConfigurations;
+ host.commandLineBuildVariables = commandLineBuildVariables;
host.enforceConstraints = enforceConstraints;
if (fallback) {
@@ -1041,6 +1043,7 @@
private final String platformName;
private final ImmutableMap<String, String> testEnvironment;
+ private final ImmutableMap<String, String> commandLineBuildVariables;
/**
* Helper container for {@link #transitiveOptionsMap} below.
@@ -1203,6 +1206,15 @@
this.testEnvironment = ImmutableMap.copyOf(testEnv);
+ // We can't use an ImmutableMap.Builder here; we need the ability to add entries with keys that
+ // are already in the map so that the same define can be specified on the command line twice,
+ // and ImmutableMap.Builder does not support that.
+ Map<String, String> commandLineDefinesBuilder = new TreeMap<>();
+ for (Map.Entry<String, String> define : options.commandLineBuildVariables) {
+ commandLineDefinesBuilder.put(define.getKey(), define.getValue());
+ }
+ commandLineBuildVariables = ImmutableMap.copyOf(commandLineDefinesBuilder);
+
this.mnemonic = buildMnemonic();
String outputDirName = (options.outputDirectoryName != null)
? options.outputDirectoryName : mnemonic;
@@ -2057,9 +2069,7 @@
public Map<String, String> getMakeEnvironment() {
Map<String, String> makeEnvironment = new HashMap<>();
makeEnvironment.putAll(globalMakeEnv);
- for (Fragment fragment : fragments.values()) {
- makeEnvironment.putAll(fragment.getCommandLineDefines());
- }
+ makeEnvironment.putAll(commandLineBuildVariables);
return ImmutableMap.copyOf(makeEnvironment);
}
@@ -2068,12 +2078,8 @@
* (Fragments, in particular the Google C++ support, can set variables through the
* command line.)
*/
- public Map<String, String> getCommandLineDefines() {
- ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
- for (Fragment fragment : fragments.values()) {
- builder.putAll(fragment.getCommandLineDefines());
- }
- return builder.build();
+ public Map<String, String> getCommandLineBuildVariables() {
+ return commandLineBuildVariables;
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index 1e14df9..a02c7a9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -331,7 +331,6 @@
// The dynamic mode for linking.
private final DynamicMode dynamicMode;
private final boolean stripBinaries;
- private final ImmutableMap<String, String> commandLineDefines;
private final String solibDirectory;
private final CompilationMode compilationMode;
@@ -457,15 +456,6 @@
}
}
- // We can't use an ImmutableMap.Builder here; we need the ability (at least
- // in tests) to add entries with keys that are already in the map, and only
- // HashMap supports this (by replacing the existing entry under the key).
- Map<String, String> commandLineDefinesBuilder = new HashMap<>();
- for (Map.Entry<String, String> define : cppOptions.commandLineDefinedVariables) {
- commandLineDefinesBuilder.put(define.getKey(), define.getValue());
- }
- commandLineDefines = ImmutableMap.copyOf(commandLineDefinesBuilder);
-
ListMultimap<CompilationMode, String> cFlags = ArrayListMultimap.create();
ListMultimap<CompilationMode, String> cxxFlags = ArrayListMultimap.create();
linkOptionsFromCompilationMode = ArrayListMultimap.create();
@@ -1576,22 +1566,6 @@
return cppOptions.stl;
}
- /*
- * Returns the command-line "Make" variable overrides.
- */
- @Override
- public ImmutableMap<String, String> getCommandLineDefines() {
- return commandLineDefines;
- }
-
- /**
- * Returns the command-line override value for the specified "Make" variable
- * for this configuration, or null if none.
- */
- public String getMakeVariableOverride(String var) {
- return commandLineDefines.get(var);
- }
-
/**
* Returns the currently active LIPO compilation mode.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
index 2195e3f..47cd385 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
@@ -31,11 +31,9 @@
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode;
import com.google.devtools.common.options.Converter;
-import com.google.devtools.common.options.Converters;
import com.google.devtools.common.options.EnumConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsParsingException;
-
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -497,16 +495,6 @@
public List<String> hostCoptList;
@Option(
- name = "define",
- converter = Converters.AssignmentConverter.class,
- defaultValue = "",
- category = "semantics",
- allowMultiple = true,
- help = "Each --define option specifies an assignment for a build variable."
- )
- public List<Map.Entry<String, String>> commandLineDefinedVariables;
-
- @Option(
name = "grte_top",
defaultValue = "null", // The default value is chosen by the toolchain.
category = "version",
@@ -572,8 +560,6 @@
public FragmentOptions getHost(boolean fallback) {
CppOptions host = (CppOptions) getDefault();
- host.commandLineDefinedVariables = commandLineDefinedVariables;
-
// The crosstool options are partially copied from the target configuration.
if (!fallback) {
if (hostCrosstoolTop == null) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java
index 873b6c4..fc60ff6 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java
@@ -30,14 +30,12 @@
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.rules.objc.J2ObjcConfiguration;
import com.google.devtools.common.options.Options;
-
+import java.util.Map;
+import java.util.regex.Pattern;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.util.Map;
-import java.util.regex.Pattern;
-
/**
* Tests for {@link BuildConfiguration}.
*/
@@ -334,4 +332,46 @@
assertThat(config1.getFragment(J2ObjcConfiguration.class))
.isNotSameAs(config3.getFragment(J2ObjcConfiguration.class));
}
+
+ @Test
+ public void testCommandLineVariables() throws Exception {
+ BuildConfiguration config = create(
+ "--define", "a=b/c:d", "--define", "b=FOO", "--define", "DEFUN=Nope");
+ assertThat(config.getCommandLineBuildVariables().get("a")).isEqualTo("b/c:d");
+ assertThat(config.getCommandLineBuildVariables().get("b")).isEqualTo("FOO");
+ assertThat(config.getCommandLineBuildVariables().get("DEFUN")).isEqualTo("Nope");
+ }
+
+ // Regression test for bug #2518997:
+ // "--define in blazerc overrides --define from command line"
+ @Test
+ public void testCommandLineVariablesOverride() throws Exception {
+ BuildConfiguration config = create("--define", "a=b", "--define", "a=c");
+ assertThat(config.getCommandLineBuildVariables().get("a")).isEqualTo("c");
+ }
+
+ // This is really a test of option parsing, not command-line variable
+ // semantics.
+ @Test
+ public void testCommandLineVariablesWithFunnyCharacters() throws Exception {
+ BuildConfiguration config = create(
+ "--define", "foo=#foo",
+ "--define", "comma=a,b",
+ "--define", "space=foo bar",
+ "--define", "thing=a \"quoted\" thing",
+ "--define", "qspace=a\\ quoted\\ space",
+ "--define", "#a=pounda");
+ assertThat(config.getCommandLineBuildVariables().get("foo")).isEqualTo("#foo");
+ assertThat(config.getCommandLineBuildVariables().get("comma")).isEqualTo("a,b");
+ assertThat(config.getCommandLineBuildVariables().get("space")).isEqualTo("foo bar");
+ assertThat(config.getCommandLineBuildVariables().get("thing")).isEqualTo("a \"quoted\" thing");
+ assertThat(config.getCommandLineBuildVariables().get("qspace")).isEqualTo("a\\ quoted\\ space");
+ assertThat(config.getCommandLineBuildVariables().get("#a")).isEqualTo("pounda");
+ }
+
+ @Test
+ public void testHostDefine() throws Exception {
+ BuildConfiguration cfg = createHost("--define=foo=bar");
+ assertThat(cfg.getCommandLineBuildVariables().get("foo")).isEqualTo("bar");
+ }
}