1// 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 cc 16 17import ( 18 "runtime" 19 "strings" 20 "testing" 21 22 "android/soong/android" 23 24 "github.com/google/blueprint" 25) 26 27type visitDirectDepsInterface interface { 28 VisitDirectDeps(blueprint.Module, func(dep blueprint.Module)) 29} 30 31func hasDirectDep(ctx visitDirectDepsInterface, m android.Module, wantDep android.Module) bool { 32 var found bool 33 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 34 if dep == wantDep { 35 found = true 36 } 37 }) 38 return found 39} 40 41func TestAfdoDeps(t *testing.T) { 42 t.Parallel() 43 bp := ` 44 cc_library_shared { 45 name: "libTest", 46 host_supported: true, 47 srcs: ["test.c"], 48 static_libs: ["libFoo"], 49 afdo: true, 50 lto: { 51 thin: true, 52 }, 53 } 54 55 cc_library_static { 56 name: "libFoo", 57 host_supported: true, 58 srcs: ["foo.c"], 59 static_libs: ["libBar"], 60 } 61 62 cc_library_static { 63 name: "libBar", 64 host_supported: true, 65 srcs: ["bar.c"], 66 } 67 ` 68 69 result := android.GroupFixturePreparers( 70 PrepareForTestWithFdoProfile, 71 prepareForCcTest, 72 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""), 73 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 74 variables.AfdoProfiles = []string{ 75 "libTest://afdo_profiles_package:libTest_afdo", 76 } 77 }), 78 android.MockFS{ 79 "afdo_profiles_package/Android.bp": []byte(` 80 fdo_profile { 81 name: "libTest_afdo", 82 arch: { 83 arm64: { 84 profile: "libTest.afdo", 85 }, 86 }, 87 } 88 `), 89 }.AddToFixture(), 90 ).RunTestWithBp(t, bp) 91 92 profileSampleCFlag := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo" 93 uniqueInternalLinkageNamesCFlag := "-funique-internal-linkage-names" 94 afdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=40" 95 noAfdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=5" 96 97 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared") 98 libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest") 99 libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest") 100 101 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps 102 cFlags := libTest.Rule("cc").Args["cFlags"] 103 if !strings.Contains(cFlags, profileSampleCFlag) { 104 t.Errorf("Expected 'libTest' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags) 105 } 106 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 107 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags) 108 } 109 110 ldFlags := libTest.Rule("ld").Args["ldFlags"] 111 if !strings.Contains(ldFlags, afdoLtoLdFlag) { 112 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in ldflags %q", afdoLtoLdFlag, ldFlags) 113 } 114 115 cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"] 116 if !strings.Contains(cFlags, profileSampleCFlag) { 117 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags) 118 } 119 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 120 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags) 121 } 122 123 cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"] 124 if !strings.Contains(cFlags, profileSampleCFlag) { 125 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags) 126 } 127 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 128 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags) 129 } 130 131 // Check dependency edge from afdo-enabled module to static deps 132 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) { 133 t.Errorf("libTest missing dependency on afdo variant of libFoo") 134 } 135 136 if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) { 137 t.Errorf("libTest missing dependency on afdo variant of libBar") 138 } 139 140 // Verify non-afdo variant exists and doesn't contain afdo 141 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static") 142 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static") 143 144 cFlags = libFoo.Rule("cc").Args["cFlags"] 145 if strings.Contains(cFlags, profileSampleCFlag) { 146 t.Errorf("Expected 'libFoo' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags) 147 } 148 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 149 t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags) 150 } 151 cFlags = libBar.Rule("cc").Args["cFlags"] 152 if strings.Contains(cFlags, profileSampleCFlag) { 153 t.Errorf("Expected 'libBar' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags) 154 } 155 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 156 t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags) 157 } 158 159 // Check dependency edges of static deps 160 if hasDirectDep(result, libTest.Module(), libFoo.Module()) { 161 t.Errorf("libTest should not depend on non-afdo variant of libFoo") 162 } 163 164 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { 165 t.Errorf("libFoo missing dependency on non-afdo variant of libBar") 166 } 167 168 // Verify that the arm variant does not have FDO since the fdo_profile module only has a profile for arm64 169 libTest32 := result.ModuleForTests("libTest", "android_arm_armv7-a-neon_shared") 170 libFooAfdoVariant32 := result.ModuleForTests("libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin") 171 libBarAfdoVariant32 := result.ModuleForTests("libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin") 172 173 cFlags = libTest32.Rule("cc").Args["cFlags"] 174 if strings.Contains(cFlags, profileSampleCFlag) { 175 t.Errorf("Expected arm32 'libTest' not to enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags) 176 } 177 178 // TODO(b/324141705): when the fdo_profile module doesn't provide a source file the dependencies don't get 179 // -funique-internal-linkage-names but the module does. 180 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 181 t.Errorf("Expected arm32 'libTest' to enable -funique-internal-linkage-names but did not find %q in cflags %q", 182 uniqueInternalLinkageNamesCFlag, cFlags) 183 } 184 185 ldFlags = libTest32.Rule("ld").Args["ldFlags"] 186 if !strings.Contains(ldFlags, noAfdoLtoLdFlag) { 187 t.Errorf("Expected arm32 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags) 188 } 189 if strings.Contains(ldFlags, afdoLtoLdFlag) { 190 t.Errorf("Expected arm32 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags) 191 } 192 193 // Check dependency edge from afdo-enabled module to static deps 194 if !hasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) { 195 t.Errorf("arm32 libTest missing dependency on afdo variant of libFoo") 196 } 197 198 if !hasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) { 199 t.Errorf("arm32 libTest missing dependency on afdo variant of libBar") 200 } 201 202 cFlags = libFooAfdoVariant32.Rule("cc").Args["cFlags"] 203 if strings.Contains(cFlags, profileSampleCFlag) { 204 t.Errorf("Expected arm32 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 205 } 206 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 207 t.Errorf("Expected arm32 'libFoo' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 208 } 209 cFlags = libBarAfdoVariant32.Rule("cc").Args["cFlags"] 210 if strings.Contains(cFlags, profileSampleCFlag) { 211 t.Errorf("Expected arm32 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 212 } 213 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 214 t.Errorf("Expected arm32 'libBar' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 215 } 216 217 // Verify that the host variants don't enable afdo 218 libTestHost := result.ModuleForTests("libTest", result.Config.BuildOSTarget.String()+"_shared") 219 libFooHost := result.ModuleForTests("libFoo", result.Config.BuildOSTarget.String()+"_static_lto-thin") 220 libBarHost := result.ModuleForTests("libBar", result.Config.BuildOSTarget.String()+"_static_lto-thin") 221 222 cFlags = libTestHost.Rule("cc").Args["cFlags"] 223 if strings.Contains(cFlags, profileSampleCFlag) { 224 t.Errorf("Expected host 'libTest' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags) 225 } 226 227 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 228 t.Errorf("Expected host 'libTest' to not enable afdo but found %q in cflags %q", 229 uniqueInternalLinkageNamesCFlag, cFlags) 230 } 231 232 if runtime.GOOS != "darwin" { 233 ldFlags := libTestHost.Rule("ld").Args["ldFlags"] 234 if !strings.Contains(ldFlags, noAfdoLtoLdFlag) { 235 t.Errorf("Expected host 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags) 236 } 237 if strings.Contains(ldFlags, afdoLtoLdFlag) { 238 t.Errorf("Expected host 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags) 239 } 240 } 241 242 // Check dependency edge from afdo-enabled module to static deps 243 if !hasDirectDep(result, libTestHost.Module(), libFooHost.Module()) { 244 t.Errorf("host libTest missing dependency on non-afdo variant of libFoo") 245 } 246 247 if !hasDirectDep(result, libFooHost.Module(), libBarHost.Module()) { 248 t.Errorf("host libTest missing dependency on non-afdo variant of libBar") 249 } 250 251 cFlags = libFooHost.Rule("cc").Args["cFlags"] 252 if strings.Contains(cFlags, profileSampleCFlag) { 253 t.Errorf("Expected host 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 254 } 255 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 256 t.Errorf("Expected host 'libFoo' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 257 } 258 cFlags = libBarHost.Rule("cc").Args["cFlags"] 259 if strings.Contains(cFlags, profileSampleCFlag) { 260 t.Errorf("Expected host 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 261 } 262 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { 263 t.Errorf("Expected host 'libBar' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) 264 } 265} 266 267func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) { 268 t.Parallel() 269 bp := ` 270 cc_library_shared { 271 name: "libTest", 272 srcs: ["foo.c"], 273 static_libs: ["libFoo"], 274 } 275 276 cc_library_static { 277 name: "libFoo", 278 srcs: ["foo.c"], 279 static_libs: ["libBar"], 280 afdo: true, // TODO(b/256670524): remove support for enabling afdo from static only libraries, this can only propagate from shared libraries/binaries 281 } 282 283 cc_library_static { 284 name: "libBar", 285 } 286 ` 287 288 result := android.GroupFixturePreparers( 289 prepareForCcTest, 290 PrepareForTestWithFdoProfile, 291 android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libFoo.afdo", ""), 292 android.MockFS{ 293 "afdo_profiles_package/Android.bp": []byte(` 294 soong_namespace { 295 } 296 fdo_profile { 297 name: "libFoo_afdo", 298 profile: "libFoo.afdo", 299 } 300 `), 301 }.AddToFixture(), 302 ).RunTestWithBp(t, bp) 303 304 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module() 305 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static") 306 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module() 307 308 if !hasDirectDep(result, libTest, libFoo.Module()) { 309 t.Errorf("libTest missing dependency on non-afdo variant of libFoo") 310 } 311 312 if !hasDirectDep(result, libFoo.Module(), libBar) { 313 t.Errorf("libFoo missing dependency on non-afdo variant of libBar") 314 } 315 316 fooVariants := result.ModuleVariantsForTests("foo") 317 for _, v := range fooVariants { 318 if strings.Contains(v, "afdo-") { 319 t.Errorf("Expected no afdo variant of 'foo', got %q", v) 320 } 321 } 322 323 cFlags := libFoo.Rule("cc").Args["cFlags"] 324 if w := "-fprofile-sample-accurate"; strings.Contains(cFlags, w) { 325 t.Errorf("Expected 'foo' to not enable afdo, but found %q in cflags %q", w, cFlags) 326 } 327 328 barVariants := result.ModuleVariantsForTests("bar") 329 for _, v := range barVariants { 330 if strings.Contains(v, "afdo-") { 331 t.Errorf("Expected no afdo variant of 'bar', got %q", v) 332 } 333 } 334} 335 336func TestAfdoEnabledWithRuntimeDepNoAfdo(t *testing.T) { 337 bp := ` 338 cc_library { 339 name: "libTest", 340 srcs: ["foo.c"], 341 runtime_libs: ["libFoo"], 342 afdo: true, 343 } 344 345 cc_library { 346 name: "libFoo", 347 } 348 ` 349 350 result := android.GroupFixturePreparers( 351 prepareForCcTest, 352 PrepareForTestWithFdoProfile, 353 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""), 354 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 355 variables.AfdoProfiles = []string{ 356 "libTest://afdo_profiles_package:libTest_afdo", 357 } 358 }), 359 android.MockFS{ 360 "afdo_profiles_package/Android.bp": []byte(` 361 fdo_profile { 362 name: "libTest_afdo", 363 profile: "libTest.afdo", 364 } 365 `), 366 }.AddToFixture(), 367 ).RunTestWithBp(t, bp) 368 369 libFooVariants := result.ModuleVariantsForTests("libFoo") 370 for _, v := range libFooVariants { 371 if strings.Contains(v, "afdo-") { 372 t.Errorf("Expected no afdo variant of 'foo', got %q", v) 373 } 374 } 375} 376 377func TestAfdoEnabledWithMultiArchs(t *testing.T) { 378 bp := ` 379 cc_library_shared { 380 name: "foo", 381 srcs: ["test.c"], 382 afdo: true, 383 compile_multilib: "both", 384 } 385` 386 result := android.GroupFixturePreparers( 387 PrepareForTestWithFdoProfile, 388 prepareForCcTest, 389 android.FixtureAddTextFile("afdo_profiles_package/foo_arm.afdo", ""), 390 android.FixtureAddTextFile("afdo_profiles_package/foo_arm64.afdo", ""), 391 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 392 variables.AfdoProfiles = []string{ 393 "foo://afdo_profiles_package:foo_afdo", 394 } 395 }), 396 android.MockFS{ 397 "afdo_profiles_package/Android.bp": []byte(` 398 soong_namespace { 399 } 400 fdo_profile { 401 name: "foo_afdo", 402 arch: { 403 arm: { 404 profile: "foo_arm.afdo", 405 }, 406 arm64: { 407 profile: "foo_arm64.afdo", 408 } 409 } 410 } 411 `), 412 }.AddToFixture(), 413 ).RunTestWithBp(t, bp) 414 415 fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared") 416 fooArmCFlags := fooArm.Rule("cc").Args["cFlags"] 417 if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm.afdo"; !strings.Contains(fooArmCFlags, w) { 418 t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArmCFlags) 419 } 420 421 fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a_shared") 422 fooArm64CFlags := fooArm64.Rule("cc").Args["cFlags"] 423 if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm64.afdo"; !strings.Contains(fooArm64CFlags, w) { 424 t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArm64CFlags) 425 } 426} 427 428func TestMultipleAfdoRDeps(t *testing.T) { 429 t.Parallel() 430 bp := ` 431 cc_library_shared { 432 name: "libTest", 433 srcs: ["test.c"], 434 static_libs: ["libFoo"], 435 afdo: true, 436 } 437 438 cc_library_shared { 439 name: "libBar", 440 srcs: ["bar.c"], 441 static_libs: ["libFoo"], 442 afdo: true, 443 } 444 445 cc_library_static { 446 name: "libFoo", 447 srcs: ["foo.c"], 448 } 449 ` 450 451 result := android.GroupFixturePreparers( 452 PrepareForTestWithFdoProfile, 453 prepareForCcTest, 454 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""), 455 android.FixtureAddTextFile("afdo_profiles_package/libBar.afdo", ""), 456 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 457 variables.AfdoProfiles = []string{ 458 "libTest://afdo_profiles_package:libTest_afdo", 459 "libBar://afdo_profiles_package:libBar_afdo", 460 } 461 }), 462 android.MockFS{ 463 "afdo_profiles_package/Android.bp": []byte(` 464 fdo_profile { 465 name: "libTest_afdo", 466 profile: "libTest.afdo", 467 } 468 fdo_profile { 469 name: "libBar_afdo", 470 profile: "libBar.afdo", 471 } 472 `), 473 }.AddToFixture(), 474 ).RunTestWithBp(t, bp) 475 476 expectedCFlagLibTest := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo" 477 expectedCFlagLibBar := "-fprofile-sample-use=afdo_profiles_package/libBar.afdo" 478 479 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared") 480 libFooAfdoVariantWithLibTest := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest") 481 482 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_shared") 483 libFooAfdoVariantWithLibBar := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libBar") 484 485 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps 486 cFlags := libTest.Rule("cc").Args["cFlags"] 487 if !strings.Contains(cFlags, expectedCFlagLibTest) { 488 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags) 489 } 490 cFlags = libBar.Rule("cc").Args["cFlags"] 491 if !strings.Contains(cFlags, expectedCFlagLibBar) { 492 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags) 493 } 494 495 cFlags = libFooAfdoVariantWithLibTest.Rule("cc").Args["cFlags"] 496 if !strings.Contains(cFlags, expectedCFlagLibTest) { 497 t.Errorf("Expected 'libFooAfdoVariantWithLibTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags) 498 } 499 500 cFlags = libFooAfdoVariantWithLibBar.Rule("cc").Args["cFlags"] 501 if !strings.Contains(cFlags, expectedCFlagLibBar) { 502 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags) 503 } 504 505 // Check dependency edges of static deps 506 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariantWithLibTest.Module()) { 507 t.Errorf("libTest missing dependency on afdo variant of libFoo") 508 } 509 510 if !hasDirectDep(result, libBar.Module(), libFooAfdoVariantWithLibBar.Module()) { 511 t.Errorf("libFoo missing dependency on non-afdo variant of libBar") 512 } 513} 514 515func TestAfdoDepsWithoutProfile(t *testing.T) { 516 t.Parallel() 517 bp := ` 518 cc_library_shared { 519 name: "libTest", 520 srcs: ["test.c"], 521 static_libs: ["libFoo"], 522 afdo: true, 523 } 524 525 cc_library_static { 526 name: "libFoo", 527 srcs: ["foo.c"], 528 static_libs: ["libBar"], 529 } 530 531 cc_library_static { 532 name: "libBar", 533 srcs: ["bar.c"], 534 } 535 ` 536 537 result := android.GroupFixturePreparers( 538 PrepareForTestWithFdoProfile, 539 prepareForCcTest, 540 ).RunTestWithBp(t, bp) 541 542 // Even without a profile path, the afdo enabled libraries should be built with 543 // -funique-internal-linkage-names. 544 expectedCFlag := "-funique-internal-linkage-names" 545 546 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared") 547 libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest") 548 libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest") 549 550 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps 551 cFlags := libTest.Rule("cc").Args["cFlags"] 552 if !strings.Contains(cFlags, expectedCFlag) { 553 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) 554 } 555 556 cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"] 557 if !strings.Contains(cFlags, expectedCFlag) { 558 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) 559 } 560 561 cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"] 562 if !strings.Contains(cFlags, expectedCFlag) { 563 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) 564 } 565 // Check dependency edge from afdo-enabled module to static deps 566 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) { 567 t.Errorf("libTest missing dependency on afdo variant of libFoo") 568 } 569 570 if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) { 571 t.Errorf("libTest missing dependency on afdo variant of libBar") 572 } 573 574 // Verify non-afdo variant exists and doesn't contain afdo 575 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static") 576 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static") 577 578 cFlags = libFoo.Rule("cc").Args["cFlags"] 579 if strings.Contains(cFlags, expectedCFlag) { 580 t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags) 581 } 582 cFlags = libBar.Rule("cc").Args["cFlags"] 583 if strings.Contains(cFlags, expectedCFlag) { 584 t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags) 585 } 586 587 // Check dependency edges of static deps 588 if hasDirectDep(result, libTest.Module(), libFoo.Module()) { 589 t.Errorf("libTest should not depend on non-afdo variant of libFoo") 590 } 591 592 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { 593 t.Errorf("libFoo missing dependency on non-afdo variant of libBar") 594 } 595} 596