Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/cc/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 18 kB image not shown  

Quelle  prebuilt_test.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2019 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cc

import (
 "fmt"
 "runtime"
 "testing"

 "android/soong/android"
)

var prepareForPrebuiltTest = android.GroupFixturePreparers(
 prepareForCcTest,
 android.PrepareForTestWithAndroidMk,
)

func testPrebuilt(t *testing.T, bp string, fs android.MockFS, handlers ...android.FixturePreparer) *android.TestContext {
 t.Helper()
 result := android.GroupFixturePreparers(
  prepareForPrebuiltTest,
  fs.AddToFixture(),
  android.GroupFixturePreparers(handlers...),
 ).RunTestWithBp(t, bp)

 return result.TestContext
}

type configCustomizer func(config android.Config)

func TestPrebuilt(t *testing.T) {
 bp := `
  cc_library {
   name: "liba",
   split_all_variants: true,
  }

  cc_prebuilt_library_shared {
   name: "liba",
   srcs: ["liba.so"],
   prefer: true,
  }

  cc_library {
   name: "libb",
  }

  cc_prebuilt_library_static {
   name: "libb",
   srcs: ["libb.a"],
   prefer: true,
  }

  cc_library_shared {
   name: "libd",
  }

  cc_prebuilt_library_shared {
   name: "libd",
   srcs: ["libd.so"],
  }

  cc_library_static {
   name: "libe",
  }

  cc_prebuilt_library_static {
   name: "libe",
   srcs: ["libe.a"],
  }

  cc_library {
   name: "libf",
   split_all_variants: true,
  }

  cc_prebuilt_library {
   name: "libf",
   static: {
    srcs: ["libf.a"],
   },
   shared: {
    srcs: ["libf.so"],
   },
  }

  cc_object {
   name: "crtx",
  }

  cc_prebuilt_object {
   name: "crtx",
   srcs: ["crtx.o"],
  }
 `

 ctx := testPrebuilt(t, bp, map[string][]byte{
  "liba.so": nil,
  "libb.a":  nil,
  "libd.so": nil,
  "libe.a":  nil,
  "libf.a":  nil,
  "libf.so": nil,
  "crtx.o":  nil,
 })

 // Verify that all the modules exist and that their dependencies were connected correctly
 liba := ctx.ModuleForTests(t, "liba", "android_arm64_armv8-a_shared").Module()
 libb := ctx.ModuleForTests(t, "libb", "android_arm64_armv8-a_static").Module()
 libd := ctx.ModuleForTests(t, "libd", "android_arm64_armv8-a_shared").Module()
 libe := ctx.ModuleForTests(t, "libe", "android_arm64_armv8-a_static").Module()
 libfStatic := ctx.ModuleForTests(t, "libf", "android_arm64_armv8-a_static").Module()
 libfShared := ctx.ModuleForTests(t, "libf", "android_arm64_armv8-a_shared").Module()
 crtx := ctx.ModuleForTests(t, "crtx", "android_arm64_armv8-a").Module()

 prebuiltLiba := ctx.ModuleForTests(t, "prebuilt_liba", "android_arm64_armv8-a_shared").Module()
 prebuiltLibb := ctx.ModuleForTests(t, "prebuilt_libb", "android_arm64_armv8-a_static").Module()
 prebuiltLibd := ctx.ModuleForTests(t, "prebuilt_libd", "android_arm64_armv8-a_shared").Module()
 prebuiltLibe := ctx.ModuleForTests(t, "prebuilt_libe", "android_arm64_armv8-a_static").Module()
 prebuiltLibfStatic := ctx.ModuleForTests(t, "prebuilt_libf", "android_arm64_armv8-a_static").Module()
 prebuiltLibfShared := ctx.ModuleForTests(t, "prebuilt_libf", "android_arm64_armv8-a_shared").Module()
 prebuiltCrtx := ctx.ModuleForTests(t, "prebuilt_crtx", "android_arm64_armv8-a").Module()

 if !android.HasDirectDep(ctx, liba, prebuiltLiba) {
  t.Errorf("liba missing dependency on prebuilt_liba")
 }

 if !android.HasDirectDep(ctx, libb, prebuiltLibb) {
  t.Errorf("libb missing dependency on prebuilt_libb")
 }

 if !android.HasDirectDep(ctx, libd, prebuiltLibd) {
  t.Errorf("libd missing dependency on prebuilt_libd")
 }

 if !android.HasDirectDep(ctx, libe, prebuiltLibe) {
  t.Errorf("libe missing dependency on prebuilt_libe")
 }

 if !android.HasDirectDep(ctx, libfStatic, prebuiltLibfStatic) {
  t.Errorf("libf static missing dependency on prebuilt_libf")
 }

 if !android.HasDirectDep(ctx, libfShared, prebuiltLibfShared) {
  t.Errorf("libf shared missing dependency on prebuilt_libf")
 }

 if !android.HasDirectDep(ctx, crtx, prebuiltCrtx) {
  t.Errorf("crtx missing dependency on prebuilt_crtx")
 }

 entries := android.AndroidMkInfoForTest(t, ctx, prebuiltLiba).PrimaryInfo
 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_prebuilt_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
 entries = android.AndroidMkInfoForTest(t, ctx, prebuiltLibb).PrimaryInfo
 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_prebuilt_library_static", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}

func TestPrebuiltLibraryShared(t *testing.T) {
 ctx := testPrebuilt(t, `
 cc_prebuilt_library_shared {
  name: "libtest",
  srcs: ["libf.so"],
  split_all_variants: true,
    strip: {
        none: true,
    },
 }
 `, map[string][]byte{
  "libf.so": nil,
 })

 shared := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared").Module().(*Module)
 assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
}

func TestPrebuiltLibraryStatic(t *testing.T) {
 ctx := testPrebuilt(t, `
 cc_prebuilt_library_static {
  name: "libtest",
  srcs: ["libf.a"],
 }
 `, map[string][]byte{
  "libf.a": nil,
 })

 static := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static").Module().(*Module)
 assertString(t, static.OutputFile().Path().Base(), "libf.a")
}

func TestPrebuiltLibrary(t *testing.T) {
 ctx := testPrebuilt(t, `
 cc_prebuilt_library {
  name: "libtest",
  static: {
   srcs: ["libf.a"],
  },
  shared: {
   srcs: ["libf.so"],
  },
  split_all_variants: true,
    strip: {
        none: true,
    },
 }
 `, map[string][]byte{
  "libf.a":  nil,
  "libf.so": nil,
 })

 shared := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared").Module().(*Module)
 assertString(t, shared.OutputFile().Path().Base(), "libtest.so")

 static := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static").Module().(*Module)
 assertString(t, static.OutputFile().Path().Base(), "libf.a")
}

func TestPrebuiltLibraryStem(t *testing.T) {
 ctx := testPrebuilt(t, `
 cc_prebuilt_library {
  name: "libfoo",
  stem: "libbar",
  static: {
   srcs: ["libfoo.a"],
  },
  shared: {
   srcs: ["libfoo.so"],
  },
  strip: {
   none: true,
  },
  split_all_variants: true,
 }
 `, map[string][]byte{
  "libfoo.a":  nil,
  "libfoo.so": nil,
 })

 static := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static").Module().(*Module)
 assertString(t, static.OutputFile().Path().Base(), "libfoo.a")

 shared := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
 assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
}

func TestPrebuiltLibrarySharedStem(t *testing.T) {
 ctx := testPrebuilt(t, `
 cc_prebuilt_library_shared {
  name: "libfoo",
  stem: "libbar",
  srcs: ["libfoo.so"],
  strip: {
   none: true,
  },
  split_all_variants: true,
 }
 `, map[string][]byte{
  "libfoo.so": nil,
 })

 shared := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
 assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
}

func TestPrebuiltHostBinary(t *testing.T) {
 if runtime.GOOS != "linux" {
  t.Skipf("Skipping host prebuilt testing that is only supported on linux not %s", runtime.GOOS)
 }

 ctx := testPrebuilt(t, `
 cc_prebuilt_library_shared {
  name: "libfoo",
  device_supported: false,
  host_supported: true,
  target: {
   linux_glibc_x86_64: {
    srcs: ["linux_glibc_x86_64/lib64/libfoo.so"],
   },
  },
 }

 cc_prebuilt_binary {
  name: "foo",
  device_supported: false,
  host_supported: true,
  shared_libs: ["libfoo"],
  target: {
   linux_glibc_x86_64: {
    srcs: ["linux_glibc_x86_64/bin/foo"],
   },
  },
 }
 `, map[string][]byte{
  "libfoo.so": nil,
  "foo":       nil,
 })

 fooRule := ctx.ModuleForTests(t, "foo", "linux_glibc_x86_64").Rule("CpExecutable")
 assertString(t, fooRule.Output.String(), "out/soong/.intermediates/foo/linux_glibc_x86_64/foo")
 assertString(t, fooRule.Input.String(), "linux_glibc_x86_64/bin/foo")
}

func TestPrebuiltLibrarySanitized(t *testing.T) {
 bp := `cc_prebuilt_library {
 name: "libtest",
  static: {
                        sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, },
  },
  shared: {
                        sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, },
  },
  split_all_variants: true,
 }
 cc_prebuilt_library_static {
  name: "libtest_static",
                sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, },
  split_all_variants: true,
 }
 cc_prebuilt_library_shared {
  name: "libtest_shared",
                sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, },
  split_all_variants: true,
 }`

 fs := map[string][]byte{
  "libf.a":         nil,
  "libf.hwasan.a":  nil,
  "libf.so":        nil,
  "hwasan/libf.so": nil,
 }

 // Without SANITIZE_TARGET.
 ctx := testPrebuilt(t, bp, fs)

 shared_rule := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
 assertString(t, shared_rule.Input.String(), "libf.so")

 static := ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static").Module().(*Module)
 assertString(t, static.OutputFile().Path().Base(), "libf.a")

 shared_rule2 := ctx.ModuleForTests(t, "libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
 assertString(t, shared_rule2.Input.String(), "libf.so")

 static2 := ctx.ModuleForTests(t, "libtest_static", "android_arm64_armv8-a_static").Module().(*Module)
 assertString(t, static2.OutputFile().Path().Base(), "libf.a")

 // With SANITIZE_TARGET=hwaddress
 ctx = testPrebuilt(t, bp, fs,
  android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
   variables.SanitizeDevice = []string{"hwaddress"}
  }),
 )

 shared_rule = ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
 assertString(t, shared_rule.Input.String(), "hwasan/libf.so")

 static = ctx.ModuleForTests(t, "libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
 assertString(t, static.OutputFile().Path().Base(), "libf.hwasan.a")

 shared_rule2 = ctx.ModuleForTests(t, "libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
 assertString(t, shared_rule2.Input.String(), "hwasan/libf.so")

 static2 = ctx.ModuleForTests(t, "libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
 assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a")
}

func TestPrebuiltBinaryNoSrcsNoError(t *testing.T) {
 const bp = `
cc_prebuilt_binary {
 name: "bintest",
 srcs: [],
}`
 ctx := testPrebuilt(t, bp, map[string][]byte{})
 mod := ctx.ModuleForTests(t, "bintest", "android_arm64_armv8-a").Module().(*Module)
 android.AssertBoolEquals(t, `expected no srcs to yield no output file`, false, mod.OutputFile().Valid())
}

func TestPrebuiltBinaryMultipleSrcs(t *testing.T) {
 const bp = `
cc_prebuilt_binary {
 name: "bintest",
 srcs: ["foo", "bar"],
}`
 testCcError(t, `Android.bp:4:6: module "bintest" variant "android_arm64_armv8-a": srcs: multiple prebuilt source files`, bp)
}

func TestMultiplePrebuilts(t *testing.T) {
 bp := `
  // an rdep
  cc_library {
   name: "libfoo",
   shared_libs: ["libbar"],
   split_all_variants: true,
  }

  // multiple variations of dep
  // source
  cc_library {
   name: "libbar",
   split_all_variants: true,
  }
  // prebuilt "v1"
  cc_prebuilt_library_shared {
   name: "libbar",
   srcs: ["libbar.so"],
  }
  // prebuilt "v2"
  cc_prebuilt_library_shared {
   name: "libbar.v2",
   stem: "libbar",
   source_module_name: "libbar",
   srcs: ["libbar.so"],
  }

  // selectors
  apex_contributions {
   name: "myapex_contributions",
   contents: ["%v"],
  }
  all_apex_contributions {name: "all_apex_contributions"}
 `
 testCases := []struct {
  desc                   string
  selectedDependencyName string
  expectedDependencyName string
 }{
  {
   desc:                   "Source library is selected using apex_contributions",
   selectedDependencyName: "libbar",
   expectedDependencyName: "libbar",
  },
  {
   desc:                   "Prebuilt library v1 is selected using apex_contributions",
   selectedDependencyName: "prebuilt_libbar",
   expectedDependencyName: "prebuilt_libbar",
  },
  {
   desc:                   "Prebuilt library v2 is selected using apex_contributions",
   selectedDependencyName: "prebuilt_libbar.v2",
   expectedDependencyName: "prebuilt_libbar.v2",
  },
 }

 for _, tc := range testCases {
  preparer := android.GroupFixturePreparers(
   android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
    android.RegisterApexContributionsBuildComponents(ctx)
   }),
   android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
  )
  ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{
   "libbar.so": nil,
   "crtx.o":    nil,
  }, preparer)
  libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
  expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
  android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, android.HasDirectDep(ctx, libfoo, expectedDependency))
  // check that LOCAL_SHARED_LIBRARIES contains libbar and not libbar.v<N>
  entries := android.AndroidMkInfoForTest(t, ctx, libfoo).PrimaryInfo
  android.AssertStringListContains(t, "Version should not be present in LOCAL_SHARED_LIBRARIES", entries.EntryMap["LOCAL_SHARED_LIBRARIES"], "libbar")

  // check installation rules
  // the selected soong module should be exported to make
  libbar := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
  android.AssertBoolEquals(t, fmt.Sprintf("dependency %s should be exported to make\n", expectedDependency), true, !libbar.IsHideFromMake())

  // check LOCAL_MODULE of the selected module name
  // the prebuilt should have the same LOCAL_MODULE when exported to make
  entries = android.AndroidMkInfoForTest(t, ctx, libbar).PrimaryInfo
  android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0])
 }
}

// Setting prefer on multiple prebuilts is an error, unless one of them is also listed in apex_contributions
func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) {
 bp := `
  // an rdep
  cc_library {
   name: "libfoo",
   shared_libs: ["libbar"],
  }

  // multiple variations of dep
  // source
  cc_library {
   name: "libbar",
  }
  // prebuilt "v1"
  cc_prebuilt_library_shared {
   name: "libbar",
   srcs: ["libbar.so"],
   prefer: true,
  }
  // prebuilt "v2"
  cc_prebuilt_library_shared {
   name: "libbar.v2",
   stem: "libbar",
   source_module_name: "libbar",
   srcs: ["libbar.so"],
   prefer: true,
  }

  // selectors
  apex_contributions {
   name: "myapex_contributions",
   contents: [%v],
  }
  all_apex_contributions {name: "all_apex_contributions"}
 `

 testCases := []struct {
  desc                   string
  selectedDependencyName string
  expectedDependencyName string
  expectedErr            string
 }{
  {
   desc:        "Multiple prebuilts have prefer: true",
   expectedErr: "Multiple prebuilt modules prebuilt_libbar and prebuilt_libbar.v2 have been marked as preferred for this source module",
  },
  {
   desc:                   "Multiple prebuilts have prefer: true. The prebuilt listed in apex_contributions wins.",
   selectedDependencyName: `"prebuilt_libbar"`,
   expectedDependencyName: "prebuilt_libbar",
  },
 }

 for _, tc := range testCases {
  preparer := android.GroupFixturePreparers(
   android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
    android.RegisterApexContributionsBuildComponents(ctx)
   }),
   android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
  )
  if tc.expectedErr != "" {
   preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedErr))
  }

  ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{
   "libbar.so": nil,
   "crtx.o":    nil,
  }, preparer)
  if tc.expectedErr != "" {
   return // the fixture will assert that the excepted err has been raised
  }
  libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
  expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
  android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName),
   true, android.HasDirectDep(ctx, libfoo, expectedDependency))
 }
}

// If module sdk cannot provide a cc module variant (e.g. static), then the module variant from source should be used
func TestMissingVariantInModuleSdk(t *testing.T) {
 bp := `
  // an rdep
  cc_library {
   name: "libfoo",
   static_libs: ["libbar"],
   split_all_variants: true,
  }

  // source
  cc_library {
   name: "libbar",
  }
  // prebuilt
  // libbar only exists as a shared library
  cc_prebuilt_library_shared {
   name: "libbar",
   srcs: ["libbar.so"],
  }
  // selectors
  apex_contributions {
   name: "myapex_contributions",
   contents: ["prebuilt_libbar"],
  }
  all_apex_contributions {name: "all_apex_contributions"}
 `

 preparer := android.GroupFixturePreparers(
  android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
   android.RegisterApexContributionsBuildComponents(ctx)
  }),
  android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
 )
 ctx := testPrebuilt(t, bp, map[string][]byte{
  "libbar.so": nil,
  "crtx.o":    nil,
 }, preparer)
 libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module()
 sourceLibBar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_static").Module()
 // Even though the prebuilt is listed in apex_contributions, the prebuilt does not have a static variant.
 // Therefore source of libbar should be used.
 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true,
  android.HasDirectDep(ctx, libfoo, sourceLibBar))
}

[Dauer der Verarbeitung: 0.22 Sekunden, vorverarbeitet 2026-06-28]