blob: 4e515b4038c0cab2dcae0f7e06bbc088975918bf [file] [log] [blame]
Colin Cross9bb9bfb2022-03-17 11:12:32 -07001// Copyright 2022 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.
14
15package java
16
17import (
Sam Delmerico95d70942023-08-02 18:00:35 -040018 "fmt"
Jared Duke70b85422025-01-28 19:13:39 +000019 "strconv"
Colin Cross9bb9bfb2022-03-17 11:12:32 -070020 "testing"
21
22 "android/soong/android"
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050023
24 "github.com/google/blueprint/proptools"
Colin Cross9bb9bfb2022-03-17 11:12:32 -070025)
26
27func TestR8(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080028 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +000029 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -070030 android_app {
31 name: "app",
32 srcs: ["foo.java"],
33 libs: ["lib"],
34 static_libs: ["static_lib"],
35 platform_apis: true,
36 }
37
Jared Duke40d731a2022-09-20 15:32:14 -070038 android_app {
39 name: "stable_app",
40 srcs: ["foo.java"],
41 sdk_version: "current",
42 min_sdk_version: "31",
43 }
44
45 android_app {
46 name: "core_platform_app",
47 srcs: ["foo.java"],
48 sdk_version: "core_platform",
Spandan Dasc404cc72023-02-23 18:05:05 +000049 min_sdk_version: "31",
Jared Duke40d731a2022-09-20 15:32:14 -070050 }
51
Colin Cross9bb9bfb2022-03-17 11:12:32 -070052 java_library {
53 name: "lib",
54 srcs: ["foo.java"],
55 }
56
57 java_library {
58 name: "static_lib",
59 srcs: ["foo.java"],
60 }
61 `)
62
63 app := result.ModuleForTests("app", "android_common")
Jared Duke40d731a2022-09-20 15:32:14 -070064 stableApp := result.ModuleForTests("stable_app", "android_common")
65 corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070066 lib := result.ModuleForTests("lib", "android_common")
67 staticLib := result.ModuleForTests("static_lib", "android_common")
68
69 appJavac := app.Rule("javac")
70 appR8 := app.Rule("r8")
Jared Duke40d731a2022-09-20 15:32:14 -070071 stableAppR8 := stableApp.Rule("r8")
72 corePlatformAppR8 := corePlatformApp.Rule("r8")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070073 libHeader := lib.Output("turbine-combined/lib.jar").Output
74 staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
75
76 android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
77 appJavac.Args["classpath"], libHeader.String())
78 android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
79 appJavac.Args["classpath"], staticLibHeader.String())
80
81 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
82 appR8.Args["r8Flags"], libHeader.String())
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050083 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
Colin Cross9bb9bfb2022-03-17 11:12:32 -070084 appR8.Args["r8Flags"], staticLibHeader.String())
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090085 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
86 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -070087 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
88 appR8.Args["r8Flags"], "--android-platform-build")
89 android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
90 stableAppR8.Args["r8Flags"], "--android-platform-build")
91 android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
92 corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090093}
94
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050095func TestR8TransitiveDeps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080096 t.Parallel()
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050097 bp := `
98 override_android_app {
99 name: "override_app",
100 base: "app",
101 }
102
103 android_app {
104 name: "app",
105 srcs: ["foo.java"],
106 libs: [
107 "lib",
108 "uses_libs_dep_import",
109 ],
110 static_libs: [
111 "static_lib",
112 "repeated_dep",
113 ],
114 platform_apis: true,
115 }
116
117 java_library {
118 name: "static_lib",
119 srcs: ["foo.java"],
120 }
121
122 java_library {
123 name: "lib",
124 libs: [
125 "transitive_lib",
126 "repeated_dep",
127 "prebuilt_lib",
128 ],
129 static_libs: ["transitive_static_lib"],
130 srcs: ["foo.java"],
131 }
132
133 java_library {
134 name: "repeated_dep",
135 srcs: ["foo.java"],
136 }
137
138 java_library {
139 name: "transitive_static_lib",
140 srcs: ["foo.java"],
141 }
142
143 java_library {
144 name: "transitive_lib",
145 srcs: ["foo.java"],
146 libs: ["transitive_lib_2"],
147 }
148
149 java_library {
150 name: "transitive_lib_2",
151 srcs: ["foo.java"],
152 }
153
154 java_import {
155 name: "lib",
156 jars: ["lib.jar"],
157 }
158
159 java_library {
160 name: "uses_lib",
161 srcs: ["foo.java"],
162 }
163
164 java_library {
165 name: "optional_uses_lib",
166 srcs: ["foo.java"],
167 }
168
169 android_library {
170 name: "uses_libs_dep",
171 uses_libs: ["uses_lib"],
172 optional_uses_libs: ["optional_uses_lib"],
173 }
174
175 android_library_import {
176 name: "uses_libs_dep_import",
177 aars: ["aar.aar"],
178 static_libs: ["uses_libs_dep"],
179 }
180 `
181
182 testcases := []struct {
183 name string
184 unbundled bool
185 }{
186 {
187 name: "non-unbundled build",
188 unbundled: false,
189 },
190 {
191 name: "unbundled build",
192 unbundled: true,
193 },
194 }
195
196 for _, tc := range testcases {
197 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800198 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000199 fixturePreparer := PrepareForTestWithJavaDefaultModules
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500200 if tc.unbundled {
201 fixturePreparer = android.GroupFixturePreparers(
202 fixturePreparer,
203 android.FixtureModifyProductVariables(
204 func(variables android.FixtureProductVariables) {
205 variables.Unbundled_build = proptools.BoolPtr(true)
206 },
207 ),
208 )
209 }
210 result := fixturePreparer.RunTestWithBp(t, bp)
211
212 getHeaderJar := func(name string) android.Path {
213 mod := result.ModuleForTests(name, "android_common")
214 return mod.Output("turbine-combined/" + name + ".jar").Output
215 }
216
217 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
218 overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
219 appHeader := getHeaderJar("app")
220 overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
221 libHeader := getHeaderJar("lib")
222 transitiveLibHeader := getHeaderJar("transitive_lib")
223 transitiveLib2Header := getHeaderJar("transitive_lib_2")
224 staticLibHeader := getHeaderJar("static_lib")
225 transitiveStaticLibHeader := getHeaderJar("transitive_static_lib")
226 repeatedDepHeader := getHeaderJar("repeated_dep")
227 usesLibHeader := getHeaderJar("uses_lib")
228 optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
229 prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
230
231 for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
232 android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
233 rule.Args["r8Flags"], appHeader.String())
234 android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath",
235 rule.Args["r8Flags"], overrideAppHeader.String())
236 android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath",
237 rule.Args["r8Flags"], transitiveLibHeader.String())
238 android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath",
239 rule.Args["r8Flags"], transitiveLib2Header.String())
240 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
241 rule.Args["r8Flags"], libHeader.String())
242 android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath",
243 rule.Args["r8Flags"], usesLibHeader.String())
244 android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath",
245 rule.Args["r8Flags"], optionalUsesLibHeader.String())
246 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
247 rule.Args["r8Flags"], staticLibHeader.String())
248 android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath",
249 rule.Args["r8Flags"], transitiveStaticLibHeader.String())
250 // we shouldn't list this dep because it is already included as static_libs in the app
251 android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath",
252 rule.Args["r8Flags"], repeatedDepHeader.String())
253 // skip a prebuilt transitive dep if the source is also a transitive dep
254 android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath",
255 rule.Args["r8Flags"], prebuiltLibHeader.String())
256 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
257 rule.Args["r8Flags"], "-ignorewarnings")
258 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
259 rule.Args["r8Flags"], "--android-platform-build")
260 }
261 })
262 }
263}
264
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900265func TestR8Flags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800266 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000267 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900268 android_app {
269 name: "app",
270 srcs: ["foo.java"],
271 platform_apis: true,
272 optimize: {
273 shrink: false,
274 optimize: false,
275 obfuscate: false,
276 ignore_warnings: false,
277 },
278 }
279 `)
280
281 app := result.ModuleForTests("app", "android_common")
282 appR8 := app.Rule("r8")
283 android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
284 appR8.Args["r8Flags"], "-dontshrink")
285 android.AssertStringDoesContain(t, "expected -dontoptimize in app r8 flags",
286 appR8.Args["r8Flags"], "-dontoptimize")
287 android.AssertStringDoesContain(t, "expected -dontobfuscate in app r8 flags",
288 appR8.Args["r8Flags"], "-dontobfuscate")
289 android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
290 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -0700291 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
292 appR8.Args["r8Flags"], "--android-platform-build")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700293}
294
295func TestD8(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800296 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000297 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700298 java_library {
299 name: "foo",
300 srcs: ["foo.java"],
301 libs: ["lib"],
302 static_libs: ["static_lib"],
303 installable: true,
304 }
305
306 java_library {
307 name: "lib",
308 srcs: ["foo.java"],
309 }
310
311 java_library {
312 name: "static_lib",
313 srcs: ["foo.java"],
314 }
Jared Duke70b85422025-01-28 19:13:39 +0000315
316 android_app {
317 name: "app",
318 srcs: ["foo.java"],
319 platform_apis: true,
320 optimize: {
321 enabled: false,
322 },
323 }
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700324 `)
325
326 foo := result.ModuleForTests("foo", "android_common")
327 lib := result.ModuleForTests("lib", "android_common")
Jared Duke70b85422025-01-28 19:13:39 +0000328 app := result.ModuleForTests("app", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700329 staticLib := result.ModuleForTests("static_lib", "android_common")
330
331 fooJavac := foo.Rule("javac")
332 fooD8 := foo.Rule("d8")
Jared Duke70b85422025-01-28 19:13:39 +0000333 appD8 := app.Rule("d8")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700334 libHeader := lib.Output("turbine-combined/lib.jar").Output
335 staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
336
337 android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
338 fooJavac.Args["classpath"], libHeader.String())
339 android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
340 fooJavac.Args["classpath"], staticLibHeader.String())
341
342 android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
343 fooD8.Args["d8Flags"], libHeader.String())
344 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath",
345 fooD8.Args["d8Flags"], staticLibHeader.String())
Jared Duke70b85422025-01-28 19:13:39 +0000346
347 // A --release flag is added only for targets that opt out of default R8 behavior (e.g., apps).
348 // For library targets that don't use R8 by default, no --debug or --release flag should be
349 // added, instead relying on default D8 behavior (--debug).
350 android.AssertStringDoesContain(t, "expected --release in app d8 flags",
351 appD8.Args["d8Flags"], "--release")
352 android.AssertStringDoesNotContain(t, "expected no --release flag in lib d8 flags",
353 fooD8.Args["d8Flags"], "--release")
354 android.AssertStringDoesNotContain(t, "expected no --debug flag in lib d8 flags",
355 fooD8.Args["d8Flags"], "--debug")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700356}
Jared Duke5979b302022-12-19 21:08:39 +0000357
Sam Delmerico95d70942023-08-02 18:00:35 -0400358func TestProguardFlagsInheritanceStatic(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800359 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000360 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Jared Duke5979b302022-12-19 21:08:39 +0000361 android_app {
362 name: "app",
363 static_libs: [
364 "primary_android_lib",
365 "primary_lib",
366 ],
367 platform_apis: true,
368 }
369
370 java_library {
371 name: "primary_lib",
372 optimize: {
373 proguard_flags_files: ["primary.flags"],
374 },
375 }
376
377 android_library {
378 name: "primary_android_lib",
379 static_libs: ["secondary_lib"],
380 optimize: {
381 proguard_flags_files: ["primary_android.flags"],
382 },
383 }
384
385 java_library {
386 name: "secondary_lib",
387 static_libs: ["tertiary_lib"],
388 optimize: {
389 proguard_flags_files: ["secondary.flags"],
390 },
391 }
392
393 java_library {
394 name: "tertiary_lib",
395 optimize: {
396 proguard_flags_files: ["tertiary.flags"],
397 },
398 }
399 `)
400
401 app := result.ModuleForTests("app", "android_common")
402 appR8 := app.Rule("r8")
403 android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
404 appR8.Args["r8Flags"], "primary.flags")
405 android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
406 appR8.Args["r8Flags"], "primary_android.flags")
407 android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
408 appR8.Args["r8Flags"], "secondary.flags")
409 android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
410 appR8.Args["r8Flags"], "tertiary.flags")
411}
Sam Delmerico95d70942023-08-02 18:00:35 -0400412
413func TestProguardFlagsInheritance(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800414 t.Parallel()
Sam Delmerico95d70942023-08-02 18:00:35 -0400415 directDepFlagsFileName := "direct_dep.flags"
416 transitiveDepFlagsFileName := "transitive_dep.flags"
Sam Delmerico95d70942023-08-02 18:00:35 -0400417
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000418 topLevelModules := []struct {
419 name string
420 definition string
421 }{
422 {
423 name: "android_app",
424 definition: `
425 android_app {
426 name: "app",
427 static_libs: ["androidlib"], // this must be static_libs to initate dexing
428 platform_apis: true,
429 }
430 `,
431 },
432 {
433 name: "android_library",
434 definition: `
435 android_library {
436 name: "app",
437 static_libs: ["androidlib"], // this must be static_libs to initate dexing
438 installable: true,
439 optimize: {
440 enabled: true,
441 shrink: true,
442 },
443 }
444 `,
445 },
446 {
447 name: "java_library",
448 definition: `
449 java_library {
450 name: "app",
451 static_libs: ["androidlib"], // this must be static_libs to initate dexing
452 srcs: ["Foo.java"],
453 installable: true,
454 optimize: {
455 enabled: true,
456 shrink: true,
457 },
458 }
459 `,
460 },
461 }
462
463 bp := `
Sam Delmerico95d70942023-08-02 18:00:35 -0400464 android_library {
465 name: "androidlib",
466 static_libs: ["app_dep"],
467 }
468
469 java_library {
470 name: "app_dep",
471 %s: ["dep"],
472 }
473
474 java_library {
475 name: "dep",
476 %s: ["transitive_dep"],
477 optimize: {
478 proguard_flags_files: ["direct_dep.flags"],
479 export_proguard_flags_files: %v,
480 },
481 }
482
483 java_library {
484 name: "transitive_dep",
485 optimize: {
486 proguard_flags_files: ["transitive_dep.flags"],
487 export_proguard_flags_files: %v,
488 },
489 }
490 `
491
492 testcases := []struct {
493 name string
494 depType string
495 depExportsFlagsFiles bool
496 transitiveDepType string
497 transitiveDepExportsFlagsFiles bool
498 expectedFlagsFiles []string
499 }{
500 {
501 name: "libs_export_libs_export",
502 depType: "libs",
503 depExportsFlagsFiles: true,
504 transitiveDepType: "libs",
505 transitiveDepExportsFlagsFiles: true,
506 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
507 },
508 {
509 name: "static_export_libs_export",
510 depType: "static_libs",
511 depExportsFlagsFiles: true,
512 transitiveDepType: "libs",
513 transitiveDepExportsFlagsFiles: true,
514 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
515 },
516 {
517 name: "libs_no-export_static_export",
518 depType: "libs",
519 depExportsFlagsFiles: false,
520 transitiveDepType: "static_libs",
521 transitiveDepExportsFlagsFiles: true,
522 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
523 },
524 {
525 name: "static_no-export_static_export",
526 depType: "static_libs",
527 depExportsFlagsFiles: false,
528 transitiveDepType: "static_libs",
529 transitiveDepExportsFlagsFiles: true,
530 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
531 },
532 {
533 name: "libs_export_libs_no-export",
534 depType: "libs",
535 depExportsFlagsFiles: true,
536 transitiveDepType: "libs",
537 transitiveDepExportsFlagsFiles: false,
538 expectedFlagsFiles: []string{directDepFlagsFileName},
539 },
540 {
541 name: "static_export_libs_no-export",
542 depType: "static_libs",
543 depExportsFlagsFiles: true,
544 transitiveDepType: "libs",
545 transitiveDepExportsFlagsFiles: false,
546 expectedFlagsFiles: []string{directDepFlagsFileName},
547 },
548 {
549 name: "libs_no-export_static_no-export",
550 depType: "libs",
551 depExportsFlagsFiles: false,
552 transitiveDepType: "static_libs",
553 transitiveDepExportsFlagsFiles: false,
554 expectedFlagsFiles: []string{},
555 },
556 {
557 name: "static_no-export_static_no-export",
558 depType: "static_libs",
559 depExportsFlagsFiles: false,
560 transitiveDepType: "static_libs",
561 transitiveDepExportsFlagsFiles: false,
562 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
563 },
564 {
565 name: "libs_no-export_libs_export",
566 depType: "libs",
567 depExportsFlagsFiles: false,
568 transitiveDepType: "libs",
569 transitiveDepExportsFlagsFiles: true,
570 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
571 },
572 {
573 name: "static_no-export_libs_export",
574 depType: "static_libs",
575 depExportsFlagsFiles: false,
576 transitiveDepType: "libs",
577 transitiveDepExportsFlagsFiles: true,
578 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
579 },
580 {
581 name: "libs_export_static_export",
582 depType: "libs",
583 depExportsFlagsFiles: true,
584 transitiveDepType: "static_libs",
585 transitiveDepExportsFlagsFiles: true,
586 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
587 },
588 {
589 name: "static_export_static_export",
590 depType: "static_libs",
591 depExportsFlagsFiles: true,
592 transitiveDepType: "static_libs",
593 transitiveDepExportsFlagsFiles: true,
594 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
595 },
596 {
597 name: "libs_no-export_libs_no-export",
598 depType: "libs",
599 depExportsFlagsFiles: false,
600 transitiveDepType: "libs",
601 transitiveDepExportsFlagsFiles: false,
602 expectedFlagsFiles: []string{},
603 },
604 {
605 name: "static_no-export_libs_no-export",
606 depType: "static_libs",
607 depExportsFlagsFiles: false,
608 transitiveDepType: "libs",
609 transitiveDepExportsFlagsFiles: false,
610 expectedFlagsFiles: []string{directDepFlagsFileName},
611 },
612 {
613 name: "libs_export_static_no-export",
614 depType: "libs",
615 depExportsFlagsFiles: true,
616 transitiveDepType: "static_libs",
617 transitiveDepExportsFlagsFiles: false,
618 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
619 },
620 {
621 name: "static_export_static_no-export",
622 depType: "static_libs",
623 depExportsFlagsFiles: true,
624 transitiveDepType: "static_libs",
625 transitiveDepExportsFlagsFiles: false,
626 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
627 },
628 }
629
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000630 for _, topLevelModuleDef := range topLevelModules {
631 for _, tc := range testcases {
632 t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800633 t.Parallel()
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000634 result := android.GroupFixturePreparers(
635 PrepareForTestWithJavaDefaultModules,
636 android.FixtureMergeMockFs(android.MockFS{
637 directDepFlagsFileName: nil,
638 transitiveDepFlagsFileName: nil,
639 }),
640 ).RunTestWithBp(t,
641 topLevelModuleDef.definition+
642 fmt.Sprintf(
643 bp,
644 tc.depType,
645 tc.transitiveDepType,
646 tc.depExportsFlagsFiles,
647 tc.transitiveDepExportsFlagsFiles,
648 ),
649 )
650 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
Sam Delmerico95d70942023-08-02 18:00:35 -0400651
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000652 shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
653 if shouldHaveDepFlags {
654 android.AssertStringDoesContain(t, "expected deps's proguard flags",
655 appR8.Args["r8Flags"], directDepFlagsFileName)
656 } else {
657 android.AssertStringDoesNotContain(t, "app did not expect deps's proguard flags",
658 appR8.Args["r8Flags"], directDepFlagsFileName)
659 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400660
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000661 shouldHaveTransitiveDepFlags := android.InList(transitiveDepFlagsFileName, tc.expectedFlagsFiles)
662 if shouldHaveTransitiveDepFlags {
663 android.AssertStringDoesContain(t, "expected transitive deps's proguard flags",
664 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
665 } else {
666 android.AssertStringDoesNotContain(t, "app did not expect transitive deps's proguard flags",
667 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
668 }
669 })
670 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400671 }
672}
673
674func TestProguardFlagsInheritanceAppImport(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800675 t.Parallel()
Sam Delmerico95d70942023-08-02 18:00:35 -0400676 bp := `
677 android_app {
678 name: "app",
679 static_libs: ["aarimport"], // this must be static_libs to initate dexing
680 platform_apis: true,
681 }
682
Sam Delmerico95d70942023-08-02 18:00:35 -0400683 android_library_import {
684 name: "aarimport",
685 aars: ["import.aar"],
686 }
687 `
688 result := android.GroupFixturePreparers(
689 PrepareForTestWithJavaDefaultModules,
690 ).RunTestWithBp(t, bp)
691
692 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
693 android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
694 appR8.Args["r8Flags"], "proguard.txt")
695}
Spandan Das3dbda182024-05-20 22:23:10 +0000696
697func TestR8FlagsArtProfile(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800698 t.Parallel()
Spandan Das3dbda182024-05-20 22:23:10 +0000699 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
700 android_app {
701 name: "app",
702 srcs: ["foo.java"],
703 platform_apis: true,
704 dex_preopt: {
705 profile_guided: true,
706 profile: "profile.txt.prof",
707 enable_profile_rewriting: true,
708 },
709 }
710 `)
711
712 app := result.ModuleForTests("app", "android_common")
713 appR8 := app.Rule("r8")
714 android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
715 appR8.Args["r8Flags"], "--art-profile")
716
717 appDexpreopt := app.Rule("dexpreopt")
718 android.AssertStringDoesContain(t,
719 "expected --art-profile output to be used to create .prof binary",
720 appDexpreopt.RuleParams.Command,
721 "--create-profile-from=out/soong/.intermediates/app/android_common/profile.prof.txt --output-profile-type=app",
722 )
723}
Spandan Das15a67112024-05-30 00:07:40 +0000724
725// This test checks that users explicitly set `enable_profile_rewriting` to true when the following are true
726// 1. optimize or obfuscate is enabled AND
727// 2. dex_preopt.profile_guided is enabled
728//
729// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
730func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800731 t.Parallel()
Spandan Das15a67112024-05-30 00:07:40 +0000732 testJavaError(t,
733 "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
734 `
735android_app {
736 name: "app",
737 srcs: ["foo.java"],
738 platform_apis: true,
739 dex_preopt: {
740 profile_guided: true,
741 profile: "profile.txt.prof",
742 // enable_profile_rewriting is not set, this is an error
743 },
744 optimize: {
745 optimize: true,
746 }
747}`)
748}
Jared Duked32e85f2024-09-25 23:54:30 +0000749
750func TestDebugReleaseFlags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800751 t.Parallel()
Jared Duked32e85f2024-09-25 23:54:30 +0000752 bp := `
753 android_app {
754 name: "app",
755 srcs: ["foo.java"],
756 platform_apis: true,
Jared Duke70b85422025-01-28 19:13:39 +0000757 optimize: {
758 enabled: %s,
759 },
Jared Duked32e85f2024-09-25 23:54:30 +0000760 dxflags: ["%s"]
761 }
762 `
763
764 testcases := []struct {
765 name string
766 envVar string
767 isEng bool
Jared Duke70b85422025-01-28 19:13:39 +0000768 useD8 bool
Jared Duked32e85f2024-09-25 23:54:30 +0000769 dxFlags string
770 expectedFlags string
771 }{
772 {
773 name: "app_no_optimize_dx",
774 envVar: "NO_OPTIMIZE_DX",
775 expectedFlags: "--debug",
776 },
777 {
778 name: "app_release_no_optimize_dx",
779 envVar: "NO_OPTIMIZE_DX",
780 dxFlags: "--release",
781 // Global env vars override explicit dxflags.
782 expectedFlags: "--debug",
783 },
784 {
785 name: "app_generate_dex_debug",
786 envVar: "GENERATE_DEX_DEBUG",
787 expectedFlags: "--debug",
788 },
789 {
790 name: "app_release_generate_dex_debug",
791 envVar: "GENERATE_DEX_DEBUG",
792 dxFlags: "--release",
793 // Global env vars override explicit dxflags.
794 expectedFlags: "--debug",
795 },
796 {
797 name: "app_eng",
798 isEng: true,
799 expectedFlags: "--debug",
800 },
801 {
802 name: "app_release_eng",
803 isEng: true,
804 dxFlags: "--release",
805 // Eng mode does *not* override explicit dxflags.
806 expectedFlags: "--release",
807 },
Jared Duke70b85422025-01-28 19:13:39 +0000808 {
809 name: "app_d8",
810 useD8: true,
811 // D8 usage w/ apps should explicitly enable --release mode.
812 expectedFlags: "--release",
813 },
814 {
815 name: "app_d8_debug",
816 useD8: true,
817 dxFlags: "--debug",
818 // D8 usage w/ apps respects overriding dxFlags.
819 expectedFlags: "--debug",
820 },
Jared Duked32e85f2024-09-25 23:54:30 +0000821 }
822
823 for _, tc := range testcases {
824 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800825 t.Parallel()
Jared Duked32e85f2024-09-25 23:54:30 +0000826 fixturePreparer := PrepareForTestWithJavaDefaultModules
827 fixturePreparer = android.GroupFixturePreparers(
828 fixturePreparer,
829 android.FixtureModifyProductVariables(
830 func(variables android.FixtureProductVariables) {
831 variables.Eng = proptools.BoolPtr(tc.isEng)
832 },
833 ),
834 )
835 if tc.envVar != "" {
836 fixturePreparer = android.GroupFixturePreparers(
837 fixturePreparer,
838 android.FixtureMergeEnv(map[string]string{
839 tc.envVar: "true",
840 }),
841 )
842 }
Jared Duke70b85422025-01-28 19:13:39 +0000843 result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, strconv.FormatBool(!tc.useD8), tc.dxFlags))
Jared Duked32e85f2024-09-25 23:54:30 +0000844
Jared Duke70b85422025-01-28 19:13:39 +0000845 dexRuleKey := "r8"
846 if tc.useD8 {
847 dexRuleKey = "d8"
848 }
849 dexFlagsKey := dexRuleKey + "Flags"
850 appDex := result.ModuleForTests("app", "android_common").Rule(dexRuleKey)
851 android.AssertStringDoesContain(t, "expected flag in dex flags",
852 appDex.Args[dexFlagsKey], tc.expectedFlags)
Jared Duked32e85f2024-09-25 23:54:30 +0000853
854 var unexpectedFlags string
855 if tc.expectedFlags == "--debug" {
856 unexpectedFlags = "--release"
857 } else if tc.expectedFlags == "--release" {
858 unexpectedFlags = "--debug"
859 }
860 if unexpectedFlags != "" {
Jared Duke70b85422025-01-28 19:13:39 +0000861 android.AssertStringDoesNotContain(t, "unexpected flag in dex flags",
862 appDex.Args[dexFlagsKey], unexpectedFlags)
Jared Duked32e85f2024-09-25 23:54:30 +0000863 }
864 })
865 }
866}