Add support for "far dependencies"

AddVariationDependencies is used to add dependency modules that
have the same variations as the depending module, but with additional
variataions.  It cannot be used to add a dependency that is unrelated
to the depending module, for example a dependency on a code generator
that needs to run on the host to generate a target source file.

Add AddFarVariationDependencies, which adds a dependency on a module
that contains all the passed variations, but ignores the variations
of the depending module, as well as any unspecified variations on
the dependency module.

Change-Id: Ief696ec85cf33ad5fb187227d215c1c2e894f962
diff --git a/context.go b/context.go
index ff3a6ce..d044947 100644
--- a/context.go
+++ b/context.go
@@ -174,6 +174,17 @@
 	return newVm
 }
 
+// Compare this variationMap to another one.  Returns true if the every entry in this map
+// is either the same in the other map or doesn't exist in the other map.
+func (vm variationMap) subset(other variationMap) bool {
+	for k, v1 := range vm {
+		if v2, ok := other[k]; ok && v1 != v2 {
+			return false
+		}
+	}
+	return true
+}
+
 func (vm variationMap) equal(other variationMap) bool {
 	return reflect.DeepEqual(vm, other)
 }
@@ -1027,7 +1038,7 @@
 }
 
 func (c *Context) addVariationDependency(module *moduleInfo, variations []Variation,
-	depName string) []error {
+	depName string, far bool) []error {
 
 	depsPos := module.propertyPos["deps"]
 
@@ -1043,13 +1054,24 @@
 	// We can't just append variant.Variant to module.dependencyVariants.variantName and
 	// compare the strings because the result won't be in mutator registration order.
 	// Create a new map instead, and then deep compare the maps.
-	newVariant := module.dependencyVariant.clone()
+	var newVariant variationMap
+	if !far {
+		newVariant = module.dependencyVariant.clone()
+	} else {
+		newVariant = make(variationMap)
+	}
 	for _, v := range variations {
 		newVariant[v.Mutator] = v.Variation
 	}
 
 	for _, m := range depInfo.modules {
-		if newVariant.equal(m.variant) {
+		var found bool
+		if far {
+			found = m.variant.subset(newVariant)
+		} else {
+			found = m.variant.equal(newVariant)
+		}
+		if found {
 			// AddVariationDependency allows adding a dependency on itself, but only if
 			// that module is earlier in the module list than this one, since we always
 			// run GenerateBuildActions in order for the variants of a module
diff --git a/module_ctx.go b/module_ctx.go
index 9182c2d..1cdb51c 100644
--- a/module_ctx.go
+++ b/module_ctx.go
@@ -120,6 +120,7 @@
 	BaseModuleContext
 
 	AddVariationDependencies([]Variation, ...string)
+	AddFarVariationDependencies([]Variation, ...string)
 }
 
 type ModuleContext interface {
@@ -327,7 +328,25 @@
 	deps ...string) {
 
 	for _, dep := range deps {
-		errs := mctx.context.addVariationDependency(mctx.module, variations, dep)
+		errs := mctx.context.addVariationDependency(mctx.module, variations, dep, false)
+		if len(errs) > 0 {
+			mctx.errs = append(mctx.errs, errs...)
+		}
+	}
+}
+
+// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
+// variations argument to select which variant of the dependency to use.  A variant of the
+// dependency must exist that matches the variations argument, but may also have other variations.
+// For any unspecified variation the first variant will be used.
+//
+// Unlike AddVariationDependencies, the variations of the current module are ignored - the
+// depdendency only needs to match the supplied variations.
+func (mctx *dynamicDependerModuleContext) AddFarVariationDependencies(variations []Variation,
+	deps ...string) {
+
+	for _, dep := range deps {
+		errs := mctx.context.addVariationDependency(mctx.module, variations, dep, true)
 		if len(errs) > 0 {
 			mctx.errs = append(mctx.errs, errs...)
 		}