1// Copyright 2017 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 "reflect" 19 "testing" 20 21 "android/soong/android" 22 "android/soong/bazel/cquery" 23) 24 25func TestLibraryReuse(t *testing.T) { 26 t.Parallel() 27 t.Run("simple", func(t *testing.T) { 28 ctx := testCc(t, ` 29 cc_library { 30 name: "libfoo", 31 srcs: ["foo.c", "baz.o"], 32 }`) 33 34 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 35 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 36 37 if len(libfooShared.Inputs) != 2 { 38 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 39 } 40 41 if len(libfooStatic.Inputs) != 2 { 42 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 43 } 44 45 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] { 46 t.Errorf("static object not reused for shared library") 47 } 48 if libfooShared.Inputs[1] != libfooStatic.Inputs[1] { 49 t.Errorf("static object not reused for shared library") 50 } 51 }) 52 53 t.Run("extra static source", func(t *testing.T) { 54 ctx := testCc(t, ` 55 cc_library { 56 name: "libfoo", 57 srcs: ["foo.c"], 58 static: { 59 srcs: ["bar.c"] 60 }, 61 }`) 62 63 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 64 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 65 66 if len(libfooShared.Inputs) != 1 { 67 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 68 } 69 70 if len(libfooStatic.Inputs) != 2 { 71 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 72 } 73 74 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] { 75 t.Errorf("static object not reused for shared library") 76 } 77 }) 78 79 t.Run("extra shared source", func(t *testing.T) { 80 ctx := testCc(t, ` 81 cc_library { 82 name: "libfoo", 83 srcs: ["foo.c"], 84 shared: { 85 srcs: ["bar.c"] 86 }, 87 }`) 88 89 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 90 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 91 92 if len(libfooShared.Inputs) != 2 { 93 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 94 } 95 96 if len(libfooStatic.Inputs) != 1 { 97 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 98 } 99 100 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] { 101 t.Errorf("static object not reused for shared library") 102 } 103 }) 104 105 t.Run("extra static cflags", func(t *testing.T) { 106 ctx := testCc(t, ` 107 cc_library { 108 name: "libfoo", 109 srcs: ["foo.c"], 110 static: { 111 cflags: ["-DFOO"], 112 }, 113 }`) 114 115 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 116 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 117 118 if len(libfooShared.Inputs) != 1 { 119 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 120 } 121 122 if len(libfooStatic.Inputs) != 1 { 123 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 124 } 125 126 if libfooShared.Inputs[0] == libfooStatic.Inputs[0] { 127 t.Errorf("static object reused for shared library when it shouldn't be") 128 } 129 }) 130 131 t.Run("extra shared cflags", func(t *testing.T) { 132 ctx := testCc(t, ` 133 cc_library { 134 name: "libfoo", 135 srcs: ["foo.c"], 136 shared: { 137 cflags: ["-DFOO"], 138 }, 139 }`) 140 141 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 142 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 143 144 if len(libfooShared.Inputs) != 1 { 145 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 146 } 147 148 if len(libfooStatic.Inputs) != 1 { 149 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 150 } 151 152 if libfooShared.Inputs[0] == libfooStatic.Inputs[0] { 153 t.Errorf("static object reused for shared library when it shouldn't be") 154 } 155 }) 156 157 t.Run("global cflags for reused generated sources", func(t *testing.T) { 158 ctx := testCc(t, ` 159 cc_library { 160 name: "libfoo", 161 srcs: [ 162 "foo.c", 163 "a.proto", 164 ], 165 shared: { 166 srcs: [ 167 "bar.c", 168 ], 169 }, 170 }`) 171 172 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 173 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 174 175 if len(libfooShared.Inputs) != 3 { 176 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 177 } 178 179 if len(libfooStatic.Inputs) != 2 { 180 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 181 } 182 183 if !reflect.DeepEqual(libfooShared.Inputs[0:2].Strings(), libfooStatic.Inputs.Strings()) { 184 t.Errorf("static objects not reused for shared library") 185 } 186 187 libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module) 188 if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.Local.CFlags) { 189 t.Errorf("missing protobuf cflags") 190 } 191 }) 192} 193 194func TestStubsVersions(t *testing.T) { 195 t.Parallel() 196 bp := ` 197 cc_library { 198 name: "libfoo", 199 srcs: ["foo.c"], 200 stubs: { 201 versions: ["29", "R", "current"], 202 }, 203 } 204 ` 205 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 206 config.TestProductVariables.Platform_version_active_codenames = []string{"R"} 207 ctx := testCcWithConfig(t, config) 208 209 variants := ctx.ModuleVariantsForTests("libfoo") 210 for _, expectedVer := range []string{"29", "R", "current"} { 211 expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer 212 if !inList(expectedVariant, variants) { 213 t.Errorf("missing expected variant: %q", expectedVariant) 214 } 215 } 216} 217 218func TestStubsVersions_NotSorted(t *testing.T) { 219 t.Parallel() 220 bp := ` 221 cc_library { 222 name: "libfoo", 223 srcs: ["foo.c"], 224 stubs: { 225 versions: ["29", "current", "R"], 226 }, 227 } 228 ` 229 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 230 config.TestProductVariables.Platform_version_active_codenames = []string{"R"} 231 testCcErrorWithConfig(t, `"libfoo" .*: versions: not sorted`, config) 232} 233 234func TestStubsVersions_ParseError(t *testing.T) { 235 t.Parallel() 236 bp := ` 237 cc_library { 238 name: "libfoo", 239 srcs: ["foo.c"], 240 stubs: { 241 versions: ["29", "current", "X"], 242 }, 243 } 244 ` 245 246 testCcError(t, `"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`, bp) 247} 248 249func TestCcLibraryWithBazel(t *testing.T) { 250 t.Parallel() 251 bp := ` 252cc_library { 253 name: "foo", 254 srcs: ["foo.cc"], 255 bazel_module: { label: "//foo/bar:bar" }, 256}` 257 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 258 config.BazelContext = android.MockBazelContext{ 259 OutputBaseDir: "outputbase", 260 LabelToCcInfo: map[string]cquery.CcInfo{ 261 "//foo/bar:bar": cquery.CcInfo{ 262 CcObjectFiles: []string{"foo.o"}, 263 Includes: []string{"include"}, 264 SystemIncludes: []string{"system_include"}, 265 Headers: []string{"foo.h"}, 266 RootDynamicLibraries: []string{"foo.so"}, 267 UnstrippedOutput: "foo_unstripped.so", 268 }, 269 "//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{ 270 CcObjectFiles: []string{"foo.o"}, 271 Includes: []string{"include"}, 272 SystemIncludes: []string{"system_include"}, 273 Headers: []string{"foo.h"}, 274 RootStaticArchives: []string{"foo.a"}, 275 }, 276 }, 277 } 278 ctx := testCcWithConfig(t, config) 279 280 staticFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module() 281 outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("") 282 if err != nil { 283 t.Errorf("Unexpected error getting cc_object outputfiles %s", err) 284 } 285 286 expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.a"} 287 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) 288 289 flagExporter := ctx.ModuleProvider(staticFoo, FlagExporterInfoProvider).(FlagExporterInfo) 290 android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs) 291 android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs) 292 android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders) 293 android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps) 294 295 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module() 296 outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("") 297 if err != nil { 298 t.Errorf("Unexpected error getting cc_library outputfiles %s", err) 299 } 300 expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"} 301 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) 302 303 android.AssertStringEquals(t, "unstripped shared library", "outputbase/execroot/__main__/foo_unstripped.so", sharedFoo.(*Module).linker.unstrippedOutputFilePath().String()) 304 flagExporter = ctx.ModuleProvider(sharedFoo, FlagExporterInfoProvider).(FlagExporterInfo) 305 android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs) 306 android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs) 307 android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders) 308 android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps) 309} 310 311func TestCcLibraryWithBazelValidations(t *testing.T) { 312 t.Parallel() 313 bp := ` 314cc_library { 315 name: "foo", 316 srcs: ["foo.cc"], 317 bazel_module: { label: "//foo/bar:bar" }, 318 tidy: true, 319}` 320 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 321 config.BazelContext = android.MockBazelContext{ 322 OutputBaseDir: "outputbase", 323 LabelToCcInfo: map[string]cquery.CcInfo{ 324 "//foo/bar:bar": cquery.CcInfo{ 325 CcObjectFiles: []string{"foo.o"}, 326 Includes: []string{"include"}, 327 SystemIncludes: []string{"system_include"}, 328 Headers: []string{"foo.h"}, 329 RootDynamicLibraries: []string{"foo.so"}, 330 UnstrippedOutput: "foo_unstripped.so", 331 }, 332 "//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{ 333 CcObjectFiles: []string{"foo.o"}, 334 Includes: []string{"include"}, 335 SystemIncludes: []string{"system_include"}, 336 Headers: []string{"foo.h"}, 337 RootStaticArchives: []string{"foo.a"}, 338 TidyFiles: []string{"foo.c.tidy"}, 339 }, 340 }, 341 } 342 ctx := android.GroupFixturePreparers( 343 prepareForCcTest, 344 android.FixtureMergeEnv(map[string]string{ 345 "ALLOW_LOCAL_TIDY_TRUE": "1", 346 }), 347 ).RunTestWithConfig(t, config).TestContext 348 349 staticFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module() 350 outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("") 351 if err != nil { 352 t.Errorf("Unexpected error getting cc_object outputfiles %s", err) 353 } 354 355 expectedOutputFiles := []string{"out/soong/.intermediates/foo/android_arm_armv7-a-neon_static/validated/foo.a"} 356 android.AssertPathsRelativeToTopEquals(t, "output files", expectedOutputFiles, outputFiles) 357 358 flagExporter := ctx.ModuleProvider(staticFoo, FlagExporterInfoProvider).(FlagExporterInfo) 359 android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs) 360 android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs) 361 android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders) 362 android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps) 363 364 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module() 365 outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("") 366 if err != nil { 367 t.Errorf("Unexpected error getting cc_library outputfiles %s", err) 368 } 369 expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"} 370 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) 371 372 android.AssertStringEquals(t, "unstripped shared library", "outputbase/execroot/__main__/foo_unstripped.so", sharedFoo.(*Module).linker.unstrippedOutputFilePath().String()) 373 flagExporter = ctx.ModuleProvider(sharedFoo, FlagExporterInfoProvider).(FlagExporterInfo) 374 android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs) 375 android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs) 376 android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders) 377 android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps) 378} 379 380func TestLibraryVersionScript(t *testing.T) { 381 t.Parallel() 382 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, ` 383 cc_library { 384 name: "libfoo", 385 srcs: ["foo.c"], 386 version_script: "foo.map.txt", 387 }`) 388 389 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld") 390 391 android.AssertStringListContains(t, "missing dependency on version_script", 392 libfoo.Implicits.Strings(), "foo.map.txt") 393 android.AssertStringDoesContain(t, "missing flag for version_script", 394 libfoo.Args["ldFlags"], "-Wl,--version-script,foo.map.txt") 395 396} 397 398func TestLibraryDynamicList(t *testing.T) { 399 t.Parallel() 400 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, ` 401 cc_library { 402 name: "libfoo", 403 srcs: ["foo.c"], 404 dynamic_list: "foo.dynamic.txt", 405 }`) 406 407 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld") 408 409 android.AssertStringListContains(t, "missing dependency on dynamic_list", 410 libfoo.Implicits.Strings(), "foo.dynamic.txt") 411 android.AssertStringDoesContain(t, "missing flag for dynamic_list", 412 libfoo.Args["ldFlags"], "-Wl,--dynamic-list,foo.dynamic.txt") 413 414} 415 416func TestCcLibrarySharedWithBazelValidations(t *testing.T) { 417 t.Parallel() 418 bp := ` 419cc_library_shared { 420 name: "foo", 421 srcs: ["foo.cc"], 422 bazel_module: { label: "//foo/bar:bar" }, 423 tidy: true, 424}` 425 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 426 config.BazelContext = android.MockBazelContext{ 427 OutputBaseDir: "outputbase", 428 LabelToCcInfo: map[string]cquery.CcInfo{ 429 "//foo/bar:bar": cquery.CcInfo{ 430 CcObjectFiles: []string{"foo.o"}, 431 Includes: []string{"include"}, 432 SystemIncludes: []string{"system_include"}, 433 RootDynamicLibraries: []string{"foo.so"}, 434 TocFile: "foo.so.toc", 435 TidyFiles: []string{"foo.c.tidy"}, 436 }, 437 }, 438 } 439 ctx := android.GroupFixturePreparers( 440 prepareForCcTest, 441 android.FixtureMergeEnv(map[string]string{ 442 "ALLOW_LOCAL_TIDY_TRUE": "1", 443 }), 444 ).RunTestWithConfig(t, config).TestContext 445 446 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module() 447 producer := sharedFoo.(android.OutputFileProducer) 448 outputFiles, err := producer.OutputFiles("") 449 if err != nil { 450 t.Errorf("Unexpected error getting cc_object outputfiles %s", err) 451 } 452 expectedOutputFiles := []string{"out/soong/.intermediates/foo/android_arm_armv7-a-neon_shared/validated/foo.so"} 453 android.AssertPathsRelativeToTopEquals(t, "output files", expectedOutputFiles, outputFiles) 454 455 tocFilePath := sharedFoo.(*Module).Toc() 456 if !tocFilePath.Valid() { 457 t.Errorf("Invalid tocFilePath: %s", tocFilePath) 458 } 459 tocFile := tocFilePath.Path() 460 expectedToc := "outputbase/execroot/__main__/foo.so.toc" 461 android.AssertStringEquals(t, "toc file", expectedToc, tocFile.String()) 462 463 entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0] 464 expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"} 465 gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"] 466 android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags) 467 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 468} 469 470func TestCcLibrarySharedWithBazel(t *testing.T) { 471 t.Parallel() 472 bp := ` 473cc_library_shared { 474 name: "foo", 475 srcs: ["foo.cc"], 476 bazel_module: { label: "//foo/bar:bar" }, 477}` 478 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 479 config.BazelContext = android.MockBazelContext{ 480 OutputBaseDir: "outputbase", 481 LabelToCcInfo: map[string]cquery.CcInfo{ 482 "//foo/bar:bar": cquery.CcInfo{ 483 CcObjectFiles: []string{"foo.o"}, 484 Includes: []string{"include"}, 485 SystemIncludes: []string{"system_include"}, 486 RootDynamicLibraries: []string{"foo.so"}, 487 TocFile: "foo.so.toc", 488 }, 489 }, 490 } 491 ctx := testCcWithConfig(t, config) 492 493 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module() 494 producer := sharedFoo.(android.OutputFileProducer) 495 outputFiles, err := producer.OutputFiles("") 496 if err != nil { 497 t.Errorf("Unexpected error getting cc_object outputfiles %s", err) 498 } 499 expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"} 500 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) 501 502 tocFilePath := sharedFoo.(*Module).Toc() 503 if !tocFilePath.Valid() { 504 t.Errorf("Invalid tocFilePath: %s", tocFilePath) 505 } 506 tocFile := tocFilePath.Path() 507 expectedToc := "outputbase/execroot/__main__/foo.so.toc" 508 android.AssertStringEquals(t, "toc file", expectedToc, tocFile.String()) 509 510 entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0] 511 expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"} 512 gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"] 513 android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags) 514 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 515} 516 517func TestWholeStaticLibPrebuilts(t *testing.T) { 518 t.Parallel() 519 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, ` 520 cc_prebuilt_library_static { 521 name: "libprebuilt", 522 srcs: ["foo.a"], 523 } 524 525 cc_library_static { 526 name: "libdirect", 527 whole_static_libs: ["libprebuilt"], 528 } 529 530 cc_library_static { 531 name: "libtransitive", 532 whole_static_libs: ["libdirect"], 533 } 534 535 cc_library_static { 536 name: "libdirect_with_srcs", 537 srcs: ["bar.c"], 538 whole_static_libs: ["libprebuilt"], 539 } 540 541 cc_library_static { 542 name: "libtransitive_with_srcs", 543 srcs: ["baz.c"], 544 whole_static_libs: ["libdirect_with_srcs"], 545 } 546 `) 547 548 libdirect := result.ModuleForTests("libdirect", "android_arm64_armv8-a_static").Rule("arWithLibs") 549 libtransitive := result.ModuleForTests("libtransitive", "android_arm64_armv8-a_static").Rule("arWithLibs") 550 551 libdirectWithSrcs := result.ModuleForTests("libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs") 552 libtransitiveWithSrcs := result.ModuleForTests("libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs") 553 554 barObj := result.ModuleForTests("libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("cc") 555 bazObj := result.ModuleForTests("libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("cc") 556 557 android.AssertStringListContains(t, "missing dependency on foo.a", 558 libdirect.Inputs.Strings(), "foo.a") 559 android.AssertStringDoesContain(t, "missing flag for foo.a", 560 libdirect.Args["arLibs"], "foo.a") 561 562 android.AssertStringListContains(t, "missing dependency on foo.a", 563 libtransitive.Inputs.Strings(), "foo.a") 564 android.AssertStringDoesContain(t, "missing flag for foo.a", 565 libtransitive.Args["arLibs"], "foo.a") 566 567 android.AssertStringListContains(t, "missing dependency on foo.a", 568 libdirectWithSrcs.Inputs.Strings(), "foo.a") 569 android.AssertStringDoesContain(t, "missing flag for foo.a", 570 libdirectWithSrcs.Args["arLibs"], "foo.a") 571 android.AssertStringListContains(t, "missing dependency on bar.o", 572 libdirectWithSrcs.Inputs.Strings(), barObj.Output.String()) 573 android.AssertStringDoesContain(t, "missing flag for bar.o", 574 libdirectWithSrcs.Args["arObjs"], barObj.Output.String()) 575 576 android.AssertStringListContains(t, "missing dependency on foo.a", 577 libtransitiveWithSrcs.Inputs.Strings(), "foo.a") 578 android.AssertStringDoesContain(t, "missing flag for foo.a", 579 libtransitiveWithSrcs.Args["arLibs"], "foo.a") 580 581 android.AssertStringListContains(t, "missing dependency on bar.o", 582 libtransitiveWithSrcs.Inputs.Strings(), barObj.Output.String()) 583 android.AssertStringDoesContain(t, "missing flag for bar.o", 584 libtransitiveWithSrcs.Args["arObjs"], barObj.Output.String()) 585 586 android.AssertStringListContains(t, "missing dependency on baz.o", 587 libtransitiveWithSrcs.Inputs.Strings(), bazObj.Output.String()) 588 android.AssertStringDoesContain(t, "missing flag for baz.o", 589 libtransitiveWithSrcs.Args["arObjs"], bazObj.Output.String()) 590} 591