Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  library_test.go   Sprache: unbekannt

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

// Copyright 2019 The Android Open Source Project
//
// 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 rust

import (
 "strings"
 "testing"

 "android/soong/android"
)

// Test that variants are being generated correctly, and that crate-types are correct.
func TestLibraryVariants(t *testing.T) {

 ctx := testRust(t, `
  rust_library {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
   split_all_variants: true,
  }
  rust_ffi {
   name: "libfoo.ffi",
   srcs: ["foo.rs"],
   crate_name: "foo",
   split_all_variants: true,
  }
  rust_ffi_static {
   name: "libfoo.ffi_static",
   srcs: ["foo.rs"],
   crate_name: "foo"
  }`)

 // Test all variants are being built.
 libfooRlib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")
 libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc")
 libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")
 libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_shared").Rule("rustc")

 rlibCrateType := "rlib"
 dylibCrateType := "dylib"
 sharedCrateType := "cdylib"

 // Test crate type for rlib is correct.
 if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
  t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.Args["rustcFlags"])
 }

 // Test crate type for dylib is correct.
 if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type="+dylibCrateType) {
  t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.Args["rustcFlags"])
 }

 // Test crate type for FFI rlibs is correct
 if !strings.Contains(libfooFFIRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
  t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooFFIRlib.Args["rustcFlags"])
 }

 // Test crate type for C shared libraries is correct.
 if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
  t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
 }

}

// Test that dylibs are not statically linking the standard library.
func TestDylibPreferDynamic(t *testing.T) {
 ctx := testRust(t, `
  rust_library_dylib {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
  }`)

 libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc")

 if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
  t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
 }
}

func TestValidateLibraryStem(t *testing.T) {
 testRustError(t, "crate_name must be defined.", `
   rust_library_host {
    name: "libfoo",
    srcs: ["foo.rs"],
   }`)

 testRustError(t, "library crate_names must be alphanumeric with underscores allowed", `
   rust_library_host {
    name: "libfoo-bar",
    srcs: ["foo.rs"],
    crate_name: "foo-bar"
   }`)

 testRustError(t, "Invalid name or stem property; library filenames must start with lib<crate_name>", `
   rust_library_host {
    name: "foobar",
    srcs: ["foo.rs"],
    crate_name: "foo_bar"
   }`)
 testRustError(t, "Invalid name or stem property; library filenames must start with lib<crate_name>", `
   rust_library_host {
    name: "foobar",
    stem: "libfoo",
    srcs: ["foo.rs"],
    crate_name: "foo_bar"
   }`)
 testRustError(t, "Invalid name or stem property; library filenames must start with lib<crate_name>", `
   rust_library_host {
    name: "foobar",
    stem: "foo_bar",
    srcs: ["foo.rs"],
    crate_name: "foo_bar"
   }`)

}

func TestSharedLibrary(t *testing.T) {
 ctx := testRust(t, `
  rust_ffi_shared {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
  }`)

 libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared")

 libfooOutput := libfoo.Rule("rustc")
 if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
  t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v",
   libfooOutput.Args["linkFlags"])
 }

 if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkDylibs) {
  t.Errorf("Non-static libstd dylib expected to be a dependency of Rust shared libraries. Dylib deps are: %#v",
   libfoo.Module().(*Module).Properties.AndroidMkDylibs)
 }
}

func TestSharedLibraryToc(t *testing.T) {
 ctx := testRust(t, `
  rust_ffi_shared {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
  }
  cc_binary {
   name: "fizzbuzz",
   shared_libs: ["libfoo"],
  }`)

 fizzbuzz := ctx.ModuleForTests(t, "fizzbuzz", "android_arm64_armv8-a").Rule("ld")

 if !android.SuffixInList(fizzbuzz.Implicits.Strings(), "libfoo.so.toc") {
  t.Errorf("missing expected libfoo.so.toc implicit dependency, instead found: %#v",
   fizzbuzz.Implicits.Strings())
 }
}

func TestStaticLibraryLinkage(t *testing.T) {
 ctx := testRust(t, `
  rust_ffi_static {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
  }`)

 libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std")

 if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) {
  t.Errorf("Static libstd rlib expected to be a dependency of Rust rlib libraries. Rlib deps are: %#v",
   libfoo.Module().(*Module).Properties.AndroidMkDylibs)
 }
}

func TestNativeDependencyOfRlib(t *testing.T) {
 ctx := testRust(t, `
  rust_ffi_static {
   name: "libffi_static",
   crate_name: "ffi_static",
   rlibs: ["librust_rlib"],
   srcs: ["foo.rs"],
  }
  rust_library_rlib {
   name: "librust_rlib",
   crate_name: "rust_rlib",
   srcs: ["foo.rs"],
   shared_libs: ["libshared_cc_dep"],
   static_libs: ["libstatic_cc_dep"],
   split_all_variants: true,
  }
  cc_library_shared {
   name: "libshared_cc_dep",
   srcs: ["foo.cpp"],
  }
  cc_library_static {
   name: "libstatic_cc_dep",
   srcs: ["foo.cpp"],
  }
  `)

 rustRlibRlibStd := ctx.ModuleForTests(t, "librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
 rustRlibDylibStd := ctx.ModuleForTests(t, "librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
 ffiRlib := ctx.ModuleForTests(t, "libffi_static", "android_arm64_armv8-a_rlib_rlib-std")

 modules := []android.TestingModule{
  rustRlibRlibStd,
  rustRlibDylibStd,
  ffiRlib,
 }

 // librust_rlib specifies -L flag to cc deps output directory on rustc command
 // and re-export the cc deps to rdep libffi_static
 // When building rlib crate, rustc doesn't link the native libraries
 // The build system assumes the  cc deps will be at the final linkage (either a shared library or binary)
 // Hence, these flags are no-op
 // TODO: We could consider removing these flags
 for _, module := range modules {
  if !strings.Contains(module.Rule("rustc").Args["libFlags"],
   "-L out/soong/.intermediates/libshared_cc_dep/android_arm64_armv8-a_shared/") {
   t.Errorf(
    "missing -L flag for libshared_cc_dep of %s, rustcFlags: %#v",
    module.Module().Name(), rustRlibRlibStd.Rule("rustc").Args["libFlags"],
   )
  }
  if !strings.Contains(module.Rule("rustc").Args["libFlags"],
   "-L out/soong/.intermediates/libstatic_cc_dep/android_arm64_armv8-a_static/") {
   t.Errorf(
    "missing -L flag for libstatic_cc_dep of %s, rustcFlags: %#v",
    module.Module().Name(), rustRlibRlibStd.Rule("rustc").Args["libFlags"],
   )
  }
 }
}

// Test that variants pull in the right type of rustlib autodep
func TestAutoDeps(t *testing.T) {

 ctx := testRust(t, `
  rust_library {
   name: "libbar",
   srcs: ["bar.rs"],
   crate_name: "bar",
  }
  rust_library_rlib {
   name: "librlib_only",
   srcs: ["bar.rs"],
   crate_name: "rlib_only",
  }
  rust_library {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
   rustlibs: [
    "libbar",
    "librlib_only",
   ],
   split_all_variants: true,
  }
  rust_ffi {
   name: "libfoo.ffi",
   srcs: ["foo.rs"],
   crate_name: "foo",
   rustlibs: [
    "libbar",
    "librlib_only",
   ],
   split_all_variants: true,
  }
  rust_ffi_static {
   name: "libfoo.ffi.static",
   srcs: ["foo.rs"],
   crate_name: "foo",
   rustlibs: [
    "libbar",
    "librlib_only",
   ],
  }`)

 libfooRlib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std")
 libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib")
 libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_rlib_rlib-std")
 libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_shared")

 for _, static := range []android.TestingModule{libfooRlib, libfooFFIRlib} {
  if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) {
   t.Errorf("libbar not present as rlib dependency in static lib: %s", static.Module().Name())
  }
  if android.InList("libbar", static.Module().(*Module).Properties.AndroidMkDylibs) {
   t.Errorf("libbar present as dynamic dependency in static lib: %s", static.Module().Name())
  }
 }

 for _, dyn := range []android.TestingModule{libfooDylib, libfooShared} {
  if !android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkDylibs) {
   t.Errorf("libbar not present as dynamic dependency in dynamic lib: %s", dyn.Module().Name())
  }
  if android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
   t.Errorf("libbar present as rlib dependency in dynamic lib: %s", dyn.Module().Name())
  }
  if !android.InList("librlib_only", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
   t.Errorf("librlib_only should be selected by rustlibs as an rlib: %s.", dyn.Module().Name())
  }
 }
}

// Test that stripped versions are correctly generated and used.
func TestStrippedLibrary(t *testing.T) {
 ctx := testRust(t, `
  rust_library_dylib {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.rs"],
  }
  rust_library_dylib {
   name: "libbar",
   crate_name: "bar",
   srcs: ["foo.rs"],
   strip: {
    none: true
   }
  }
 `)

 foo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib")
 foo.Output("libfoo.dylib.so")
 foo.Output("unstripped/libfoo.dylib.so")
 // Check that the `cp` rule is using the stripped version as input.
 cp := foo.Rule("android.Cp")
 if strings.HasSuffix(cp.Input.String(), "unstripped/libfoo.dylib.so") {
  t.Errorf("installed library not based on stripped version: %v", cp.Input)
 }

 fizzBar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_dylib").MaybeOutput("unstripped/libbar.dylib.so")
 if fizzBar.Rule != nil {
  t.Errorf("unstripped library exists, so stripped library has incorrectly been generated")
 }
}

func TestLibstdLinkage(t *testing.T) {
 ctx := testRust(t, `
  rust_library {
   name: "libfoo",
   srcs: ["foo.rs"],
   crate_name: "foo",
   split_all_variants: true,
  }
  rust_ffi {
   name: "libbar",
   srcs: ["foo.rs"],
   crate_name: "bar",
   rustlibs: ["libfoo"],
   split_all_variants: true,
  }
  rust_ffi_static {
   name: "libbar_static",
   srcs: ["foo.rs"],
   crate_name: "bar",
   rustlibs: ["libfoo"],
  }
  rust_ffi {
   name: "libbar.prefer_rlib",
   srcs: ["foo.rs"],
   crate_name: "bar",
   rustlibs: ["libfoo"],
   prefer_rlib: true,
  }`)

 libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
 libfooRlibStatic := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
 libfooRlibDynamic := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)

 libbarShared := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_shared").Module().(*Module)
 libbarFFIRlib := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)

 // prefer_rlib works the same for both rust_library and rust_ffi, so a single check is sufficient here.
 libbarRlibStd := ctx.ModuleForTests(t, "libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module)

 if !android.InList("libstd", libfooRlibStatic.Properties.AndroidMkRlibs) {
  t.Errorf("rlib-std variant for device rust_library_rlib does not link libstd as an rlib")
 }
 if !android.InList("libstd", libfooRlibDynamic.Properties.AndroidMkDylibs) {
  t.Errorf("dylib-std variant for device rust_library_rlib does not link libstd as an dylib")
 }
 if !android.InList("libstd", libfooDylib.Properties.AndroidMkDylibs) {
  t.Errorf("Device rust_library_dylib does not link libstd as an dylib")
 }

 if !android.InList("libstd", libbarShared.Properties.AndroidMkDylibs) {
  t.Errorf("Device rust_ffi_shared does not link libstd as an dylib")
 }
 if !android.InList("libstd", libbarFFIRlib.Properties.AndroidMkRlibs) {
  t.Errorf("Device rust_ffi_static does not link libstd as an rlib")
 }
 if !android.InList("libfoo.rlib-std", libbarFFIRlib.Properties.AndroidMkRlibs) {
  t.Errorf("Device rust_ffi_static does not link dependent rustlib rlib-std variant")
 }
 if !android.InList("libstd", libbarRlibStd.Properties.AndroidMkRlibs) {
  t.Errorf("rust_ffi with prefer_rlib does not link libstd as an rlib")
 }

}

func TestRustFFIExportedIncludes(t *testing.T) {
 ctx := testRust(t, `
  rust_ffi {
   name: "libbar",
   srcs: ["foo.rs"],
   crate_name: "bar",
   export_include_dirs: ["rust_includes"],
   host_supported: true,
  }
  cc_library_static {
   name: "libfoo",
   srcs: ["foo.cpp"],
   shared_libs: ["libbar"],
   host_supported: true,
  }`)
 libfooStatic := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_static").Rule("cc")
 android.AssertStringDoesContain(t, "cFlags for lib module", libfooStatic.Args["cFlags"], " -Irust_includes ")
}

// Make sure cc_rustlibs_for_make has the expected behavior, and that
// cc_library_static does as well.
// This is here instead of cc/library_test.go because the test needs to
// define a rust_ffi module which can't be done in soong-cc to avoid the
// circular dependency.
func TestCCRustlibsForMake(t *testing.T) {
 result := testRust(t, `
  rust_ffi_static {
   name: "libbar",
   srcs: ["foo.rs"],
   crate_name: "bar",
   export_include_dirs: ["rust_includes"],
   host_supported: true,
  }

  cc_rustlibs_for_make {
   name: "libmakerustlibs",
   whole_static_libs: ["libbar"],
  }

  cc_library_static {
   name: "libccstatic",
   whole_static_libs: ["libbar"],
  }
 `)

 libmakerustlibs := result.ModuleForTests(t, "libmakerustlibs", "android_arm64_armv8-a_static").MaybeRule("rustc")
 libccstatic := result.ModuleForTests(t, "libccstatic", "android_arm64_armv8-a_static").MaybeRule("rustc")

 if libmakerustlibs.Output == nil {
  t.Errorf("cc_rustlibs_for_make is not generating a  Rust staticlib when it should")
 }

 if libccstatic.Output != nil {
  t.Errorf("cc_library_static is generating a Rust staticlib when it should not")
 }
}

func TestRustVersionScript(t *testing.T) {
 ctx := testRust(t, `
 rust_library {
  name: "librs",
  srcs: ["bar.rs"],
  crate_name: "rs",
  extra_exported_symbols: "librs.map.txt",
  split_all_variants: true,
 }
 rust_ffi {
  name: "libffi",
  srcs: ["foo.rs"],
  crate_name: "ffi",
  version_script: "libffi.map.txt",
 }
 `)

 //linkFlags
 librs := ctx.ModuleForTests(t, "librs", "android_arm64_armv8-a_dylib").Rule("rustc")
 libffi := ctx.ModuleForTests(t, "libffi", "android_arm64_armv8-a_shared").Rule("rustc")

 if !strings.Contains(librs.Args["linkFlags"], "-Wl,--version-script=librs.map.txt") {
  t.Errorf("missing expected -Wl,--version-script= linker flag for libextended shared lib, linkFlags: %#v",
   librs.Args["linkFlags"])
 }
 if strings.Contains(librs.Args["linkerScriptFlags"], "-Wl,--android-version-script=librs.map.txt") {
  t.Errorf("unexpected -Wl,--android-version-script= linker flag for libextended shared lib, linkFlags: %#v",
   librs.Args["linkerScriptFlags"])
 }

 if !strings.Contains(libffi.Args["linkerScriptFlags"], "-Wl,--android-version-script=libffi.map.txt") {
  t.Errorf("missing -Wl,--android-version-script= linker flag for libreplaced shared lib, linkFlags: %#v",
   libffi.Args["linkerScriptFlags"])
 }
 if strings.Contains(libffi.Args["linkFlags"], "-Wl,--version-script=libffi.map.txt") {
  t.Errorf("unexpected -Wl,--version-script= linker flag for libextended shared lib, linkFlags: %#v",
   libffi.Args["linkFlags"])
 }
}

func TestRustVersionScriptPropertyErrors(t *testing.T) {
 testRustError(t, "version_script: can only be set for rust_ffi modules", `
  rust_library {
   name: "librs",
   srcs: ["bar.rs"],
   crate_name: "rs",
   version_script: "libbar.map.txt",
   split_all_variants: true,
  }`)
 testRustError(t, "version_script and extra_exported_symbols", `
  rust_ffi {
   name: "librs",
   srcs: ["bar.rs"],
   crate_name: "rs",
   version_script: "libbar.map.txt",
   extra_exported_symbols: "libbar.map.txt",
   split_all_variants: true,
  }`)
}

func TestStubsVersions(t *testing.T) {
 t.Parallel()
 bp := `
  rust_ffi {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.rs"],
   stubs: {
    versions: ["29", "R", "current"],
   },
  }
 `
 ctx := android.GroupFixturePreparers(
  prepareForRustTest,
  android.PrepareForTestWithVisibility,
  rustMockedFiles.AddToFixture(),
  android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
   config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
  })).RunTestWithBp(t, bp)

 variants := ctx.ModuleVariantsForTests("libfoo")
 for _, expectedVer := range []string{"29", "R", "current"} {
  expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer
  if !android.InList(expectedVariant, variants) {
   t.Errorf("missing expected variant: %q", expectedVariant)
  }
 }
}

func TestStubsVersions_ParseError(t *testing.T) {
 t.Parallel()
 bp := `
 rust_ffi_shared {
  name: "libfoo",
  crate_name: "foo",
  srcs: ["foo.rs"],
   stubs: {
    versions: ["29", "current", "X"],
   },
  }
 `
 fixture := android.GroupFixturePreparers(
  prepareForRustTest,
  android.PrepareForTestWithVisibility,
  rustMockedFiles.AddToFixture(),

  android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
   config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
  }))

 fixture.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`)).RunTestWithBp(t, bp)
}

func TestVersionedStubs(t *testing.T) {
 t.Parallel()
 bp := `
 rust_ffi_shared {
  name: "libFoo",
  crate_name: "Foo",
  srcs: ["foo.rs"],
   stubs: {
    symbol_file: "foo.map.txt",
    versions: ["1", "2", "3"],
   },
  }

 cc_library_shared {
  name: "libBar",
  srcs: ["bar.c"],
  shared_libs: ["libFoo#1"],
 }

 rust_library {
  name: "libbar_rs",
  crate_name: "bar_rs",
  srcs: ["bar.rs"],
  shared_libs: ["libFoo#1"],
  split_all_variants: true,
 }
 rust_ffi {
  name: "libbar_ffi_rs",
  crate_name: "bar_ffi_rs",
  srcs: ["bar.rs"],
  shared_libs: ["libFoo#1"],
 }
 `

 ctx := android.GroupFixturePreparers(
  prepareForRustTest,
  android.PrepareForTestWithVisibility,
  rustMockedFiles.AddToFixture()).RunTestWithBp(t, bp)

 variants := ctx.ModuleVariantsForTests("libFoo")
 expectedVariants := []string{
  "android_arm64_armv8-a_shared",
  "android_arm64_armv8-a_shared_1",
  "android_arm64_armv8-a_shared_2",
  "android_arm64_armv8-a_shared_3",
  "android_arm64_armv8-a_shared_current",
  "android_arm_armv7-a-neon_shared",
  "android_arm_armv7-a-neon_shared_1",
  "android_arm_armv7-a-neon_shared_2",
  "android_arm_armv7-a-neon_shared_3",
  "android_arm_armv7-a-neon_shared_current",
 }
 variantsMismatch := false
 if len(variants) != len(expectedVariants) {
  variantsMismatch = true
 } else {
  for _, v := range expectedVariants {
   if !android.InList(v, variants) {
    variantsMismatch = false
   }
  }
 }
 if variantsMismatch {
  t.Errorf("variants of libFoo expected:\n")
  for _, v := range expectedVariants {
   t.Errorf("%q\n", v)
  }
  t.Errorf(", but got:\n")
  for _, v := range variants {
   t.Errorf("%q\n", v)
  }
 }

 libBarLinkRule := ctx.ModuleForTests(t, "libBar", "android_arm64_armv8-a_shared").Rule("ld")
 libBarFlags := libBarLinkRule.Args["libFlags"]

 libBarRsRustcRule := ctx.ModuleForTests(t, "libbar_rs", "android_arm64_armv8-a_dylib").Rule("rustc")
 libBarRsFlags := libBarRsRustcRule.Args["linkFlags"]

 libBarFfiRsRustcRule := ctx.ModuleForTests(t, "libbar_ffi_rs", "android_arm64_armv8-a_shared").Rule("rustc")
 libBarFfiRsFlags := libBarFfiRsRustcRule.Args["linkFlags"]

 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/unstripped/libFoo.so"
 if !strings.Contains(libBarFlags, libFoo1StubPath) {
  t.Errorf("%q is not found in %q", libFoo1StubPath, libBarFlags)
 }
 if !strings.Contains(libBarRsFlags, libFoo1StubPath) {
  t.Errorf("%q is not found in %q", libFoo1StubPath, libBarRsFlags)
 }
 if !strings.Contains(libBarFfiRsFlags, libFoo1StubPath) {
  t.Errorf("%q is not found in %q", libFoo1StubPath, libBarFfiRsFlags)
 }
}

func TestCheckConflictingExplicitVersions(t *testing.T) {
 t.Parallel()
 bp := `
 cc_library_shared {
  name: "libbar",
  srcs: ["bar.c"],
  shared_libs: ["libfoo", "libfoo#impl"],
 }

 rust_ffi_shared {
  name: "libfoo",
  crate_name: "foo",
  srcs: ["foo.rs"],
  stubs: {
   versions: ["29", "current"],
  },
 }
 `
 fixture := android.GroupFixturePreparers(
  prepareForRustTest,
  android.PrepareForTestWithVisibility,
  rustMockedFiles.AddToFixture())

 fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`duplicate shared libraries with different explicit versions`)).RunTestWithBp(t, bp)
}

func TestAddnoOverride64GlobalCflags(t *testing.T) {
 t.Parallel()
 bp := `
  cc_library_shared {
   name: "libclient",
   srcs: ["foo.c"],
   shared_libs: ["libfoo#1"],
  }

  rust_ffi_shared {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.c"],
   shared_libs: ["libbar"],
   stubs: {
    symbol_file: "foo.map.txt",
    versions: ["1", "2", "3"],
   },
  }

  cc_library_shared {
   name: "libbar",
   export_include_dirs: ["include/libbar"],
   srcs: ["foo.c"],
  }`
 ctx := android.GroupFixturePreparers(
  prepareForRustTest,
  android.PrepareForTestWithVisibility,
  rustMockedFiles.AddToFixture()).RunTestWithBp(t, bp)

 cFlags := ctx.ModuleForTests(t, "libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]

 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
  t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
 }
}

// Make sure the stubs properties can only be used in modules producing shared libs
func TestRustStubsFFIOnly(t *testing.T) {
 testRustError(t, "stubs properties", `
  rust_library {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.c"],
   shared_libs: ["libbar"],
   stubs: {
    symbol_file: "foo.map.txt",
   },
  }
 `)

 testRustError(t, "stubs properties", `
  rust_library {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.c"],
   shared_libs: ["libbar"],
   stubs: {
    versions: ["1"],
   },
  }
 `)

 testRustError(t, "stubs properties", `
  rust_ffi_static {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.c"],
   shared_libs: ["libbar"],
   stubs: {
    symbol_file: "foo.map.txt",
   },
  }
 `)
 testRustError(t, "stubs properties", `
  rust_ffi_static {
   name: "libfoo",
   crate_name: "foo",
   srcs: ["foo.c"],
   shared_libs: ["libbar"],
   stubs: {
    versions: ["1"],
   },
  }
 `)
}

// TODO: When rust_ffi libraries support export_*_lib_headers,
// add a test similar to cc.TestStubsLibReexportsHeaders

// Test that no_stdlibs libraries produce a rlib-core variant which is picked up by dependencies.
func TestNoStdLib(t *testing.T) {
 ctx := testRust(t, `
  rust_library_rlib {
   name: "libno_std",
   srcs: ["foo.rs"],
   crate_name: "no_std",
   no_stdlibs: true,
  }
  rust_library {
   name: "libstd_dep",
   srcs: ["foo.rs"],
   crate_name: "std_dep",
   rustlibs: ["libno_std"],
   prefer_rlib: true,
  }
  rust_library_rlib {
   name: "libnostd_dep",
   srcs: ["foo.rs"],
   crate_name: "nostd_dep",
   no_stdlibs: true,
   rustlibs: ["libno_std"],
   vendor_available: true,
  }
 `)

 // Test that only the rlib-core variant is created for libno_std
 variants := ctx.ModuleVariantsForTests("libno_std")
 if !android.InList("android_arm64_armv8-a_rlib_rlib-core", variants) {
  t.Errorf("missing expected variant: %q", "android_arm64_armv8-a_rlib_rlib-core")
 }
 if android.InList("android_arm64_armv8-a_rlib_rlib-std", variants) {
  t.Errorf("unexpected variant: %q", "android_arm64_armv8-a_rlib_rlib-std")
 }

 libstdDep := ctx.ModuleForTests(t, "libstd_dep", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
 if !android.InList("libno_std.rlib-core", libstdDep.Properties.AndroidMkRlibs) {
  t.Errorf("rlib-std variant for device rust_library does not link libno_std as an rlib-core variant")
  t.Errorf("All rlibs: %v", libstdDep.Properties.AndroidMkRlibs)
 }

 libnostdDep := ctx.ModuleForTests(t, "libnostd_dep", "android_arm64_armv8-a_rlib_rlib-core").Module().(*Module)
 if !android.InList("libno_std.rlib-core", libnostdDep.Properties.AndroidMkRlibs) {
  t.Errorf("rlib-core variant for device rust_library does not link libno_std as an rlib-core variant")
 }
}

func TestNoStdVariant(t *testing.T) {
 ctx := testRust(t, `
 rust_defaults {
  name: "no_std_override",
  arch: {
   arm64: {
    no_std: {
     flags: ["-C target-feature=-sve2"],
    }
   },
  },
 }
 rust_library_rlib {
  name: "libmaybe_std",
  defaults: ["no_std_override"],
  srcs: ["foo.rs"],
  crate_name: "maybe_std",
  no_std: {
   enabled: true,
  }
 }
 rust_library_rlib {
  name: "libno_std",
  srcs: ["foo.rs"],
  crate_name: "no_std",
  rustlibs: ["libmaybe_std"],
  no_stdlibs: true
 }
 rust_library_rlib {
  name: "libyes_std",
  srcs: ["foo.rs"],
  crate_name: "yes_std",
  rustlibs: ["libmaybe_std"],
 }
 `)
 variants := ctx.ModuleVariantsForTests("libmaybe_std")
 // We should have both a core linkage variant and a std linkage variant
 if !android.InList("android_arm64_armv8-a_rlib_rlib-core", variants) {
  t.Errorf("missing expected variant: %q", "android_arm64_armv8-a_rlib_rlib-core")
 }
 if !android.InList("android_arm64_armv8-a_rlib_rlib-std", variants) {
  t.Errorf("missing expected variant: %q", "android_arm64_armv8-a_rlib_rlib-std")
 }

 // The std variant should depend on std
 maybe_std_std := ctx.ModuleForTests(t, "libmaybe_std", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
 if !android.InList("libstd", maybe_std_std.Properties.AndroidMkRlibs) {
  t.Errorf("missing expected dependency on libstd")
 }
 // The nostd variant should not
 maybe_std_core := ctx.ModuleForTests(t, "libmaybe_std", "android_arm64_armv8-a_rlib_rlib-core").Module().(*Module)
 if android.InList("libstd", maybe_std_core.Properties.AndroidMkRlibs) {
  t.Errorf("unexpected dependency on libstd")
 }

 maybe_std_core_rustc := ctx.ModuleForTests(t, "libmaybe_std", "android_arm64_armv8-a_rlib_rlib-core").Rule("rustc")
 if !strings.Contains(maybe_std_core_rustc.Args["rustcFlags"], "-C target-feature=-sve2") {
  t.Errorf("Defaults did not correctly apply to no_std variant: %v", maybe_std_core_rustc.Args["rustcFlags"])
 }

 // The nostd library should select the nostd variant
 no_std := ctx.ModuleForTests(t, "libno_std", "android_arm64_armv8-a_rlib_rlib-core").Module().(*Module)
 if !android.InList("libmaybe_std.rlib-core", no_std.Properties.AndroidMkRlibs) {
  t.Errorf("missing expected dependency on libmaybe_std.rlib-core")
 }
 if android.InList("libmaybe_std.rlib-std", no_std.Properties.AndroidMkRlibs) {
  t.Errorf("unexpected dependency on libmaybe_std.rlib-std")
 }

 // The nostd library should select the nostd variant
 yes_std := ctx.ModuleForTests(t, "libyes_std", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
 if android.InList("libmaybe_std.rlib-core", yes_std.Properties.AndroidMkRlibs) {
  t.Errorf("unexpected dependency on libmaybe_std.rlib-core")
 }
 if !android.InList("libmaybe_std.rlib-std", yes_std.Properties.AndroidMkRlibs) {
  t.Errorf("missing expected dependency on libmaybe_std.rlib-std")
 }
}

// Test that feature and rustlib overrides are applied correctly.
func TestLibraryFeatureAndRustlibOverrides(t *testing.T) {
 ctx := testRust(t, `
  rust_library {
   name: "libfoo",
   srcs: ["foo.rs"],
   features: ["c"],
   crate_name: "foo",
   no_std: {
    enabled: true,
    features: [],
   },
   rlib: {
    features: ["a", "b"],
    rustlibs: ["libbar"],
   },
   split_all_variants: true,
  }
  rust_library {
   name: "libbar",
   srcs: ["bar.rs"],
   crate_name: "bar",
  }
 `)

 libfooRlib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")

 if !strings.Contains(libfooRlib.Args["rustcFlags"], "--cfg 'feature=\"a\"' --cfg 'feature=\"b\"'") {
  t.Errorf("missing expected features for rlib variant, rustcFlags: %#v", libfooRlib.Args["rustcFlags"])
 }
 if strings.Contains(libfooRlib.Args["rustcFlags"], "--cfg 'feature=\"c\"'") {
  t.Errorf("unexpected feature for rlib variant, rustcFlags: %#v", libfooRlib.Args["rustcFlags"])
 }

 if !strings.Contains(libfooRlib.Args["libFlags"], "--extern bar=out/soong/.intermediates/libbar/android_arm64_armv8-a_rlib_rlib-std/libbar.rlib") {
  t.Errorf("missing expected rustlibs for rlib variant, libFlags: %#v", libfooRlib.Args["libFlags"])
 }

 libfooNoStd := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-core").Rule("rustc")
 if strings.Contains(libfooNoStd.Args["rustcFlags"], "--cfg 'feature=\"c\"'") {
  t.Errorf("unexpected feature for no_std variant, rustcFlags: %#v", libfooRlib.Args["rustcFlags"])
 }
 if strings.Contains(libfooNoStd.Args["rustcFlags"], "--cfg 'feature=\"a\"'") {
  t.Errorf("unexpected feature for no_std variant, rustcFlags: %#v", libfooRlib.Args["rustcFlags"])
 }
}

// TODO once we can enforce that rlib-core does not depend on rlib-std or dylib-std, test it

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

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik