Keep the first and last snapshot of variables.
So we can compare our reconstruction of the variable state.
Test: treehugger
Change-Id: I9c1995f8969dcf95256aa7c05a01d0431e36caa2
diff --git a/core/dumpconfig.mk b/core/dumpconfig.mk
index cb7fbcb..dd3ef43 100644
--- a/core/dumpconfig.mk
+++ b/core/dumpconfig.mk
@@ -79,11 +79,19 @@
# $(2): Root nodes to import
# $(3): All variable names
# $(4): Single-value variables
-define dump-product-var-names
+# $(5): Makefile being processed
+define dump-phase-start
$(eval $(file >> $(DUMPCONFIG_FILE),phase,$(strip $(1)),$(strip $(2)))) \
$(foreach var,$(3), \
$(eval $(file >> $(DUMPCONFIG_FILE),var,$(if $(filter $(4),$(var)),single,list),$(var))) \
-)
+) \
+$(call dump-config-vals,$(strip $(5)),initial)
+endef
+
+# Args:
+# $(1): Makefile being processed
+define dump-phase-end
+$(call dump-config-vals,$(strip $(1)),final)
endef
define dump-debug
@@ -110,7 +118,7 @@
# Args:
# $(1): Makefile that was included
-# $(2): block (before,import,after)
+# $(2): block (before,import,after,initial,final)
define dump-config-vals
$(foreach var,$(filter-out $(DUMPCONFIG_SKIP_VARS),$(.KATI_SYMBOLS)),\
$(eval $(file >> $(DUMPCONFIG_FILE),val,$(call escape-for-csv,$(1)),$(2),$(call escape-for-csv,$(var)),$(call escape-for-csv,$($(var))),$(call escape-for-csv,$(KATI_variable_location $(var))))) \
diff --git a/core/node_fns.mk b/core/node_fns.mk
index 878a4dd..8d20160 100644
--- a/core/node_fns.mk
+++ b/core/node_fns.mk
@@ -254,13 +254,13 @@
# of the default list semantics
#
define import-nodes
+$(call dump-phase-start,$(1),$(2),$(3),$(4),build/make/core/node_fns.mk) \
$(if \
$(foreach _in,$(2), \
$(eval _node_import_context := _nic.$(1).[[$(_in)]]) \
$(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
should be empty here: $(_include_stack))),) \
$(eval _include_stack := ) \
- $(call dump-product-var-names,$(1),$(2),$(3),$(4)) \
$(call _import-nodes-inner,$(_node_import_context),$(_in),$(3),$(4)) \
$(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \
$(eval _node_import_context :=) \
@@ -268,5 +268,6 @@
$(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
should be empty here: $(_include_stack))),) \
) \
-,)
+,) \
+$(call dump-phase-end,build/make/core/node_fns.mk)
endef
diff --git a/tools/product_config/src/com/android/build/config/ConfigBase.java b/tools/product_config/src/com/android/build/config/ConfigBase.java
index 0c67d16..eb21219 100644
--- a/tools/product_config/src/com/android/build/config/ConfigBase.java
+++ b/tools/product_config/src/com/android/build/config/ConfigBase.java
@@ -18,6 +18,7 @@
import java.io.PrintStream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -30,6 +31,17 @@
protected List<String> mRootNodes;
/**
+ * State of the make varaible environment from before the first config file.
+ */
+ protected Map<String, Str> mInitialVariables = new HashMap();
+
+ /**
+ * State of the make varaible environment from after the first config file.
+ */
+ protected Map<String, Str> mFinalVariables = new HashMap();
+
+
+ /**
* The variables that are handled specially.
*/
protected final TreeMap<String, VarType> mProductVars = new TreeMap();
@@ -81,6 +93,20 @@
}
/**
+ * Return the state the make variable environment from before the first config file.
+ */
+ public Map<String, Str> getInitialVariables() {
+ return mInitialVariables;
+ }
+
+ /**
+ * Return the state the make variable environment from before the first config file.
+ */
+ public Map<String, Str> getFinalVariables() {
+ return mFinalVariables;
+ }
+
+ /**
* Copy common base class fields from that to this.
*/
public void copyFrom(ConfigBase that) {
@@ -89,5 +115,7 @@
for (Map.Entry<String, ConfigBase.VarType> entry: that.getProductVars().entrySet()) {
addProductVar(entry.getKey(), entry.getValue());
}
+ mInitialVariables = new HashMap(that.getInitialVariables());
+ mFinalVariables = new HashMap(that.getFinalVariables());
}
}
diff --git a/tools/product_config/src/com/android/build/config/DumpConfigParser.java b/tools/product_config/src/com/android/build/config/DumpConfigParser.java
index 94bf205..06663ca 100644
--- a/tools/product_config/src/com/android/build/config/DumpConfigParser.java
+++ b/tools/product_config/src/com/android/build/config/DumpConfigParser.java
@@ -54,10 +54,6 @@
private static final Pattern LIST_SEPARATOR = Pattern.compile("\\s+");
- public class BuildPhase {
-
- }
-
/**
* Constructor.
*/
@@ -120,6 +116,8 @@
MakeConfig makeConfig = new MakeConfig();
MakeConfig.ConfigFile configFile = new MakeConfig.ConfigFile("<ignored>");
MakeConfig.Block block = new MakeConfig.Block(MakeConfig.BlockType.UNSET);
+ Map<String, Str> initialVariables = new HashMap();
+ Map<String, Str> finalVariables = new HashMap();
// Number of "phases" we've seen so far.
for (; index < lineCount; index++) {
@@ -128,10 +126,13 @@
final String lineType = fields.get(0);
if (matchLineType(line, "phase", 2)) {
+ // Start the new one
makeConfig = new MakeConfig();
makeConfig.setPhase(fields.get(1));
makeConfig.setRootNodes(splitList(fields.get(2)));
mResults.add(makeConfig);
+ initialVariables = makeConfig.getInitialVariables();
+ finalVariables = makeConfig.getFinalVariables();
if (DEBUG) {
System.out.println("PHASE:");
@@ -216,32 +217,41 @@
}
} else if (matchLineType(line, "val", 5)) {
final String productMakefile = fields.get(1);
- final MakeConfig.BlockType blockType = parseBlockType(line, fields.get(2));
+ final String blockTypeString = fields.get(2);
final String varName = fields.get(3);
final String varValue = fields.get(4);
final Position pos = Position.parse(fields.get(5));
+ final Str str = new Str(pos, varValue);
- if (!productMakefile.equals(configFile.getFilename())) {
- mErrors.WARNING_DUMPCONFIG.add(
- new Position(mFilename, line.getLine()),
- "Mismatched 'val' product makefile."
- + " Expected: " + configFile.getFilename()
- + " Saw: " + productMakefile);
- continue;
+ if (blockTypeString.equals("initial")) {
+ initialVariables.put(varName, str);
+ } else if (blockTypeString.equals("final")) {
+ finalVariables.put(varName, str);
+ } else {
+ if (!productMakefile.equals(configFile.getFilename())) {
+ mErrors.WARNING_DUMPCONFIG.add(
+ new Position(mFilename, line.getLine()),
+ "Mismatched 'val' product makefile."
+ + " Expected: " + configFile.getFilename()
+ + " Saw: " + productMakefile);
+ continue;
+ }
+
+ final MakeConfig.BlockType blockType = parseBlockType(line, blockTypeString);
+ if (blockType == null) {
+ continue;
+ }
+ if (blockType != block.getBlockType()) {
+ mErrors.WARNING_DUMPCONFIG.add(
+ new Position(mFilename, line.getLine()),
+ "Mismatched 'val' block type."
+ + " Expected: " + block.getBlockType()
+ + " Saw: " + blockType);
+ }
+
+ // Add the variable to the block in progress
+ block.addVar(varName, str);
}
- if (blockType == null) {
- continue;
- }
- if (blockType != block.getBlockType()) {
- mErrors.WARNING_DUMPCONFIG.add(
- new Position(mFilename, line.getLine()),
- "Mismatched 'val' block type."
- + " Expected: " + block.getBlockType()
- + " Saw: " + blockType);
- }
-
- // Add the variable to the block in progress
- block.addVar(varName, new Str(pos, varValue));
} else {
if (DEBUG) {
System.out.print("# ");
diff --git a/tools/product_config/src/com/android/build/config/MakeWriter.java b/tools/product_config/src/com/android/build/config/MakeWriter.java
index 8c79c46..58dfcc0 100644
--- a/tools/product_config/src/com/android/build/config/MakeWriter.java
+++ b/tools/product_config/src/com/android/build/config/MakeWriter.java
@@ -17,7 +17,10 @@
package com.android.build.config;
import java.io.PrintStream;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
public class MakeWriter {
public static final int FLAG_WRITE_HEADER = 1;
@@ -43,6 +46,11 @@
writeFile(out, config, file);
out.println();
}
+ out.println("---------------------------------------------------------");
+ out.println("VARIABLES TOUCHED BY MAKE BASED CONFIG:");
+ out.println("---------------------------------------------------------");
+ writeStrVars(out, getModifiedVars(config.getInitialVariables(),
+ config.getFinalVariables()), config);
}
private void writeFile(PrintStream out, GenericConfig config, GenericConfig.ConfigFile file) {
@@ -100,4 +108,48 @@
}
out.println();
}
+
+ private static Map<String, Str> getModifiedVars(Map<String, Str> before,
+ Map<String, Str> after) {
+ final HashMap<String, Str> result = new HashMap();
+ // Entries that were added or changed.
+ for (Map.Entry<String, Str> afterEntry: after.entrySet()) {
+ final String varName = afterEntry.getKey();
+ final Str afterValue = afterEntry.getValue();
+ final Str beforeValue = before.get(varName);
+ if (beforeValue == null || !beforeValue.equals(afterValue)) {
+ result.put(varName, afterValue);
+ }
+ }
+ // removed Entries that were removed, we just treat them as
+ for (Map.Entry<String, Str> beforeEntry: before.entrySet()) {
+ final String varName = beforeEntry.getKey();
+ if (!after.containsKey(varName)) {
+ result.put(varName, new Str(""));
+ }
+ }
+ return result;
+ }
+
+ private static class Var {
+ Var(String name, Str val) {
+ this.name = name;
+ this.val = val;
+ }
+ final String name;
+ final Str val;
+ }
+
+ private static void writeStrVars(PrintStream out, Map<String, Str> vars, ConfigBase config) {
+ // Sort by file name and var name
+ TreeMap<String, Var> sorted = new TreeMap();
+ for (Map.Entry<String, Str> entry: vars.entrySet()) {
+ sorted.put(entry.getValue().getPosition().toString() + " " + entry.getKey(),
+ new Var(entry.getKey(), entry.getValue()));
+ }
+ // Print it
+ for (Var var: sorted.values()) {
+ out.println(var.val.getPosition() + var.name + " := " + var.val);
+ }
+ }
}