blob: a52f4053ffda47376b438436acea43ba8f80e45a [file] [log] [blame]
Makoto Onuki4a9869d2023-10-20 10:42:47 -07001// Copyright 2023 Google Inc. All rights reserved.
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.
14package java
15
16import (
17 "android/soong/android"
18 "android/soong/tradefed"
19
Makoto Onuki2ca84272024-02-10 00:15:21 +000020 "github.com/google/blueprint"
Makoto Onuki4a9869d2023-10-20 10:42:47 -070021 "github.com/google/blueprint/proptools"
22)
23
24func init() {
25 RegisterRavenwoodBuildComponents(android.InitRegistrationContext)
26}
27
28func RegisterRavenwoodBuildComponents(ctx android.RegistrationContext) {
29 ctx.RegisterModuleType("android_ravenwood_test", ravenwoodTestFactory)
30 ctx.RegisterModuleType("android_ravenwood_libgroup", ravenwoodLibgroupFactory)
31}
32
Makoto Onuki2ca84272024-02-10 00:15:21 +000033var ravenwoodLibContentTag = dependencyTag{name: "ravenwoodlibcontent"}
34var ravenwoodUtilsTag = dependencyTag{name: "ravenwoodutils"}
35var ravenwoodRuntimeTag = dependencyTag{name: "ravenwoodruntime"}
Makoto Onuki3380f6d2024-05-10 16:00:28 -070036var ravenwoodDataTag = dependencyTag{name: "ravenwooddata"}
37var ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"}
Makoto Onuki4a9869d2023-10-20 10:42:47 -070038
39const ravenwoodUtilsName = "ravenwood-utils"
40const ravenwoodRuntimeName = "ravenwood-runtime"
41
Makoto Onuki2ca84272024-02-10 00:15:21 +000042type ravenwoodLibgroupJniDepProviderInfo struct {
43 // All the jni_libs module names with transient dependencies.
44 names map[string]bool
45}
46
47var ravenwoodLibgroupJniDepProvider = blueprint.NewProvider[ravenwoodLibgroupJniDepProviderInfo]()
48
Makoto Onuki68676572024-02-02 13:29:01 -080049func getLibPath(archType android.ArchType) string {
50 if archType.Multilib == "lib64" {
51 return "lib64"
52 }
53 return "lib"
54}
55
56type ravenwoodTestProperties struct {
57 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -070058
59 // Specify another android_app module here to copy it to the test directory, so that
60 // the ravenwood test can access it.
61 // TODO: For now, we simply refer to another android_app module and copy it to the
62 // test directory. Eventually, android_ravenwood_test should support all the resource
63 // related properties and build resources from the `res/` directory.
64 Resource_apk *string
Makoto Onuki68676572024-02-02 13:29:01 -080065}
66
Makoto Onuki4a9869d2023-10-20 10:42:47 -070067type ravenwoodTest struct {
68 Library
69
Makoto Onuki68676572024-02-02 13:29:01 -080070 ravenwoodTestProperties ravenwoodTestProperties
71
Makoto Onuki4a9869d2023-10-20 10:42:47 -070072 testProperties testProperties
73 testConfig android.Path
74
75 forceOSType android.OsType
76 forceArchType android.ArchType
77}
78
79func ravenwoodTestFactory() android.Module {
80 module := &ravenwoodTest{}
81
82 module.addHostAndDeviceProperties()
Makoto Onuki68676572024-02-02 13:29:01 -080083 module.AddProperties(&module.testProperties, &module.ravenwoodTestProperties)
Makoto Onuki4a9869d2023-10-20 10:42:47 -070084
85 module.Module.dexpreopter.isTest = true
86 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
87
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -070088 module.testProperties.Test_suites = []string{
89 "general-tests",
90 "ravenwood-tests",
91 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -070092 module.testProperties.Test_options.Unit_test = proptools.BoolPtr(false)
93
94 InitJavaModule(module, android.DeviceSupported)
95 android.InitDefaultableModule(module)
96
97 return module
98}
99
100func (r *ravenwoodTest) InstallInTestcases() bool { return true }
101func (r *ravenwoodTest) InstallForceOS() (*android.OsType, *android.ArchType) {
102 return &r.forceOSType, &r.forceArchType
103}
104func (r *ravenwoodTest) TestSuites() []string {
105 return r.testProperties.Test_suites
106}
107
108func (r *ravenwoodTest) DepsMutator(ctx android.BottomUpMutatorContext) {
109 r.Library.DepsMutator(ctx)
110
111 // Generically depend on the runtime so that it's installed together with us
Makoto Onuki2ca84272024-02-10 00:15:21 +0000112 ctx.AddVariationDependencies(nil, ravenwoodRuntimeTag, ravenwoodRuntimeName)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700113
114 // Directly depend on any utils so that we link against them
Makoto Onuki2ca84272024-02-10 00:15:21 +0000115 utils := ctx.AddVariationDependencies(nil, ravenwoodUtilsTag, ravenwoodUtilsName)[0]
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700116 if utils != nil {
117 for _, lib := range utils.(*ravenwoodLibgroup).ravenwoodLibgroupProperties.Libs {
118 ctx.AddVariationDependencies(nil, libTag, lib)
119 }
120 }
Makoto Onuki68676572024-02-02 13:29:01 -0800121
122 // Add jni libs
123 for _, lib := range r.ravenwoodTestProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000124 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800125 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700126
127 // Resources APK
128 if resourceApk := proptools.String(r.ravenwoodTestProperties.Resource_apk); resourceApk != "" {
129 ctx.AddVariationDependencies(nil, ravenwoodTestResourceApkTag, resourceApk)
130 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700131}
132
133func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
134 r.forceOSType = ctx.Config().BuildOS
135 r.forceArchType = ctx.Config().BuildArch
136
137 r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
138 TestConfigProp: r.testProperties.Test_config,
139 TestConfigTemplateProp: r.testProperties.Test_config_template,
140 TestSuites: r.testProperties.Test_suites,
141 AutoGenConfig: r.testProperties.Auto_gen_config,
142 DeviceTemplate: "${RavenwoodTestConfigTemplate}",
143 HostTemplate: "${RavenwoodTestConfigTemplate}",
144 })
145
146 r.Library.GenerateAndroidBuildActions(ctx)
147
Makoto Onuki2ca84272024-02-10 00:15:21 +0000148 // Start by depending on all files installed by dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700149 var installDeps android.InstallPaths
Makoto Onuki2ca84272024-02-10 00:15:21 +0000150
151 // All JNI libraries included in the runtime
152 var runtimeJniModuleNames map[string]bool
153
154 if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
155 for _, installFile := range utils.FilesToInstall() {
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700156 installDeps = append(installDeps, installFile)
157 }
Makoto Onuki2ca84272024-02-10 00:15:21 +0000158 jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
159 if ok {
160 runtimeJniModuleNames = jniDeps.names
161 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700162 }
163
Makoto Onuki2ca84272024-02-10 00:15:21 +0000164 if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
165 for _, installFile := range runtime.FilesToInstall() {
166 installDeps = append(installDeps, installFile)
167 }
168 jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
169 if ok {
170 runtimeJniModuleNames = jniDeps.names
171 }
172 }
173
174 // Also remember what JNI libs are in the runtime.
175
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700176 // Also depend on our config
177 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
178 installConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
179 installDeps = append(installDeps, installConfig)
180
Makoto Onuki2ca84272024-02-10 00:15:21 +0000181 // Depend on the JNI libraries, but don't install the ones that the runtime already
182 // contains.
Makoto Onuki68676572024-02-02 13:29:01 -0800183 soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000184 for _, jniLib := range collectTransitiveJniDeps(ctx) {
185 if _, ok := runtimeJniModuleNames[jniLib.name]; ok {
186 continue // Runtime already includes it.
187 }
188 installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800189 installDeps = append(installDeps, installJni)
190 }
191
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700192 resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
193 if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 {
194 for _, installFile := range resApk[0].FilesToInstall() {
195 installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile)
196 installDeps = append(installDeps, installResApk)
197 }
198 }
199
Makoto Onuki68676572024-02-02 13:29:01 -0800200 // Install our JAR with all dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700201 ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
202}
203
204func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
205 entriesList := r.Library.AndroidMkEntries()
206 entries := &entriesList[0]
207 entries.ExtraEntries = append(entries.ExtraEntries,
208 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
209 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700210 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE",
211 "general-tests", "ravenwood-tests")
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700212 if r.testConfig != nil {
213 entries.SetPath("LOCAL_FULL_TEST_CONFIG", r.testConfig)
214 }
215 })
216 return entriesList
217}
218
219type ravenwoodLibgroupProperties struct {
220 Libs []string
Makoto Onuki68676572024-02-02 13:29:01 -0800221
222 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700223
224 // We use this to copy framework-res.apk to the ravenwood runtime directory.
225 Data []string
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700226}
227
228type ravenwoodLibgroup struct {
229 android.ModuleBase
230
231 ravenwoodLibgroupProperties ravenwoodLibgroupProperties
232
233 forceOSType android.OsType
234 forceArchType android.ArchType
235}
236
237func ravenwoodLibgroupFactory() android.Module {
238 module := &ravenwoodLibgroup{}
239 module.AddProperties(&module.ravenwoodLibgroupProperties)
240
241 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
242 return module
243}
244
245func (r *ravenwoodLibgroup) InstallInTestcases() bool { return true }
246func (r *ravenwoodLibgroup) InstallForceOS() (*android.OsType, *android.ArchType) {
247 return &r.forceOSType, &r.forceArchType
248}
249func (r *ravenwoodLibgroup) TestSuites() []string {
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700250 return []string{
251 "general-tests",
252 "ravenwood-tests",
253 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700254}
255
256func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) {
257 // Always depends on our underlying libs
258 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000259 ctx.AddVariationDependencies(nil, ravenwoodLibContentTag, lib)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700260 }
Makoto Onuki68676572024-02-02 13:29:01 -0800261 for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000262 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800263 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700264 for _, data := range r.ravenwoodLibgroupProperties.Data {
265 ctx.AddVariationDependencies(nil, ravenwoodDataTag, data)
266 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700267}
268
269func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
270 r.forceOSType = ctx.Config().BuildOS
271 r.forceArchType = ctx.Config().BuildArch
272
Makoto Onuki2ca84272024-02-10 00:15:21 +0000273 // Collect the JNI dependencies, including the transitive deps.
274 jniDepNames := make(map[string]bool)
275 jniLibs := collectTransitiveJniDeps(ctx)
276
277 for _, jni := range jniLibs {
278 jniDepNames[jni.name] = true
279 }
280 android.SetProvider(ctx, ravenwoodLibgroupJniDepProvider, ravenwoodLibgroupJniDepProviderInfo{
281 names: jniDepNames,
282 })
283
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700284 // Install our runtime into expected location for packaging
285 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
286 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000287 libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
Jerome Gaillard44fc5bf2024-07-30 16:11:59 +0000288 if libModule == nil {
289 if ctx.Config().AllowMissingDependencies() {
290 ctx.AddMissingDependencies([]string{lib})
291 } else {
292 ctx.PropertyErrorf("lib", "missing dependency %q", lib)
293 }
294 continue
295 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700296 libJar := android.OutputFileForModule(ctx, libModule, "")
297 ctx.InstallFile(installPath, lib+".jar", libJar)
298 }
Makoto Onuki68676572024-02-02 13:29:01 -0800299 soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000300
301 for _, jniLib := range jniLibs {
302 ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800303 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700304
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700305 dataInstallPath := installPath.Join(ctx, "ravenwood-data")
306 for _, data := range r.ravenwoodLibgroupProperties.Data {
307 libModule := ctx.GetDirectDepWithTag(data, ravenwoodDataTag)
308 file := android.OutputFileForModule(ctx, libModule, "")
309 ctx.InstallFile(dataInstallPath, file.Base(), file)
310 }
311
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700312 // Normal build should perform install steps
313 ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
314}
Makoto Onuki2ca84272024-02-10 00:15:21 +0000315
316// collectTransitiveJniDeps returns all JNI dependencies, including transitive
317// ones, including NDK / stub libs. (Because Ravenwood has no "preinstalled" libraries)
318func collectTransitiveJniDeps(ctx android.ModuleContext) []jniLib {
319 libs, _ := collectJniDeps(ctx, true, false, nil)
320 return libs
321}