platform_build_soong/bp2build/cc_library_headers_conversion_test.go
Zi Wang 9f609db46a Add variant_prepend support for all the properties in bp2build
This is a follow up of aosp/2336916. All the properties that have
variant_prepend tag are supported in bp2build.

Bug: 261644490
Test: TH and modified tests with updated expected behaviors
Change-Id: I13bb5d4d8fcd38bf153fa9083c9c945aec2dfa19
2023-01-04 11:19:50 -08:00

478 lines
15 KiB
Go

// Copyright 2021 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 bp2build
import (
"testing"
"android/soong/android"
"android/soong/cc"
)
const (
// See cc/testing.go for more context
soongCcLibraryHeadersPreamble = `
cc_defaults {
name: "linux_bionic_supported",
}`
)
func TestCcLibraryHeadersLoadStatement(t *testing.T) {
testCases := []struct {
bazelTargets BazelTargets
expectedLoadStatements string
}{
{
bazelTargets: BazelTargets{
BazelTarget{
name: "cc_library_headers_target",
ruleClass: "cc_library_headers",
// Note: no bzlLoadLocation for native rules
},
},
expectedLoadStatements: ``,
},
}
for _, testCase := range testCases {
actual := testCase.bazelTargets.LoadStatements()
expected := testCase.expectedLoadStatements
if actual != expected {
t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
}
}
}
func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) {
cc.RegisterCCBuildComponents(ctx)
}
func runCcLibraryHeadersTestCase(t *testing.T, tc Bp2buildTestCase) {
t.Helper()
RunBp2BuildTestCase(t, registerCcLibraryHeadersModuleTypes, tc)
}
func TestCcLibraryHeadersSimple(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{
"lib-1/lib1a.h": "",
"lib-1/lib1b.h": "",
"lib-2/lib2a.h": "",
"lib-2/lib2b.h": "",
"dir-1/dir1a.h": "",
"dir-1/dir1b.h": "",
"dir-2/dir2a.h": "",
"dir-2/dir2b.h": "",
"arch_arm64_exported_include_dir/a.h": "",
"arch_x86_exported_include_dir/b.h": "",
"arch_x86_64_exported_include_dir/c.h": "",
},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
export_include_dirs: ["dir-1", "dir-2"],
header_libs: ["lib-1", "lib-2"],
arch: {
arm64: {
// We expect dir-1 headers to be dropped, because dir-1 is already in export_include_dirs
export_include_dirs: ["arch_arm64_exported_include_dir", "dir-1"],
},
x86: {
export_include_dirs: ["arch_x86_exported_include_dir"],
},
x86_64: {
export_include_dirs: ["arch_x86_64_exported_include_dir"],
},
},
sdk_version: "current",
min_sdk_version: "29",
// TODO: Also support export_header_lib_headers
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"export_includes": `select({
"//build/bazel/platforms/arch:arm64": ["arch_arm64_exported_include_dir"],
"//build/bazel/platforms/arch:x86": ["arch_x86_exported_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["arch_x86_64_exported_include_dir"],
"//conditions:default": [],
}) + [
"dir-1",
"dir-2",
]`,
"sdk_version": `"current"`,
"min_sdk_version": `"29"`,
}),
},
})
}
func TestCcApiHeaders(t *testing.T) {
fs := map[string]string{
"bar/Android.bp": `cc_library_headers { name: "bar_headers", }`,
}
bp := `
cc_library_headers {
name: "foo_headers",
export_include_dirs: ["dir1", "dir2"],
export_header_lib_headers: ["bar_headers"],
arch: {
arm: {
export_include_dirs: ["dir_arm"],
},
x86: {
export_include_dirs: ["dir_x86"],
},
},
target: {
android: {
export_include_dirs: ["dir1", "dir_android"],
},
windows: {
export_include_dirs: ["dir_windows"],
},
}
}
`
expectedBazelTargets := []string{
MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.arm", AttrNameToString{
"export_includes": `["dir_arm"]`,
"arch": `"arm"`,
}),
MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.x86", AttrNameToString{
"export_includes": `["dir_x86"]`,
"arch": `"x86"`,
}),
MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.androidos", AttrNameToString{
"export_includes": `["dir_android"]`, // common includes are deduped
}),
// Windows headers are not exported
MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution", AttrNameToString{
"export_includes": `[
"dir1",
"dir2",
]`,
"deps": `[
"//bar:bar_headers.contribution",
":foo_headers.contribution.arm",
":foo_headers.contribution.x86",
":foo_headers.contribution.androidos",
]`,
}),
}
RunApiBp2BuildTestCase(t, cc.RegisterLibraryHeadersBuildComponents, Bp2buildTestCase{
Blueprint: bp,
Description: "Header library contributions to API surfaces",
ExpectedBazelTargets: expectedBazelTargets,
Filesystem: fs,
})
}
// header_libs has "variant_prepend" tag. In bp2build output,
// variant info(select) should go before general info.
func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test with os-specific header_libs props",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryPreamble + `
cc_library_headers {
name: "android-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "base-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "darwin-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "linux-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "linux_bionic-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "windows-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "foo_headers",
header_libs: ["base-lib"],
export_header_lib_headers: ["base-lib"],
target: {
android: {
header_libs: ["android-lib"],
export_header_lib_headers: ["android-lib"],
},
darwin: {
header_libs: ["darwin-lib"],
export_header_lib_headers: ["darwin-lib"],
},
linux_bionic: {
header_libs: ["linux_bionic-lib"],
export_header_lib_headers: ["linux_bionic-lib"],
},
linux_glibc: {
header_libs: ["linux-lib"],
export_header_lib_headers: ["linux-lib"],
},
windows: {
header_libs: ["windows-lib"],
export_header_lib_headers: ["windows-lib"],
},
},
include_build_directory: false,
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `select({
"//build/bazel/platforms/os:android": [":android-lib"],
"//build/bazel/platforms/os:darwin": [":darwin-lib"],
"//build/bazel/platforms/os:linux_bionic": [":linux_bionic-lib"],
"//build/bazel/platforms/os:linux_glibc": [":linux-lib"],
"//build/bazel/platforms/os:windows": [":windows-lib"],
"//conditions:default": [],
}) + [":base-lib"]`,
}),
},
})
}
func TestCcLibraryHeadersOsSpecficHeaderLibsExportHeaderLibHeaders(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryPreamble + `
cc_library_headers {
name: "android-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "exported-lib",
bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "foo_headers",
target: {
android: {
header_libs: ["android-lib", "exported-lib"],
export_header_lib_headers: ["exported-lib"]
},
},
include_build_directory: false,
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `select({
"//build/bazel/platforms/os:android": [":exported-lib"],
"//conditions:default": [],
})`,
}),
},
})
}
func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryPreamble + `cc_library_headers {
name: "foo_headers",
export_system_include_dirs: [
"shared_include_dir",
],
target: {
android: {
export_system_include_dirs: [
"android_include_dir",
],
},
linux_glibc: {
export_system_include_dirs: [
"linux_include_dir",
],
},
darwin: {
export_system_include_dirs: [
"darwin_include_dir",
],
},
},
arch: {
arm: {
export_system_include_dirs: [
"arm_include_dir",
],
},
x86_64: {
export_system_include_dirs: [
"x86_64_include_dir",
],
},
},
include_build_directory: false,
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"export_system_includes": `select({
"//build/bazel/platforms/os:android": ["android_include_dir"],
"//build/bazel/platforms/os:darwin": ["darwin_include_dir"],
"//build/bazel/platforms/os:linux_glibc": ["linux_include_dir"],
"//conditions:default": [],
}) + select({
"//build/bazel/platforms/arch:arm": ["arm_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
"//conditions:default": [],
}) + ["shared_include_dir"]`,
}),
},
})
}
func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{
"lib-1/lib1a.h": "",
"lib-1/lib1b.h": "",
"lib-2/lib2a.h": "",
"lib-2/lib2b.h": "",
"dir-1/dir1a.h": "",
"dir-1/dir1b.h": "",
"dir-2/dir2a.h": "",
"dir-2/dir2b.h": "",
"arch_arm64_exported_include_dir/a.h": "",
"arch_x86_exported_include_dir/b.h": "",
"arch_x86_64_exported_include_dir/c.h": "",
},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "lib-1",
export_include_dirs: ["lib-1"],
no_libcrt: true,
include_build_directory: false,
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "lib-1", AttrNameToString{
"export_includes": `["lib-1"]`,
}),
},
})
}
func TestCcLibraryHeadersExportedStaticLibHeadersReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_static_lib_headers is reexported",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
export_static_lib_headers: ["foo_export"],
static_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
}),
},
})
}
func TestCcLibraryHeadersExportedSharedLibHeadersReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_shared_lib_headers is reexported",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
export_shared_lib_headers: ["foo_export"],
shared_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
}),
},
})
}
func TestCcLibraryHeadersExportedHeaderLibHeadersReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_header_lib_headers is reexported",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
export_header_lib_headers: ["foo_export"],
header_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
}),
},
})
}
func TestCcLibraryHeadersWholeStaticLibsReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers whole_static_libs is reexported",
ModuleTypeUnderTest: "cc_library_headers",
ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
Filesystem: map[string]string{},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
whole_static_libs: ["foo_export"],
bazel_module: { bp2build_available: true },
}
` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
}),
},
})
}