| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 1 | // Copyright (C) 2019 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 apex | 
 | 16 |  | 
 | 17 | import ( | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 18 | 	"strings" | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 19 |  | 
 | 20 | 	"android/soong/android" | 
 | 21 | 	"android/soong/cc" | 
 | 22 |  | 
 | 23 | 	"github.com/google/blueprint/proptools" | 
 | 24 | ) | 
 | 25 |  | 
 | 26 | const ( | 
| Jooyung Han | 27151d9 | 2019-12-16 17:45:32 +0900 | [diff] [blame] | 27 | 	vndkApexName       = "com.android.vndk" | 
 | 28 | 	vndkApexNamePrefix = vndkApexName + ".v" | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 29 | ) | 
 | 30 |  | 
 | 31 | // apex_vndk creates a special variant of apex modules which contains only VNDK libraries. | 
 | 32 | // If `vndk_version` is specified, the VNDK libraries of the specified VNDK version are gathered automatically. | 
 | 33 | // If not specified, then the "current" versions are gathered. | 
 | 34 | func vndkApexBundleFactory() android.Module { | 
 | 35 | 	bundle := newApexBundle() | 
 | 36 | 	bundle.vndkApex = true | 
 | 37 | 	bundle.AddProperties(&bundle.vndkProperties) | 
 | 38 | 	android.AddLoadHook(bundle, func(ctx android.LoadHookContext) { | 
 | 39 | 		ctx.AppendProperties(&struct { | 
 | 40 | 			Compile_multilib *string | 
 | 41 | 		}{ | 
 | 42 | 			proptools.StringPtr("both"), | 
 | 43 | 		}) | 
 | 44 | 	}) | 
 | 45 | 	return bundle | 
 | 46 | } | 
 | 47 |  | 
 | 48 | func (a *apexBundle) vndkVersion(config android.DeviceConfig) string { | 
 | 49 | 	vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current") | 
 | 50 | 	if vndkVersion == "current" { | 
 | 51 | 		vndkVersion = config.PlatformVndkVersion() | 
 | 52 | 	} | 
 | 53 | 	return vndkVersion | 
 | 54 | } | 
 | 55 |  | 
 | 56 | type apexVndkProperties struct { | 
 | 57 | 	// Indicates VNDK version of which this VNDK APEX bundles VNDK libs. Default is Platform VNDK Version. | 
 | 58 | 	Vndk_version *string | 
 | 59 | } | 
 | 60 |  | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 61 | func apexVndkMutator(mctx android.TopDownMutatorContext) { | 
 | 62 | 	if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex { | 
 | 63 | 		if ab.IsNativeBridgeSupported() { | 
 | 64 | 			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType()) | 
 | 65 | 		} | 
 | 66 |  | 
 | 67 | 		vndkVersion := ab.vndkVersion(mctx.DeviceConfig()) | 
| Colin Cross | bb137a3 | 2023-01-26 09:54:42 -0800 | [diff] [blame] | 68 | 		apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion) | 
 | 69 | 		if err != nil { | 
 | 70 | 			mctx.PropertyErrorf("vndk_version", "%s", err.Error()) | 
 | 71 | 			return | 
 | 72 | 		} | 
 | 73 |  | 
 | 74 | 		targets := mctx.MultiTargets() | 
| Prashanth Swaminathan | 0344c02 | 2023-03-02 00:18:20 +0000 | [diff] [blame] | 75 | 		if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) && | 
 | 76 | 			vndkVersion != mctx.DeviceConfig().PlatformVndkVersion() { | 
 | 77 | 			// Disable VNDK APEXes for VNDK versions less than the minimum supported API | 
 | 78 | 			// level for the primary architecture. This validation is skipped if the VNDK | 
 | 79 | 			// version matches the platform VNDK version, which can occur when the device | 
 | 80 | 			// config targets the 'current' VNDK (see `vndkVersion`). | 
| Colin Cross | bb137a3 | 2023-01-26 09:54:42 -0800 | [diff] [blame] | 81 | 			ab.Disable() | 
 | 82 | 		} | 
| Justin Yun | f14beaf | 2023-08-18 17:51:14 +0900 | [diff] [blame] | 83 | 		if proptools.String(ab.vndkProperties.Vndk_version) != "" && | 
 | 84 | 			apiLevel.GreaterThanOrEqualTo(android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())) { | 
 | 85 | 			ab.Disable() | 
 | 86 | 		} | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 87 | 	} | 
 | 88 | } | 
 | 89 |  | 
 | 90 | func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) { | 
 | 91 | 	if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) { | 
 | 92 | 		vndkVersion := m.VndkVersion() | 
| Jooyung Han | 73d20d0 | 2020-03-27 16:06:55 +0900 | [diff] [blame] | 93 | 		// For VNDK-Lite device, we gather core-variants of VNDK-Sp libraries, which doesn't have VNDK version defined | 
 | 94 | 		if vndkVersion == "" { | 
 | 95 | 			vndkVersion = mctx.DeviceConfig().PlatformVndkVersion() | 
 | 96 | 		} | 
| Colin Cross | 2807f00 | 2021-03-02 10:15:29 -0800 | [diff] [blame] | 97 | 		if vndkVersion == mctx.DeviceConfig().PlatformVndkVersion() { | 
 | 98 | 			vndkVersion = "current" | 
 | 99 | 		} else { | 
 | 100 | 			vndkVersion = "v" + vndkVersion | 
 | 101 | 		} | 
 | 102 |  | 
 | 103 | 		vndkApexName := "com.android.vndk." + vndkVersion | 
 | 104 |  | 
 | 105 | 		if mctx.OtherModuleExists(vndkApexName) { | 
 | 106 | 			mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApexName) | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 107 | 		} | 
 | 108 | 	} else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex { | 
 | 109 | 		vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current") | 
| Kiyoung Kim | a2d6dee | 2023-08-11 10:14:43 +0900 | [diff] [blame] | 110 | 		mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...) | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 111 | 	} | 
 | 112 | } | 
 | 113 |  | 
| Jooyung Han | 002ab68 | 2020-01-08 01:57:58 +0900 | [diff] [blame] | 114 | // name is module.BaseModuleName() which is used as LOCAL_MODULE_NAME and also LOCAL_OVERRIDES_* | 
| Jooyung Han | 06a8a1c | 2023-08-23 11:11:43 +0900 | [diff] [blame] | 115 | func makeCompatSymlinks(name string, ctx android.ModuleContext) (symlinks android.InstallPaths) { | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 116 | 	// small helper to add symlink commands | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 117 | 	addSymlink := func(target string, dir android.InstallPath, linkName string) { | 
| Jooyung Han | 06a8a1c | 2023-08-23 11:11:43 +0900 | [diff] [blame] | 118 | 		symlinks = append(symlinks, ctx.InstallAbsoluteSymlink(dir, linkName, target)) | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 119 | 	} | 
 | 120 |  | 
 | 121 | 	// TODO(b/142911355): [VNDK APEX] Fix hard-coded references to /system/lib/vndk | 
 | 122 | 	// When all hard-coded references are fixed, remove symbolic links | 
 | 123 | 	// Note that  we should keep following symlinks for older VNDKs (<=29) | 
 | 124 | 	// Since prebuilt vndk libs still depend on system/lib/vndk path | 
| Jooyung Han | 055418a | 2020-04-14 14:22:31 +0900 | [diff] [blame] | 125 | 	if strings.HasPrefix(name, vndkApexNamePrefix) { | 
 | 126 | 		vndkVersion := strings.TrimPrefix(name, vndkApexNamePrefix) | 
| Dan Albert | c806053 | 2020-07-22 22:32:17 -0700 | [diff] [blame] | 127 | 		if ver, err := android.ApiLevelFromUser(ctx, vndkVersion); err != nil { | 
| Jooyung Han | 055418a | 2020-04-14 14:22:31 +0900 | [diff] [blame] | 128 | 			ctx.ModuleErrorf("apex_vndk should be named as %v<ver:number>: %s", vndkApexNamePrefix, name) | 
 | 129 | 			return | 
| Dan Albert | c806053 | 2020-07-22 22:32:17 -0700 | [diff] [blame] | 130 | 		} else if ver.GreaterThan(android.SdkVersion_Android10) { | 
| Jooyung Han | 055418a | 2020-04-14 14:22:31 +0900 | [diff] [blame] | 131 | 			return | 
| Jooyung Han | 002ab68 | 2020-01-08 01:57:58 +0900 | [diff] [blame] | 132 | 		} | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 133 | 		// the name of vndk apex is formatted "com.android.vndk.v" + version | 
| Jooyung Han | 002ab68 | 2020-01-08 01:57:58 +0900 | [diff] [blame] | 134 | 		apexName := vndkApexNamePrefix + vndkVersion | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 135 | 		if ctx.Config().Android64() { | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 136 | 			dir := android.PathForModuleInPartitionInstall(ctx, "system", "lib64") | 
 | 137 | 			addSymlink("/apex/"+apexName+"/lib64", dir, "vndk-sp-"+vndkVersion) | 
 | 138 | 			addSymlink("/apex/"+apexName+"/lib64", dir, "vndk-"+vndkVersion) | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 139 | 		} | 
 | 140 | 		if !ctx.Config().Android64() || ctx.DeviceConfig().DeviceSecondaryArch() != "" { | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 141 | 			dir := android.PathForModuleInPartitionInstall(ctx, "system", "lib") | 
 | 142 | 			addSymlink("/apex/"+apexName+"/lib", dir, "vndk-sp-"+vndkVersion) | 
 | 143 | 			addSymlink("/apex/"+apexName+"/lib", dir, "vndk-"+vndkVersion) | 
| Jooyung Han | 4791cb5 | 2019-10-25 18:17:23 +0900 | [diff] [blame] | 144 | 		} | 
 | 145 | 	} | 
 | 146 |  | 
 | 147 | 	// http://b/121248172 - create a link from /system/usr/icu to | 
 | 148 | 	// /apex/com.android.i18n/etc/icu so that apps can find the ICU .dat file. | 
 | 149 | 	// A symlink can't overwrite a directory and the /system/usr/icu directory once | 
 | 150 | 	// existed so the required structure must be created whatever we find. | 
| Jooyung Han | 002ab68 | 2020-01-08 01:57:58 +0900 | [diff] [blame] | 151 | 	if name == "com.android.i18n" { | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 152 | 		dir := android.PathForModuleInPartitionInstall(ctx, "system", "usr") | 
 | 153 | 		addSymlink("/apex/com.android.i18n/etc/icu", dir, "icu") | 
| Jooyung Han | 4791cb5 | 2019-10-25 18:17:23 +0900 | [diff] [blame] | 154 | 	} | 
 | 155 |  | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 156 | 	return symlinks | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 157 | } |