| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 1 | // Copyright (C) 2024 The Android Open Source Project | 
 | 2 | // | 
 | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 4 | // you may not use this file except in compliance with the License. | 
 | 5 | // You may obtain a copy of the License at | 
 | 6 | // | 
 | 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 8 | // | 
 | 9 | // Unless required by applicable law or agreed to in writing, software | 
 | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 12 | // See the License for the specific language governing permissions and | 
 | 13 | // limitations under the License. | 
 | 14 |  | 
 | 15 | package fsgen | 
 | 16 |  | 
 | 17 | import ( | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 18 | 	"fmt" | 
 | 19 | 	"slices" | 
 | 20 | 	"sync" | 
 | 21 |  | 
| mrziwang | e5b1bb3 | 2024-11-05 15:51:40 -0800 | [diff] [blame] | 22 | 	"android/soong/android" | 
 | 23 |  | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 24 | 	"github.com/google/blueprint/proptools" | 
 | 25 | ) | 
 | 26 |  | 
 | 27 | func RegisterCollectFileSystemDepsMutators(ctx android.RegisterMutatorsContext) { | 
 | 28 | 	ctx.BottomUp("fs_collect_deps", collectDepsMutator).MutatesGlobalState() | 
 | 29 | 	ctx.BottomUp("fs_set_deps", setDepsMutator) | 
 | 30 | } | 
 | 31 |  | 
 | 32 | var fsGenStateOnceKey = android.NewOnceKey("FsGenState") | 
 | 33 | var fsGenRemoveOverridesOnceKey = android.NewOnceKey("FsGenRemoveOverrides") | 
 | 34 |  | 
 | 35 | // Map of partition module name to its partition that may be generated by Soong. | 
 | 36 | // Note that it is not guaranteed that all modules returned by this function are successfully | 
 | 37 | // created. | 
 | 38 | func getAllSoongGeneratedPartitionNames(config android.Config, partitions []string) map[string]string { | 
 | 39 | 	ret := map[string]string{} | 
 | 40 | 	for _, partition := range partitions { | 
 | 41 | 		ret[generatedModuleNameForPartition(config, partition)] = partition | 
 | 42 | 	} | 
 | 43 | 	return ret | 
 | 44 | } | 
 | 45 |  | 
 | 46 | type depCandidateProps struct { | 
 | 47 | 	Namespace string | 
 | 48 | 	Multilib  string | 
 | 49 | 	Arch      []android.ArchType | 
 | 50 | } | 
 | 51 |  | 
 | 52 | // Map of module name to depCandidateProps | 
 | 53 | type multilibDeps map[string]*depCandidateProps | 
 | 54 |  | 
 | 55 | // Information necessary to generate the filesystem modules, including details about their | 
 | 56 | // dependencies | 
 | 57 | type FsGenState struct { | 
 | 58 | 	// List of modules in `PRODUCT_PACKAGES` and `PRODUCT_PACKAGES_DEBUG` | 
 | 59 | 	depCandidates []string | 
 | 60 | 	// Map of names of partition to the information of modules to be added as deps | 
 | 61 | 	fsDeps map[string]*multilibDeps | 
 | 62 | 	// List of name of partitions to be generated by the filesystem_creator module | 
 | 63 | 	soongGeneratedPartitions []string | 
 | 64 | 	// Mutex to protect the fsDeps | 
 | 65 | 	fsDepsMutex sync.Mutex | 
 | 66 | 	// Map of _all_ soong module names to their corresponding installation properties | 
 | 67 | 	moduleToInstallationProps map[string]installationProperties | 
 | 68 | } | 
 | 69 |  | 
 | 70 | type installationProperties struct { | 
 | 71 | 	Required  []string | 
 | 72 | 	Overrides []string | 
 | 73 | } | 
 | 74 |  | 
 | 75 | func defaultDepCandidateProps(config android.Config) *depCandidateProps { | 
 | 76 | 	return &depCandidateProps{ | 
 | 77 | 		Namespace: ".", | 
 | 78 | 		Arch:      []android.ArchType{config.BuildArch}, | 
 | 79 | 	} | 
 | 80 | } | 
 | 81 |  | 
 | 82 | func generatedPartitions(ctx android.LoadHookContext) []string { | 
 | 83 | 	generatedPartitions := []string{"system"} | 
 | 84 | 	if ctx.DeviceConfig().SystemExtPath() == "system_ext" { | 
 | 85 | 		generatedPartitions = append(generatedPartitions, "system_ext") | 
 | 86 | 	} | 
 | 87 | 	if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" { | 
 | 88 | 		generatedPartitions = append(generatedPartitions, "vendor") | 
 | 89 | 	} | 
 | 90 | 	if ctx.DeviceConfig().BuildingProductImage() && ctx.DeviceConfig().ProductPath() == "product" { | 
 | 91 | 		generatedPartitions = append(generatedPartitions, "product") | 
 | 92 | 	} | 
 | 93 | 	if ctx.DeviceConfig().BuildingOdmImage() && ctx.DeviceConfig().OdmPath() == "odm" { | 
 | 94 | 		generatedPartitions = append(generatedPartitions, "odm") | 
 | 95 | 	} | 
| mrziwang | 23ba876 | 2024-11-07 16:21:53 -0800 | [diff] [blame] | 96 | 	if ctx.DeviceConfig().BuildingUserdataImage() && ctx.DeviceConfig().UserdataPath() == "data" { | 
 | 97 | 		generatedPartitions = append(generatedPartitions, "userdata") | 
 | 98 | 	} | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 99 | 	if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingSystemDlkmImage { | 
 | 100 | 		generatedPartitions = append(generatedPartitions, "system_dlkm") | 
 | 101 | 	} | 
 | 102 | 	return generatedPartitions | 
 | 103 | } | 
 | 104 |  | 
 | 105 | func createFsGenState(ctx android.LoadHookContext, generatedPrebuiltEtcModuleNames []string) *FsGenState { | 
 | 106 | 	return ctx.Config().Once(fsGenStateOnceKey, func() interface{} { | 
 | 107 | 		partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse | 
 | 108 | 		candidates := android.FirstUniqueStrings(android.Concat(partitionVars.ProductPackages, partitionVars.ProductPackagesDebug)) | 
 | 109 | 		candidates = android.Concat(candidates, generatedPrebuiltEtcModuleNames) | 
 | 110 |  | 
 | 111 | 		return &FsGenState{ | 
 | 112 | 			depCandidates: candidates, | 
 | 113 | 			fsDeps: map[string]*multilibDeps{ | 
 | 114 | 				// These additional deps are added according to the cuttlefish system image bp. | 
 | 115 | 				"system": { | 
 | 116 | 					"com.android.apex.cts.shim.v1_prebuilt":     defaultDepCandidateProps(ctx.Config()), | 
 | 117 | 					"dex_bootjars":                              defaultDepCandidateProps(ctx.Config()), | 
 | 118 | 					"framework_compatibility_matrix.device.xml": defaultDepCandidateProps(ctx.Config()), | 
 | 119 | 					"init.environ.rc-soong":                     defaultDepCandidateProps(ctx.Config()), | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 120 | 					"libcompiler_rt":                            defaultDepCandidateProps(ctx.Config()), | 
 | 121 | 					"libdmabufheap":                             defaultDepCandidateProps(ctx.Config()), | 
 | 122 | 					"libgsi":                                    defaultDepCandidateProps(ctx.Config()), | 
 | 123 | 					"llndk.libraries.txt":                       defaultDepCandidateProps(ctx.Config()), | 
 | 124 | 					"logpersist.start":                          defaultDepCandidateProps(ctx.Config()), | 
 | 125 | 					"update_engine_sideload":                    defaultDepCandidateProps(ctx.Config()), | 
 | 126 | 				}, | 
 | 127 | 				"vendor": { | 
 | 128 | 					"fs_config_files_vendor":                               defaultDepCandidateProps(ctx.Config()), | 
 | 129 | 					"fs_config_dirs_vendor":                                defaultDepCandidateProps(ctx.Config()), | 
 | 130 | 					generatedModuleName(ctx.Config(), "vendor-build.prop"): defaultDepCandidateProps(ctx.Config()), | 
 | 131 | 				}, | 
 | 132 | 				"odm": { | 
 | 133 | 					// fs_config_* files are automatically installed for all products with odm partitions. | 
 | 134 | 					// https://cs.android.com/android/_/android/platform/build/+/e4849e87ab660b59a6501b3928693db065ee873b:tools/fs_config/Android.mk;l=34;drc=8d6481b92c4b4e9b9f31a61545b6862090fcc14b;bpv=1;bpt=0 | 
 | 135 | 					"fs_config_files_odm": defaultDepCandidateProps(ctx.Config()), | 
 | 136 | 					"fs_config_dirs_odm":  defaultDepCandidateProps(ctx.Config()), | 
 | 137 | 				}, | 
 | 138 | 				"product": {}, | 
 | 139 | 				"system_ext": { | 
 | 140 | 					// VNDK apexes are automatically included. | 
 | 141 | 					// This hardcoded list will need to be updated if `PRODUCT_EXTRA_VNDK_VERSIONS` is updated. | 
 | 142 | 					// https://cs.android.com/android/_/android/platform/build/+/adba533072b00c53ac0f198c550a3cbd7a00e4cd:core/main.mk;l=984;bpv=1;bpt=0;drc=174db7b179592cf07cbfd2adb0119486fda911e7 | 
 | 143 | 					"com.android.vndk.v30": defaultDepCandidateProps(ctx.Config()), | 
 | 144 | 					"com.android.vndk.v31": defaultDepCandidateProps(ctx.Config()), | 
 | 145 | 					"com.android.vndk.v32": defaultDepCandidateProps(ctx.Config()), | 
 | 146 | 					"com.android.vndk.v33": defaultDepCandidateProps(ctx.Config()), | 
 | 147 | 					"com.android.vndk.v34": defaultDepCandidateProps(ctx.Config()), | 
 | 148 | 				}, | 
| Spandan Das | 912d26b | 2024-11-06 19:35:17 +0000 | [diff] [blame] | 149 | 				"userdata": {}, | 
 | 150 | 				"system_dlkm": { | 
 | 151 | 					// these are phony required deps of the phony fs_config_dirs_nonsystem | 
 | 152 | 					"fs_config_dirs_system_dlkm":  defaultDepCandidateProps(ctx.Config()), | 
 | 153 | 					"fs_config_files_system_dlkm": defaultDepCandidateProps(ctx.Config()), | 
 | 154 | 					// build props are automatically added to `ALL_DEFAULT_INSTALLED_MODULES` | 
 | 155 | 					"system_dlkm-build.prop": defaultDepCandidateProps(ctx.Config()), | 
 | 156 | 				}, | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 157 | 			}, | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 158 | 			fsDepsMutex:               sync.Mutex{}, | 
 | 159 | 			moduleToInstallationProps: map[string]installationProperties{}, | 
 | 160 | 		} | 
 | 161 | 	}).(*FsGenState) | 
 | 162 | } | 
 | 163 |  | 
 | 164 | func checkDepModuleInMultipleNamespaces(mctx android.BottomUpMutatorContext, foundDeps multilibDeps, module string, partitionName string) { | 
 | 165 | 	otherNamespace := mctx.Namespace().Path | 
 | 166 | 	if val, found := foundDeps[module]; found && otherNamespace != "." && !android.InList(val.Namespace, []string{".", otherNamespace}) { | 
 | 167 | 		mctx.ModuleErrorf("found in multiple namespaces(%s and %s) when including in %s partition", val.Namespace, otherNamespace, partitionName) | 
 | 168 | 	} | 
 | 169 | } | 
 | 170 |  | 
 | 171 | func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string) { | 
| Jihoon Kang | 81aeb9e | 2024-11-05 00:22:35 +0000 | [diff] [blame] | 172 | 	moduleName := mctx.ModuleName() | 
 | 173 | 	checkDepModuleInMultipleNamespaces(mctx, *deps, moduleName, installPartition) | 
 | 174 | 	if _, ok := (*deps)[moduleName]; ok { | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 175 | 		// Prefer the namespace-specific module over the platform module | 
 | 176 | 		if mctx.Namespace().Path != "." { | 
| Jihoon Kang | 81aeb9e | 2024-11-05 00:22:35 +0000 | [diff] [blame] | 177 | 			(*deps)[moduleName].Namespace = mctx.Namespace().Path | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 178 | 		} | 
| Jihoon Kang | 81aeb9e | 2024-11-05 00:22:35 +0000 | [diff] [blame] | 179 | 		(*deps)[moduleName].Arch = append((*deps)[moduleName].Arch, mctx.Module().Target().Arch.ArchType) | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 180 | 	} else { | 
 | 181 | 		multilib, _ := mctx.Module().DecodeMultilib(mctx) | 
| Jihoon Kang | 81aeb9e | 2024-11-05 00:22:35 +0000 | [diff] [blame] | 182 | 		(*deps)[moduleName] = &depCandidateProps{ | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 183 | 			Namespace: mctx.Namespace().Path, | 
 | 184 | 			Multilib:  multilib, | 
 | 185 | 			Arch:      []android.ArchType{mctx.Module().Target().Arch.ArchType}, | 
 | 186 | 		} | 
 | 187 | 	} | 
 | 188 | } | 
 | 189 |  | 
 | 190 | func collectDepsMutator(mctx android.BottomUpMutatorContext) { | 
 | 191 | 	fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) | 
 | 192 |  | 
 | 193 | 	m := mctx.Module() | 
| Jihoon Kang | 81aeb9e | 2024-11-05 00:22:35 +0000 | [diff] [blame] | 194 | 	if m.Target().Os.Class == android.Device && slices.Contains(fsGenState.depCandidates, mctx.ModuleName()) { | 
| Jihoon Kang | add2bb2 | 2024-11-05 22:29:34 +0000 | [diff] [blame] | 195 | 		installPartition := m.PartitionTag(mctx.DeviceConfig()) | 
 | 196 | 		fsGenState.fsDepsMutex.Lock() | 
 | 197 | 		// Only add the module as dependency when: | 
 | 198 | 		// - its enabled | 
 | 199 | 		// - its namespace is included in PRODUCT_SOONG_NAMESPACES | 
 | 200 | 		if m.Enabled(mctx) && m.ExportedToMake() { | 
 | 201 | 			appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition) | 
 | 202 | 		} | 
 | 203 | 		fsGenState.fsDepsMutex.Unlock() | 
 | 204 | 	} | 
 | 205 | 	// store the map of module to (required,overrides) even if the module is not in PRODUCT_PACKAGES. | 
 | 206 | 	// the module might be installed transitively. | 
 | 207 | 	if m.Target().Os.Class == android.Device && m.Enabled(mctx) && m.ExportedToMake() { | 
 | 208 | 		fsGenState.fsDepsMutex.Lock() | 
 | 209 | 		fsGenState.moduleToInstallationProps[m.Name()] = installationProperties{ | 
 | 210 | 			Required:  m.RequiredModuleNames(mctx), | 
 | 211 | 			Overrides: m.Overrides(), | 
 | 212 | 		} | 
 | 213 | 		fsGenState.fsDepsMutex.Unlock() | 
 | 214 | 	} | 
 | 215 | } | 
 | 216 |  | 
 | 217 | type depsStruct struct { | 
 | 218 | 	Deps []string | 
 | 219 | } | 
 | 220 |  | 
 | 221 | type multilibDepsStruct struct { | 
 | 222 | 	Common   depsStruct | 
 | 223 | 	Lib32    depsStruct | 
 | 224 | 	Lib64    depsStruct | 
 | 225 | 	Both     depsStruct | 
 | 226 | 	Prefer32 depsStruct | 
 | 227 | } | 
 | 228 |  | 
 | 229 | type packagingPropsStruct struct { | 
 | 230 | 	High_priority_deps []string | 
 | 231 | 	Deps               []string | 
 | 232 | 	Multilib           multilibDepsStruct | 
 | 233 | } | 
 | 234 |  | 
 | 235 | func fullyQualifiedModuleName(moduleName, namespace string) string { | 
 | 236 | 	if namespace == "." { | 
 | 237 | 		return moduleName | 
 | 238 | 	} | 
 | 239 | 	return fmt.Sprintf("//%s:%s", namespace, moduleName) | 
 | 240 | } | 
 | 241 |  | 
 | 242 | func getBitness(archTypes []android.ArchType) (ret []string) { | 
 | 243 | 	for _, archType := range archTypes { | 
 | 244 | 		if archType.Multilib == "" { | 
 | 245 | 			ret = append(ret, android.COMMON_VARIANT) | 
 | 246 | 		} else { | 
 | 247 | 			ret = append(ret, archType.Bitness()) | 
 | 248 | 		} | 
 | 249 | 	} | 
 | 250 | 	return ret | 
 | 251 | } | 
 | 252 |  | 
 | 253 | func setDepsMutator(mctx android.BottomUpMutatorContext) { | 
 | 254 | 	removeOverriddenDeps(mctx) | 
 | 255 | 	fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) | 
 | 256 | 	fsDeps := fsGenState.fsDeps | 
 | 257 | 	soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions) | 
 | 258 | 	m := mctx.Module() | 
 | 259 | 	if partition, ok := soongGeneratedPartitionMap[m.Name()]; ok { | 
 | 260 | 		depsStruct := generateDepStruct(*fsDeps[partition]) | 
 | 261 | 		if err := proptools.AppendMatchingProperties(m.GetProperties(), depsStruct, nil); err != nil { | 
 | 262 | 			mctx.ModuleErrorf(err.Error()) | 
 | 263 | 		} | 
 | 264 | 	} | 
 | 265 | } | 
 | 266 |  | 
 | 267 | // removeOverriddenDeps collects PRODUCT_PACKAGES and (transitive) required deps. | 
 | 268 | // it then removes any modules which appear in `overrides` of the above list. | 
 | 269 | func removeOverriddenDeps(mctx android.BottomUpMutatorContext) { | 
 | 270 | 	mctx.Config().Once(fsGenRemoveOverridesOnceKey, func() interface{} { | 
 | 271 | 		fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) | 
 | 272 | 		fsDeps := fsGenState.fsDeps | 
 | 273 | 		overridden := map[string]bool{} | 
 | 274 | 		allDeps := []string{} | 
 | 275 |  | 
 | 276 | 		// Step 1: Initialization: Append PRODUCT_PACKAGES to the queue | 
 | 277 | 		for _, fsDep := range fsDeps { | 
 | 278 | 			for depName, _ := range *fsDep { | 
 | 279 | 				allDeps = append(allDeps, depName) | 
 | 280 | 			} | 
 | 281 | 		} | 
 | 282 |  | 
 | 283 | 		// Step 2: Process the queue, and add required modules to the queue. | 
 | 284 | 		i := 0 | 
 | 285 | 		for { | 
 | 286 | 			if i == len(allDeps) { | 
 | 287 | 				break | 
 | 288 | 			} | 
 | 289 | 			depName := allDeps[i] | 
 | 290 | 			for _, overrides := range fsGenState.moduleToInstallationProps[depName].Overrides { | 
 | 291 | 				overridden[overrides] = true | 
 | 292 | 			} | 
 | 293 | 			// add required dep to the queue. | 
 | 294 | 			allDeps = append(allDeps, fsGenState.moduleToInstallationProps[depName].Required...) | 
 | 295 | 			i += 1 | 
 | 296 | 		} | 
 | 297 |  | 
 | 298 | 		// Step 3: Delete all the overridden modules. | 
 | 299 | 		for overridden, _ := range overridden { | 
 | 300 | 			for partition, _ := range fsDeps { | 
 | 301 | 				delete(*fsDeps[partition], overridden) | 
 | 302 | 			} | 
 | 303 | 		} | 
 | 304 | 		return nil | 
 | 305 | 	}) | 
 | 306 | } | 
 | 307 |  | 
 | 308 | var HighPriorityDeps = []string{} | 
 | 309 |  | 
 | 310 | func generateDepStruct(deps map[string]*depCandidateProps) *packagingPropsStruct { | 
 | 311 | 	depsStruct := packagingPropsStruct{} | 
 | 312 | 	for depName, depProps := range deps { | 
 | 313 | 		bitness := getBitness(depProps.Arch) | 
 | 314 | 		fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace) | 
 | 315 | 		if android.InList(depName, HighPriorityDeps) { | 
 | 316 | 			depsStruct.High_priority_deps = append(depsStruct.High_priority_deps, fullyQualifiedDepName) | 
 | 317 | 		} else if android.InList("32", bitness) && android.InList("64", bitness) { | 
 | 318 | 			// If both 32 and 64 bit variants are enabled for this module | 
 | 319 | 			switch depProps.Multilib { | 
 | 320 | 			case string(android.MultilibBoth): | 
 | 321 | 				depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName) | 
 | 322 | 			case string(android.MultilibCommon), string(android.MultilibFirst): | 
 | 323 | 				depsStruct.Deps = append(depsStruct.Deps, fullyQualifiedDepName) | 
 | 324 | 			case "32": | 
 | 325 | 				depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName) | 
 | 326 | 			case "64", "darwin_universal": | 
 | 327 | 				depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName) | 
 | 328 | 			case "prefer32", "first_prefer32": | 
 | 329 | 				depsStruct.Multilib.Prefer32.Deps = append(depsStruct.Multilib.Prefer32.Deps, fullyQualifiedDepName) | 
 | 330 | 			default: | 
 | 331 | 				depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName) | 
 | 332 | 			} | 
 | 333 | 		} else if android.InList("64", bitness) { | 
 | 334 | 			// If only 64 bit variant is enabled | 
 | 335 | 			depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName) | 
 | 336 | 		} else if android.InList("32", bitness) { | 
 | 337 | 			// If only 32 bit variant is enabled | 
 | 338 | 			depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName) | 
 | 339 | 		} else { | 
 | 340 | 			// If only common variant is enabled | 
 | 341 | 			depsStruct.Multilib.Common.Deps = append(depsStruct.Multilib.Common.Deps, fullyQualifiedDepName) | 
 | 342 | 		} | 
 | 343 | 	} | 
 | 344 | 	depsStruct.Deps = android.SortedUniqueStrings(depsStruct.Deps) | 
 | 345 | 	depsStruct.Multilib.Lib32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib32.Deps) | 
 | 346 | 	depsStruct.Multilib.Lib64.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib64.Deps) | 
 | 347 | 	depsStruct.Multilib.Prefer32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Prefer32.Deps) | 
 | 348 | 	depsStruct.Multilib.Both.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Both.Deps) | 
 | 349 | 	depsStruct.Multilib.Common.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Common.Deps) | 
 | 350 |  | 
 | 351 | 	return &depsStruct | 
 | 352 | } |