Merge "Make MockBazelContext more specific to cquerys"
diff --git a/android/bazel.go b/android/bazel.go
index b2170be..b54ae64 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -174,6 +174,18 @@
"liblinker_debuggerd_stub", // ruperts@, cc_library_static, depends on //system/libbase
"libbionic_tests_headers_posix", // ruperts@, cc_library_static
"libc_dns", // ruperts@, cc_library_static
+
+ "note_memtag_heap_async", // jingwen@, b/185079815, features.h includes not found
+ "note_memtag_heap_sync", // jingwen@, b/185079815, features.h includes not found
+
+ // List of all full_cc_libraries in //bionic, with their immediate failures
+ "libc", // jingwen@, cc_library, depends on //external/gwp_asan
+ "libc_malloc_debug", // jingwen@, cc_library, fatal error: 'assert.h' file not found
+ "libc_malloc_hooks", // jingwen@, cc_library, fatal error: 'errno.h' file not found
+ "libdl", // jingwen@, cc_library, ld.lld: error: no input files
+ "libm", // jingwen@, cc_library, fatal error: 'freebsd-compat.h' file not found
+ "libseccomp_policy", // jingwen@, cc_library, fatal error: 'seccomp_policy.h' file not found
+ "libstdc++", // jingwen@, cc_library, depends on //external/gwp_asan
}
// Used for quicker lookups
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 7911632..97eec30 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -354,15 +354,20 @@
# This file is generated by soong_build. Do not edit.
local_repository(
name = "sourceroot",
- path = "%s",
+ path = "%[1]s",
)
local_repository(
name = "rules_cc",
- path = "%s/build/bazel/rules_cc",
+ path = "%[1]s/build/bazel/rules_cc",
+)
+
+local_repository(
+ name = "bazel_skylib",
+ path = "%[1]s/build/bazel/bazel_skylib",
)
`
- return []byte(fmt.Sprintf(formatString, context.workspaceDir, context.workspaceDir))
+ return []byte(fmt.Sprintf(formatString, context.workspaceDir))
}
func (context *bazelContext) mainBzlFileContents() []byte {
diff --git a/android/paths.go b/android/paths.go
index ba1ab11..37b04dd 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -421,6 +421,9 @@
// bazel-compatible labels. Properties passed as the paths or excludes argument must have been
// annotated with struct tag `android:"path"` so that dependencies on other modules will have
// already been handled by the path_properties mutator.
+//
+// With expanded globs, we can catch package boundaries problem instead of
+// silently failing to potentially missing files from Bazel's globs.
func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList {
return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
}
@@ -431,6 +434,9 @@
// passed as the paths or excludes argument must have been annotated with struct tag
// `android:"path"` so that dependencies on other modules will have already been handled by the
// path_properties mutator.
+//
+// With expanded globs, we can catch package boundaries problem instead of
+// silently failing to potentially missing files from Bazel's globs.
func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList {
excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil))
excluded := make([]string, 0, len(excludeLabels.Includes))
diff --git a/bazel/properties.go b/bazel/properties.go
index 148386f..4bb2391 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path/filepath"
"regexp"
"sort"
)
@@ -47,6 +48,57 @@
Excludes []Label
}
+// GlobsInDir returns a list of glob expressions for a list of extensions
+// (optionally recursive) within a directory.
+func GlobsInDir(dir string, recursive bool, extensions []string) []string {
+ globs := []string{}
+
+ globInfix := ""
+ if dir == "." {
+ if recursive {
+ // e.g "**/*.h"
+ globInfix = "**/"
+ } // else e.g. "*.h"
+ for _, ext := range extensions {
+ globs = append(globs, globInfix+"*"+ext)
+ }
+ } else {
+ if recursive {
+ // e.g. "foo/bar/**/*.h"
+ dir += "/**"
+ } // else e.g. "foo/bar/*.h"
+ for _, ext := range extensions {
+ globs = append(globs, dir+"/*"+ext)
+ }
+ }
+ return globs
+}
+
+// LooseHdrsGlobs returns the list of non-recursive header globs for each parent directory of
+// each source file in this LabelList's Includes.
+func (ll *LabelList) LooseHdrsGlobs(exts []string) []string {
+ var globs []string
+ for _, parentDir := range ll.uniqueParentDirectories() {
+ globs = append(globs,
+ GlobsInDir(parentDir, false, exts)...)
+ }
+ return globs
+}
+
+// uniqueParentDirectories returns a list of the unique parent directories for
+// all files in ll.Includes.
+func (ll *LabelList) uniqueParentDirectories() []string {
+ dirMap := map[string]bool{}
+ for _, label := range ll.Includes {
+ dirMap[filepath.Dir(label.Label)] = true
+ }
+ dirs := []string{}
+ for dir := range dirMap {
+ dirs = append(dirs, dir)
+ }
+ return dirs
+}
+
// Append appends the fields of other labelList to the corresponding fields of ll.
func (ll *LabelList) Append(other LabelList) {
if len(ll.Includes) > 0 || len(other.Includes) > 0 {
@@ -224,6 +276,26 @@
return LabelListAttribute{Value: UniqueBazelLabelList(value)}
}
+// Append appends all values, including os and arch specific ones, from another
+// LabelListAttribute to this LabelListAttribute.
+func (attrs *LabelListAttribute) Append(other LabelListAttribute) {
+ for arch := range PlatformArchMap {
+ this := attrs.GetValueForArch(arch)
+ that := other.GetValueForArch(arch)
+ this.Append(that)
+ attrs.SetValueForArch(arch, this)
+ }
+
+ for os := range PlatformOsMap {
+ this := attrs.GetValueForOS(os)
+ that := other.GetValueForOS(os)
+ this.Append(that)
+ attrs.SetValueForOS(os, this)
+ }
+
+ attrs.Value.Append(other.Value)
+}
+
// HasArchSpecificValues returns true if the attribute contains
// architecture-specific label_list values.
func (attrs LabelListAttribute) HasConfigurableValues() bool {
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index cc616f2..d2a8729 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -26,6 +26,7 @@
testSrcs: [
"build_conversion_test.go",
"bzl_conversion_test.go",
+ "cc_library_conversion_test.go",
"cc_library_headers_conversion_test.go",
"cc_library_static_conversion_test.go",
"cc_object_conversion_test.go",
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index dd14c7d..b7a2810 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -374,16 +374,9 @@
// value>)" to set the default value of unset attributes. In the cases
// where the bp2build converter didn't set the default value within the
// mutator when creating the BazelTargetModule, this would be a zero
- // value. For those cases, we return a non-surprising default value so
- // generated BUILD files are syntactically correct.
- switch propertyValue.Kind() {
- case reflect.Slice:
- return "[]", nil
- case reflect.Map:
- return "{}", nil
- default:
- return "", nil
- }
+ // value. For those cases, we return an empty string so we don't
+ // unnecessarily generate empty values.
+ return "", nil
}
var ret string
@@ -397,21 +390,38 @@
case reflect.Ptr:
return prettyPrint(propertyValue.Elem(), indent)
case reflect.Slice:
- ret = "[\n"
- for i := 0; i < propertyValue.Len(); i++ {
- indexedValue, err := prettyPrint(propertyValue.Index(i), indent+1)
+ if propertyValue.Len() == 0 {
+ return "", nil
+ }
+
+ if propertyValue.Len() == 1 {
+ // Single-line list for list with only 1 element
+ ret += "["
+ indexedValue, err := prettyPrint(propertyValue.Index(0), indent)
if err != nil {
return "", err
}
+ ret += indexedValue
+ ret += "]"
+ } else {
+ // otherwise, use a multiline list.
+ ret += "[\n"
+ for i := 0; i < propertyValue.Len(); i++ {
+ indexedValue, err := prettyPrint(propertyValue.Index(i), indent+1)
+ if err != nil {
+ return "", err
+ }
- if indexedValue != "" {
- ret += makeIndent(indent + 1)
- ret += indexedValue
- ret += ",\n"
+ if indexedValue != "" {
+ ret += makeIndent(indent + 1)
+ ret += indexedValue
+ ret += ",\n"
+ }
}
+ ret += makeIndent(indent)
+ ret += "]"
}
- ret += makeIndent(indent)
- ret += "]"
+
case reflect.Struct:
// Special cases where the bp2build sends additional information to the codegenerator
// by wrapping the attributes in a custom struct type.
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 49897b3..1ede442 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -27,9 +27,7 @@
expectedBazelTarget string
}{
{
- bp: `custom {
- name: "foo",
-}
+ bp: `custom { name: "foo" }
`,
expectedBazelTarget: `soong_module(
name = "foo",
@@ -85,9 +83,7 @@
soong_module_variant = "",
soong_module_deps = [
],
- required = [
- "bar",
- ],
+ required = ["bar"],
)`,
},
{
@@ -116,12 +112,10 @@
targets: ["goal_foo"],
tag: ".foo",
},
- dists: [
- {
- targets: ["goal_bar"],
- tag: ".bar",
- },
- ],
+ dists: [{
+ targets: ["goal_bar"],
+ tag: ".bar",
+ }],
}
`,
expectedBazelTarget: `soong_module(
@@ -133,18 +127,12 @@
],
dist = {
"tag": ".foo",
- "targets": [
- "goal_foo",
- ],
+ "targets": ["goal_foo"],
},
- dists = [
- {
- "tag": ".bar",
- "targets": [
- "goal_bar",
- ],
- },
- ],
+ dists = [{
+ "tag": ".bar",
+ "targets": ["goal_bar"],
+ }],
)`,
},
{
@@ -169,19 +157,13 @@
soong_module_variant = "",
soong_module_deps = [
],
- dists = [
- {
- "tag": ".tag",
- "targets": [
- "my_goal",
- ],
- },
- ],
+ dists = [{
+ "tag": ".tag",
+ "targets": ["my_goal"],
+ }],
owner = "custom_owner",
ramdisk = True,
- required = [
- "bar",
- ],
+ required = ["bar"],
target_required = [
"qux",
"bazqux",
@@ -553,9 +535,7 @@
}`,
expectedBazelTargets: []string{`filegroup(
name = "fg_foo",
- srcs = [
- "b",
- ],
+ srcs = ["b"],
)`,
},
},
@@ -625,7 +605,7 @@
bp: `filegroup {
name: "foobar",
srcs: [
- ":foo",
+ ":foo",
"c",
],
bazel_module: { bp2build_available: true },
@@ -671,25 +651,15 @@
`genrule(
name = "foo",
cmd = "$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "foo.in",
- ],
- tools = [
- ":foo.tool",
- ],
+ outs = ["foo.out"],
+ srcs = ["foo.in"],
+ tools = [":foo.tool"],
)`,
`genrule(
name = "foo.tool",
cmd = "cp $(SRCS) $(OUTS)",
- outs = [
- "foo_tool.out",
- ],
- srcs = [
- "foo_tool.in",
- ],
+ outs = ["foo_tool.out"],
+ srcs = ["foo_tool.in"],
)`,
},
},
@@ -718,15 +688,9 @@
expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "$(locations :foo.tools) -s $(OUTS) $(SRCS)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "foo.in",
- ],
- tools = [
- ":foo.tools",
- ],
+ outs = ["foo.out"],
+ srcs = ["foo.in"],
+ tools = [":foo.tools"],
)`,
`genrule(
name = "foo.tools",
@@ -735,9 +699,7 @@
"foo_tool.out",
"foo_tool2.out",
],
- srcs = [
- "foo_tool.in",
- ],
+ srcs = ["foo_tool.in"],
)`,
},
},
@@ -758,15 +720,9 @@
expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "foo.in",
- ],
- tools = [
- "//other:foo.tool",
- ],
+ outs = ["foo.out"],
+ srcs = ["foo.in"],
+ tools = ["//other:foo.tool"],
)`,
},
fs: otherGenruleBp,
@@ -788,15 +744,9 @@
expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "//other:other.tool",
- ],
- tools = [
- "//other:foo.tool",
- ],
+ outs = ["foo.out"],
+ srcs = ["//other:other.tool"],
+ tools = ["//other:foo.tool"],
)`,
},
fs: otherGenruleBp,
@@ -818,12 +768,8 @@
expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "$(location //other:foo.tool) -s $(OUTS) $(SRCS)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "foo.in",
- ],
+ outs = ["foo.out"],
+ srcs = ["foo.in"],
tools = [
"//other:foo.tool",
"//other:other.tool",
@@ -849,12 +795,8 @@
expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "foo.in",
- ],
+ outs = ["foo.out"],
+ srcs = ["foo.in"],
tools = [
"//other:foo.tool",
"//other:other.tool",
@@ -879,12 +821,8 @@
expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "cp $(SRCS) $(OUTS)",
- outs = [
- "foo.out",
- ],
- srcs = [
- "foo.in",
- ],
+ outs = ["foo.out"],
+ srcs = ["foo.in"],
)`,
},
},
@@ -988,12 +926,8 @@
expectedBazelTarget: `genrule(
name = "gen",
cmd = "do-something $(SRCS) $(OUTS)",
- outs = [
- "out",
- ],
- srcs = [
- "in1",
- ],
+ outs = ["out"],
+ srcs = ["in1"],
)`,
description: "genrule applies properties from a genrule_defaults dependency if not specified",
},
@@ -1062,12 +996,8 @@
expectedBazelTarget: `genrule(
name = "gen",
cmd = "cp $(SRCS) $(OUTS)",
- outs = [
- "out",
- ],
- srcs = [
- "in1",
- ],
+ outs = ["out"],
+ srcs = ["in1"],
)`,
description: "genrule applies properties from list of genrule_defaults",
},
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
new file mode 100644
index 0000000..783af2e
--- /dev/null
+++ b/bp2build/cc_library_conversion_test.go
@@ -0,0 +1,271 @@
+// 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 (
+ "android/soong/android"
+ "android/soong/cc"
+ "strings"
+ "testing"
+)
+
+const (
+ // See cc/testing.go for more context
+ soongCcLibraryPreamble = `
+cc_defaults {
+ name: "linux_bionic_supported",
+}
+
+toolchain_library {
+ name: "libclang_rt.builtins-x86_64-android",
+ defaults: ["linux_bionic_supported"],
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ product_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+ src: "",
+}`
+)
+
+func TestCcLibraryBp2Build(t *testing.T) {
+ testCases := []struct {
+ description string
+ moduleTypeUnderTest string
+ moduleTypeUnderTestFactory android.ModuleFactory
+ moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
+ bp string
+ expectedBazelTargets []string
+ filesystem map[string]string
+ dir string
+ }{
+ {
+ description: "cc_library - simple example",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "android.cpp": "",
+ "darwin.cpp": "",
+ // Refer to cc.headerExts for the supported header extensions in Soong.
+ "header.h": "",
+ "header.hh": "",
+ "header.hpp": "",
+ "header.hxx": "",
+ "header.h++": "",
+ "header.inl": "",
+ "header.inc": "",
+ "header.ipp": "",
+ "header.h.generic": "",
+ "impl.cpp": "",
+ "linux.cpp": "",
+ "x86.cpp": "",
+ "x86_64.cpp": "",
+ "foo-dir/a.h": "",
+ },
+ bp: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ cflags: ["-Wall"],
+ header_libs: ["some-headers"],
+ export_include_dirs: ["foo-dir"],
+ ldflags: ["-Wl,--exclude-libs=bar.a"],
+ arch: {
+ x86: {
+ ldflags: ["-Wl,--exclude-libs=baz.a"],
+ srcs: ["x86.cpp"],
+ },
+ x86_64: {
+ ldflags: ["-Wl,--exclude-libs=qux.a"],
+ srcs: ["x86_64.cpp"],
+ },
+ },
+ target: {
+ android: {
+ srcs: ["android.cpp"],
+ },
+ linux_glibc: {
+ srcs: ["linux.cpp"],
+ },
+ darwin: {
+ srcs: ["darwin.cpp"],
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = ["-Wall"],
+ deps = [":some-headers"],
+ hdrs = [
+ "header.h",
+ "header.hh",
+ "header.hpp",
+ "header.hxx",
+ "header.h++",
+ "header.inl",
+ "header.inc",
+ "header.ipp",
+ "header.h.generic",
+ "foo-dir/a.h",
+ ],
+ includes = ["foo-dir"],
+ linkopts = ["-Wl,--exclude-libs=bar.a"] + select({
+ "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
+ "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
+ "//conditions:default": [],
+ }),
+ srcs = ["impl.cpp"] + select({
+ "//build/bazel/platforms/arch:x86": ["x86.cpp"],
+ "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["android.cpp"],
+ "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
+ "//build/bazel/platforms/os:linux": ["linux.cpp"],
+ "//conditions:default": [],
+ }),
+)`},
+ },
+ {
+ description: "cc_library - trimmed example of //bionic/linker:ld-android",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "ld-android.cpp": "",
+ "linked_list.h": "",
+ "linker.h": "",
+ "linker_block_allocator.h": "",
+ "linker_cfi.h": "",
+ },
+ bp: soongCcLibraryPreamble + `
+cc_library_headers { name: "libc_headers" }
+cc_library {
+ name: "fake-ld-android",
+ srcs: ["ld_android.cpp"],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wunused",
+ "-Werror",
+ ],
+ header_libs: ["libc_headers"],
+ ldflags: [
+ "-Wl,--exclude-libs=libgcc.a",
+ "-Wl,--exclude-libs=libgcc_stripped.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
+ ],
+ arch: {
+ x86: {
+ ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+ },
+ x86_64: {
+ ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "fake-ld-android",
+ copts = [
+ "-Wall",
+ "-Wextra",
+ "-Wunused",
+ "-Werror",
+ ],
+ deps = [":libc_headers"],
+ hdrs = [
+ "linked_list.h",
+ "linker.h",
+ "linker_block_allocator.h",
+ "linker_cfi.h",
+ ],
+ linkopts = [
+ "-Wl,--exclude-libs=libgcc.a",
+ "-Wl,--exclude-libs=libgcc_stripped.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
+ ] + select({
+ "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=libgcc_eh.a"],
+ "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=libgcc_eh.a"],
+ "//conditions:default": [],
+ }),
+ srcs = ["ld_android.cpp"],
+)`},
+ },
+ }
+
+ dir := "."
+ for _, testCase := range testCases {
+ filesystem := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
+ }
+ for f, content := range testCase.filesystem {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ filesystem[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
+ ctx := android.NewTestContext(config)
+
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+ ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterBp2BuildConfig(bp2buildConfig) // TODO(jingwen): make this the default for all tests
+ ctx.RegisterForBazelConversion()
+
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if Errored(t, testCase.description, errs) {
+ continue
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if Errored(t, testCase.description, errs) {
+ continue
+ }
+
+ checkDir := dir
+ if testCase.dir != "" {
+ checkDir = testCase.dir
+ }
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
+ if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
+ t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
+ } else {
+ for i, target := range bazelTargets {
+ if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
+ t.Errorf(
+ "%s: Expected generated Bazel target to be '%s', got '%s'",
+ testCase.description,
+ w,
+ g,
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 74226ae..c59241f 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -23,7 +23,7 @@
const (
// See cc/testing.go for more context
- soongCcLibraryPreamble = `
+ soongCcLibraryHeadersPreamble = `
cc_defaults {
name: "linux_bionic_supported",
}
@@ -98,7 +98,7 @@
"arch_x86_exported_include_dir/b.h": "",
"arch_x86_64_exported_include_dir/c.h": "",
},
- bp: soongCcLibraryPreamble + `
+ bp: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "lib-1",
export_include_dirs: ["lib-1"],
@@ -141,30 +141,18 @@
"dir-2/dir2a.h",
"dir-2/dir2b.h",
] + select({
- "//build/bazel/platforms/arch:arm64": [
- "arch_arm64_exported_include_dir/a.h",
- ],
- "//build/bazel/platforms/arch:x86": [
- "arch_x86_exported_include_dir/b.h",
- ],
- "//build/bazel/platforms/arch:x86_64": [
- "arch_x86_64_exported_include_dir/c.h",
- ],
+ "//build/bazel/platforms/arch:arm64": ["arch_arm64_exported_include_dir/a.h"],
+ "//build/bazel/platforms/arch:x86": ["arch_x86_exported_include_dir/b.h"],
+ "//build/bazel/platforms/arch:x86_64": ["arch_x86_64_exported_include_dir/c.h"],
"//conditions:default": [],
}),
includes = [
"dir-1",
"dir-2",
] + 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",
- ],
+ "//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": [],
}),
)`, `cc_library_headers(
@@ -173,18 +161,14 @@
"lib-1/lib1a.h",
"lib-1/lib1b.h",
],
- includes = [
- "lib-1",
- ],
+ includes = ["lib-1"],
)`, `cc_library_headers(
name = "lib-2",
hdrs = [
"lib-2/lib2a.h",
"lib-2/lib2b.h",
],
- includes = [
- "lib-2",
- ],
+ includes = ["lib-2"],
)`},
},
{
@@ -223,27 +207,13 @@
name = "darwin-lib",
)`, `cc_library_headers(
name = "foo_headers",
- deps = [
- ":base-lib",
- ] + select({
- "//build/bazel/platforms/os:android": [
- ":android-lib",
- ],
- "//build/bazel/platforms/os:darwin": [
- ":darwin-lib",
- ],
- "//build/bazel/platforms/os:fuchsia": [
- ":fuchsia-lib",
- ],
- "//build/bazel/platforms/os:linux": [
- ":linux-lib",
- ],
- "//build/bazel/platforms/os:linux_bionic": [
- ":linux_bionic-lib",
- ],
- "//build/bazel/platforms/os:windows": [
- ":windows-lib",
- ],
+ deps = [":base-lib"] + select({
+ "//build/bazel/platforms/os:android": [":android-lib"],
+ "//build/bazel/platforms/os:darwin": [":darwin-lib"],
+ "//build/bazel/platforms/os:fuchsia": [":fuchsia-lib"],
+ "//build/bazel/platforms/os:linux": [":linux-lib"],
+ "//build/bazel/platforms/os:linux_bionic": [":linux_bionic-lib"],
+ "//build/bazel/platforms/os:windows": [":windows-lib"],
"//conditions:default": [],
}),
)`, `cc_library_headers(
@@ -278,7 +248,7 @@
name = "exported-lib",
)`, `cc_library_headers(
name = "foo_headers",
- deps = [] + select({
+ deps = select({
"//build/bazel/platforms/os:android": [
":android-lib",
":exported-lib",
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index ef528e9..427aed3 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -194,6 +194,8 @@
":whole_static_lib_2",
],
hdrs = [
+ "implicit_include_1.h",
+ "implicit_include_2.h",
"export_include_dir_1/export_include_dir_1_a.h",
"export_include_dir_1/export_include_dir_1_b.h",
"export_include_dir_2/export_include_dir_2_a.h",
@@ -212,8 +214,6 @@
srcs = [
"foo_static1.cc",
"foo_static2.cc",
- "implicit_include_1.h",
- "implicit_include_2.h",
"include_dir_1/include_dir_1_a.h",
"include_dir_1/include_dir_1_b.h",
"include_dir_2/include_dir_2_a.h",
@@ -222,50 +222,60 @@
"local_include_dir_1/local_include_dir_1_b.h",
"local_include_dir_2/local_include_dir_2_a.h",
"local_include_dir_2/local_include_dir_2_b.h",
+ "implicit_include_1.h",
+ "implicit_include_2.h",
],
)`, `cc_library_static(
name = "static_lib_1",
- includes = [
- ".",
- ],
- linkstatic = True,
- srcs = [
+ hdrs = [
"implicit_include_1.h",
"implicit_include_2.h",
+ ],
+ includes = ["."],
+ linkstatic = True,
+ srcs = [
"static_lib_1.cc",
+ "implicit_include_1.h",
+ "implicit_include_2.h",
],
)`, `cc_library_static(
name = "static_lib_2",
- includes = [
- ".",
- ],
- linkstatic = True,
- srcs = [
+ hdrs = [
"implicit_include_1.h",
"implicit_include_2.h",
+ ],
+ includes = ["."],
+ linkstatic = True,
+ srcs = [
"static_lib_2.cc",
+ "implicit_include_1.h",
+ "implicit_include_2.h",
],
)`, `cc_library_static(
name = "whole_static_lib_1",
- includes = [
- ".",
- ],
- linkstatic = True,
- srcs = [
+ hdrs = [
"implicit_include_1.h",
"implicit_include_2.h",
+ ],
+ includes = ["."],
+ linkstatic = True,
+ srcs = [
"whole_static_lib_1.cc",
+ "implicit_include_1.h",
+ "implicit_include_2.h",
],
)`, `cc_library_static(
name = "whole_static_lib_2",
- includes = [
- ".",
- ],
- linkstatic = True,
- srcs = [
+ hdrs = [
"implicit_include_1.h",
"implicit_include_2.h",
+ ],
+ includes = ["."],
+ linkstatic = True,
+ srcs = [
"whole_static_lib_2.cc",
+ "implicit_include_1.h",
+ "implicit_include_2.h",
],
)`},
},
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 4f3babe..a9d24ac 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -52,7 +52,6 @@
"-Werror",
],
srcs: [
- "a/b/*.h",
"a/b/*.c"
],
exclude_srcs: ["a/b/exclude.c"],
@@ -68,15 +67,15 @@
"-Wall",
"-Werror",
],
+ hdrs = [
+ "a/b/bar.h",
+ "a/b/foo.h",
+ ],
local_include_dirs = [
"include",
".",
],
- srcs = [
- "a/b/bar.h",
- "a/b/c.c",
- "a/b/foo.h",
- ],
+ srcs = ["a/b/c.c"],
)`,
},
},
@@ -123,9 +122,7 @@
"include",
".",
],
- srcs = [
- "a/b/c.c",
- ],
+ srcs = ["a/b/c.c"],
)`,
},
},
@@ -155,29 +152,15 @@
`,
expectedBazelTargets: []string{`cc_object(
name = "bar",
- copts = [
- "-fno-addrsig",
- ],
- local_include_dirs = [
- ".",
- ],
- srcs = [
- "x/y/z.c",
- ],
+ copts = ["-fno-addrsig"],
+ local_include_dirs = ["."],
+ srcs = ["x/y/z.c"],
)`, `cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- ],
- deps = [
- ":bar",
- ],
- local_include_dirs = [
- ".",
- ],
- srcs = [
- "a/b/c.c",
- ],
+ copts = ["-fno-addrsig"],
+ deps = [":bar"],
+ local_include_dirs = ["."],
+ srcs = ["a/b/c.c"],
)`,
},
},
@@ -200,12 +183,8 @@
`,
expectedBazelTargets: []string{`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- ],
- srcs = [
- "a/b/c.c",
- ],
+ copts = ["-fno-addrsig"],
+ srcs = ["a/b/c.c"],
)`,
},
},
@@ -228,12 +207,8 @@
`,
expectedBazelTargets: []string{`cc_object(
name = "foo",
- asflags = [
- "-DPLATFORM_SDK_VERSION={Platform_sdk_version}",
- ],
- copts = [
- "-fno-addrsig",
- ],
+ asflags = ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
+ copts = ["-fno-addrsig"],
)`,
},
},
@@ -321,23 +296,13 @@
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- ] + select({
- "//build/bazel/platforms/arch:x86": [
- "-fPIC",
- ],
+ copts = ["-fno-addrsig"] + select({
+ "//build/bazel/platforms/arch:x86": ["-fPIC"],
"//conditions:default": [],
}),
- local_include_dirs = [
- ".",
- ],
- srcs = [
- "a.cpp",
- ] + select({
- "//build/bazel/platforms/arch:arm": [
- "arch/arm/file.S",
- ],
+ local_include_dirs = ["."],
+ srcs = ["a.cpp"] + select({
+ "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"],
"//conditions:default": [],
}),
)`,
@@ -375,41 +340,19 @@
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- ] + select({
- "//build/bazel/platforms/arch:arm": [
- "-Wall",
- ],
- "//build/bazel/platforms/arch:arm64": [
- "-Wall",
- ],
- "//build/bazel/platforms/arch:x86": [
- "-fPIC",
- ],
- "//build/bazel/platforms/arch:x86_64": [
- "-fPIC",
- ],
+ copts = ["-fno-addrsig"] + select({
+ "//build/bazel/platforms/arch:arm": ["-Wall"],
+ "//build/bazel/platforms/arch:arm64": ["-Wall"],
+ "//build/bazel/platforms/arch:x86": ["-fPIC"],
+ "//build/bazel/platforms/arch:x86_64": ["-fPIC"],
"//conditions:default": [],
}),
- local_include_dirs = [
- ".",
- ],
- srcs = [
- "base.cpp",
- ] + select({
- "//build/bazel/platforms/arch:arm": [
- "arm.cpp",
- ],
- "//build/bazel/platforms/arch:arm64": [
- "arm64.cpp",
- ],
- "//build/bazel/platforms/arch:x86": [
- "x86.cpp",
- ],
- "//build/bazel/platforms/arch:x86_64": [
- "x86_64.cpp",
- ],
+ local_include_dirs = ["."],
+ srcs = ["base.cpp"] + select({
+ "//build/bazel/platforms/arch:arm": ["arm.cpp"],
+ "//build/bazel/platforms/arch:arm64": ["arm64.cpp"],
+ "//build/bazel/platforms/arch:x86": ["x86.cpp"],
+ "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
"//conditions:default": [],
}),
)`,
@@ -440,26 +383,14 @@
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- ] + select({
- "//build/bazel/platforms/os:android": [
- "-fPIC",
- ],
- "//build/bazel/platforms/os:darwin": [
- "-Wall",
- ],
- "//build/bazel/platforms/os:windows": [
- "-fPIC",
- ],
+ copts = ["-fno-addrsig"] + select({
+ "//build/bazel/platforms/os:android": ["-fPIC"],
+ "//build/bazel/platforms/os:darwin": ["-Wall"],
+ "//build/bazel/platforms/os:windows": ["-fPIC"],
"//conditions:default": [],
}),
- local_include_dirs = [
- ".",
- ],
- srcs = [
- "base.cpp",
- ],
+ local_include_dirs = ["."],
+ srcs = ["base.cpp"],
)`,
},
},
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index b2b3379..97729df 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -69,20 +69,26 @@
return ret, err
}
- // Create the selects for arch specific values.
- selectMap, err := prettyPrintSelectMap(archSelects, "[]", indent)
+ // Convenience function to append selects components to an attribute value.
+ appendSelects := func(selectsData selects, defaultValue, s string) (string, error) {
+ selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent)
+ if err != nil {
+ return "", err
+ }
+ if s != "" && selectMap != "" {
+ s += " + "
+ }
+ s += selectMap
+
+ return s, nil
+ }
+
+ ret, err = appendSelects(archSelects, "[]", ret)
if err != nil {
return "", err
}
- ret += selectMap
- // Create the selects for target os specific values.
- selectMap, err = prettyPrintSelectMap(osSelects, "[]", indent)
- if err != nil {
- return "", err
- }
- ret += selectMap
-
+ ret, err = appendSelects(osSelects, "[]", ret)
return ret, err
}
@@ -113,7 +119,7 @@
}
// Create the map.
- ret := " + select({\n"
+ ret := "select({\n"
ret += selects
// default condition comes last.
ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), "//conditions:default", defaultValue)
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 7600e36..2054e06 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -33,24 +33,15 @@
blueprint: `python_binary_host {
name: "foo",
main: "a.py",
- srcs: [
- "**/*.py"
- ],
- exclude_srcs: [
- "b/e.py"
- ],
- data: [
- "files/data.txt",
- ],
-
+ srcs: ["**/*.py"],
+ exclude_srcs: ["b/e.py"],
+ data: ["files/data.txt",],
bazel_module: { bp2build_available: true },
}
`,
expectedBazelTargets: []string{`py_binary(
name = "foo",
- data = [
- "files/data.txt",
- ],
+ data = ["files/data.txt"],
main = "a.py",
srcs = [
"a.py",
@@ -83,9 +74,7 @@
expectedBazelTargets: []string{`py_binary(
name = "foo",
python_version = "PY2",
- srcs = [
- "a.py",
- ],
+ srcs = ["a.py"],
)`,
},
},
@@ -113,9 +102,7 @@
// python_version is PY3 by default.
`py_binary(
name = "foo",
- srcs = [
- "a.py",
- ],
+ srcs = ["a.py"],
)`,
},
},
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index 2aa373c..37f542e 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -74,9 +74,7 @@
}`,
expectedBazelTargets: []string{`sh_binary(
name = "foo",
- srcs = [
- "foo.sh",
- ],
+ srcs = ["foo.sh"],
)`},
},
}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index cffeb24..0bca30a 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -59,72 +59,111 @@
ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
}
-// bp2buildParseCflags creates a label list attribute containing the cflags of a module, including
-func bp2BuildParseCflags(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
- var ret bazel.StringListAttribute
+// Convenience struct to hold all attributes parsed from compiler properties.
+type compilerAttributes struct {
+ copts bazel.StringListAttribute
+ srcs bazel.LabelListAttribute
+ hdrs bazel.LabelListAttribute
+}
+
+// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
+func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
+ var hdrs, srcs bazel.LabelListAttribute
+ var copts bazel.StringListAttribute
+
+ hdrsAndSrcs := func(baseCompilerProps *BaseCompilerProperties) (bazel.LabelList, bazel.LabelList) {
+ srcsList := android.BazelLabelForModuleSrcExcludes(
+ ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
+ hdrsList := android.BazelLabelForModuleSrc(ctx, srcsList.LooseHdrsGlobs(headerExts))
+ return hdrsList, srcsList
+ }
+
for _, props := range module.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- ret.Value = baseCompilerProps.Cflags
+ hdrs.Value, srcs.Value = hdrsAndSrcs(baseCompilerProps)
+ copts.Value = baseCompilerProps.Cflags
break
}
}
for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- ret.SetValueForArch(arch.Name, baseCompilerProps.Cflags)
+ hdrsList, srcsList := hdrsAndSrcs(baseCompilerProps)
+ hdrs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(hdrsList, hdrs.Value))
+ srcs.SetValueForArch(arch.Name, srcsList)
+ copts.SetValueForArch(arch.Name, baseCompilerProps.Cflags)
}
}
for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- ret.SetValueForOS(os.Name, baseCompilerProps.Cflags)
+ hdrsList, srcsList := hdrsAndSrcs(baseCompilerProps)
+ hdrs.SetValueForOS(os.Name, bazel.SubtractBazelLabelList(hdrsList, hdrs.Value))
+ srcs.SetValueForOS(os.Name, srcsList)
+ copts.SetValueForOS(os.Name, baseCompilerProps.Cflags)
}
}
- return ret
+ return compilerAttributes{
+ hdrs: hdrs,
+ srcs: srcs,
+ copts: copts,
+ }
}
-// bp2BuildParseHeaderLibs creates a label list attribute containing the header library deps of a module, including
+// Convenience struct to hold all attributes parsed from linker properties.
+type linkerAttributes struct {
+ deps bazel.LabelListAttribute
+ linkopts bazel.StringListAttribute
+}
+
+// bp2BuildParseLinkerProps creates a label list attribute containing the header library deps of a module, including
// configurable attribute values.
-func bp2BuildParseHeaderLibs(ctx android.TopDownMutatorContext, module *Module) bazel.LabelListAttribute {
- var ret bazel.LabelListAttribute
+func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
+
+ var deps bazel.LabelListAttribute
+ var linkopts bazel.StringListAttribute
+
for _, linkerProps := range module.linker.linkerProps() {
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
libs := baseLinkerProps.Header_libs
libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
- ret = bazel.MakeLabelListAttribute(
+ deps = bazel.MakeLabelListAttribute(
android.BazelLabelForModuleDeps(ctx, android.SortedUniqueStrings(libs)))
+ linkopts.Value = baseLinkerProps.Ldflags
break
}
}
+ for arch, p := range module.GetArchProperties(&BaseLinkerProperties{}) {
+ if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
+ libs := baseLinkerProps.Header_libs
+ libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
+ libs = android.SortedUniqueStrings(libs)
+ deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs))
+ linkopts.SetValueForArch(arch.Name, baseLinkerProps.Ldflags)
+ }
+ }
+
for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
libs := baseLinkerProps.Header_libs
libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
libs = android.SortedUniqueStrings(libs)
- ret.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
+ deps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
+ linkopts.SetValueForOS(os.Name, baseLinkerProps.Ldflags)
}
}
- return ret
+ return linkerAttributes{
+ deps: deps,
+ linkopts: linkopts,
+ }
}
func bp2BuildListHeadersInDir(ctx android.TopDownMutatorContext, includeDir string) bazel.LabelList {
- var globInfix string
-
- if includeDir == "." {
- globInfix = ""
- } else {
- globInfix = "/**"
- }
-
- var includeDirGlobs []string
- includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.h")
- includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.inc")
- includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.hpp")
-
- return android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
+ globs := bazel.GlobsInDir(includeDir, includeDir != ".", headerExts)
+ return android.BazelLabelForModuleSrc(ctx, globs)
}
// Bazel wants include paths to be relative to the module
diff --git a/cc/cc.go b/cc/cc.go
index 1ce83a9..9176bc3 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -56,8 +56,8 @@
ctx.TopDown("asan_deps", sanitizerDepsMutator(Asan))
ctx.BottomUp("asan", sanitizerMutator(Asan)).Parallel()
- ctx.TopDown("hwasan_deps", sanitizerDepsMutator(hwasan))
- ctx.BottomUp("hwasan", sanitizerMutator(hwasan)).Parallel()
+ ctx.TopDown("hwasan_deps", sanitizerDepsMutator(Hwasan))
+ ctx.BottomUp("hwasan", sanitizerMutator(Hwasan)).Parallel()
ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(Fuzzer))
ctx.BottomUp("fuzzer", sanitizerMutator(Fuzzer)).Parallel()
diff --git a/cc/library.go b/cc/library.go
index 18f9fae..738b45f 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -206,6 +206,7 @@
RegisterLibraryBuildComponents(android.InitRegistrationContext)
android.RegisterBp2BuildMutator("cc_library_static", CcLibraryStaticBp2Build)
+ android.RegisterBp2BuildMutator("cc_library", CcLibraryBp2Build)
}
func RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
@@ -216,6 +217,67 @@
ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
}
+// For bp2build conversion.
+type bazelCcLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Linkopts bazel.StringListAttribute
+ Deps bazel.LabelListAttribute
+ User_link_flags bazel.StringListAttribute
+ Includes bazel.StringListAttribute
+}
+
+type bazelCcLibrary struct {
+ android.BazelTargetModuleBase
+ bazelCcLibraryAttributes
+}
+
+func (m *bazelCcLibrary) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelCcLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
+
+func BazelCcLibraryFactory() android.Module {
+ module := &bazelCcLibrary{}
+ module.AddProperties(&module.bazelCcLibraryAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {
+ m, ok := ctx.Module().(*Module)
+ if !ok || !m.ConvertWithBp2build(ctx) {
+ return
+ }
+
+ if ctx.ModuleType() != "cc_library" {
+ return
+ }
+
+ compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
+ linkerAttrs := bp2BuildParseLinkerProps(ctx, m)
+ exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, m)
+ compilerAttrs.hdrs.Append(exportedIncludesHeaders)
+
+ attrs := &bazelCcLibraryAttributes{
+ Srcs: compilerAttrs.srcs,
+ Hdrs: compilerAttrs.hdrs,
+ Copts: compilerAttrs.copts,
+ Linkopts: linkerAttrs.linkopts,
+ Deps: linkerAttrs.deps,
+ Includes: exportedIncludes,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_library",
+ Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(BazelCcLibraryFactory, m.Name(), props, attrs)
+}
+
// cc_library creates both static and/or shared libraries for a device and/or
// host. By default, a cc_library has a single variant that targets the device.
// Specifying `host_supported: true` also creates a library that targets the
@@ -2058,9 +2120,10 @@
}
type bazelCcLibraryStaticAttributes struct {
- Copts []string
+ Copts bazel.StringListAttribute
Srcs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
+ Linkopts bazel.StringListAttribute
Linkstatic bool
Includes bazel.StringListAttribute
Hdrs bazel.LabelListAttribute
@@ -2091,14 +2154,13 @@
return
}
- var copts []string
- var srcs []string
+ compilerAttrs := bp2BuildParseCompilerProps(ctx, module)
+
var includeDirs []string
var localIncludeDirs []string
for _, props := range module.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- copts = baseCompilerProps.Cflags
- srcs = baseCompilerProps.Srcs
+ // TODO: these should be arch and os specific.
includeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
localIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Local_include_dirs)
break
@@ -2111,19 +2173,18 @@
localIncludeDirs = append(localIncludeDirs, ".")
}
- srcsLabels := android.BazelLabelForModuleSrc(ctx, srcs)
-
// For Bazel, be more explicit about headers - list all header files in include dirs as srcs
for _, includeDir := range includeDirs {
- srcsLabels.Append(bp2BuildListHeadersInDir(ctx, includeDir))
+ compilerAttrs.srcs.Value.Append(bp2BuildListHeadersInDir(ctx, includeDir))
}
for _, localIncludeDir := range localIncludeDirs {
- srcsLabels.Append(bp2BuildListHeadersInDir(ctx, localIncludeDir))
+ compilerAttrs.srcs.Value.Append(bp2BuildListHeadersInDir(ctx, localIncludeDir))
}
var staticLibs []string
var wholeStaticLibs []string
for _, props := range module.linker.linkerProps() {
+ // TODO: move this into bp2buildParseLinkerProps
if baseLinkerProperties, ok := props.(*BaseLinkerProperties); ok {
staticLibs = baseLinkerProperties.Static_libs
wholeStaticLibs = baseLinkerProperties.Whole_static_libs
@@ -2145,16 +2206,18 @@
allIncludes.Value = append(allIncludes.Value, includeDirs...)
allIncludes.Value = append(allIncludes.Value, localIncludeDirs...)
- headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module)
- depsLabels.Append(headerLibsLabels.Value)
+ compilerAttrs.hdrs.Append(exportedIncludesHeaders)
+
+ linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
+ depsLabels.Append(linkerAttrs.deps.Value)
attrs := &bazelCcLibraryStaticAttributes{
- Copts: copts,
- Srcs: bazel.MakeLabelListAttribute(srcsLabels),
+ Copts: compilerAttrs.copts,
+ Srcs: compilerAttrs.srcs,
Deps: bazel.MakeLabelListAttribute(depsLabels),
Linkstatic: true,
Includes: allIncludes,
- Hdrs: exportedIncludesHeaders,
+ Hdrs: compilerAttrs.hdrs,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/library_headers.go b/cc/library_headers.go
index d35748b..076ce80 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -96,14 +96,14 @@
}
exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, module)
-
- headerLibs := bp2BuildParseHeaderLibs(ctx, module)
+ compilerAttrs := bp2BuildParseCompilerProps(ctx, module)
+ linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
attrs := &bazelCcLibraryHeadersAttributes{
- Copts: bp2BuildParseCflags(ctx, module),
+ Copts: compilerAttrs.copts,
Includes: exportedIncludes,
Hdrs: exportedIncludesHeaders,
- Deps: headerLibs,
+ Deps: linkerAttrs.deps,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/object.go b/cc/object.go
index 4f8797d..9bb279a 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -113,6 +113,7 @@
// For bp2build conversion.
type bazelObjectAttributes struct {
Srcs bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Copts bazel.StringListAttribute
Asflags []string
@@ -156,16 +157,11 @@
}
// Set arch-specific configurable attributes
- var srcs bazel.LabelListAttribute
+ compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
var localIncludeDirs []string
var asFlags []string
for _, props := range m.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- srcs = bazel.MakeLabelListAttribute(
- android.BazelLabelForModuleSrcExcludes(
- ctx,
- baseCompilerProps.Srcs,
- baseCompilerProps.Exclude_srcs))
localIncludeDirs = baseCompilerProps.Local_include_dirs
break
}
@@ -200,16 +196,11 @@
}
// TODO(b/183595872) warn/error if we're not handling product variables
- for arch, p := range m.GetArchProperties(&BaseCompilerProperties{}) {
- if cProps, ok := p.(*BaseCompilerProperties); ok {
- srcs.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcExcludes(ctx, cProps.Srcs, cProps.Exclude_srcs))
- }
- }
-
attrs := &bazelObjectAttributes{
- Srcs: srcs,
+ Srcs: compilerAttrs.srcs,
+ Hdrs: compilerAttrs.hdrs,
Deps: deps,
- Copts: bp2BuildParseCflags(ctx, m),
+ Copts: compilerAttrs.copts,
Asflags: asFlags,
Local_include_dirs: localIncludeDirs,
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 8f17e4e..397121e 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -83,7 +83,7 @@
const (
Asan SanitizerType = iota + 1
- hwasan
+ Hwasan
tsan
intOverflow
cfi
@@ -97,7 +97,7 @@
switch t {
case Asan:
return "asan"
- case hwasan:
+ case Hwasan:
return "hwasan"
case tsan:
return "tsan"
@@ -121,7 +121,7 @@
switch t {
case Asan:
return "address"
- case hwasan:
+ case Hwasan:
return "hwaddress"
case memtag_heap:
return "memtag_heap"
@@ -144,7 +144,7 @@
switch t {
case Asan:
return true
- case hwasan:
+ case Hwasan:
return true
case tsan:
return true
@@ -163,7 +163,7 @@
// incompatibleWithCfi returns true if a sanitizer is incompatible with CFI.
func (t SanitizerType) incompatibleWithCfi() bool {
- return t == Asan || t == Fuzzer || t == hwasan
+ return t == Asan || t == Fuzzer || t == Hwasan
}
type SanitizeUserProps struct {
@@ -745,7 +745,7 @@
switch t {
case Asan:
return sanitize.Properties.Sanitize.Address
- case hwasan:
+ case Hwasan:
return sanitize.Properties.Sanitize.Hwaddress
case tsan:
return sanitize.Properties.Sanitize.Thread
@@ -767,7 +767,7 @@
// isUnsanitizedVariant returns true if no sanitizers are enabled.
func (sanitize *sanitize) isUnsanitizedVariant() bool {
return !sanitize.isSanitizerEnabled(Asan) &&
- !sanitize.isSanitizerEnabled(hwasan) &&
+ !sanitize.isSanitizerEnabled(Hwasan) &&
!sanitize.isSanitizerEnabled(tsan) &&
!sanitize.isSanitizerEnabled(cfi) &&
!sanitize.isSanitizerEnabled(scs) &&
@@ -778,7 +778,7 @@
// isVariantOnProductionDevice returns true if variant is for production devices (no non-production sanitizers enabled).
func (sanitize *sanitize) isVariantOnProductionDevice() bool {
return !sanitize.isSanitizerEnabled(Asan) &&
- !sanitize.isSanitizerEnabled(hwasan) &&
+ !sanitize.isSanitizerEnabled(Hwasan) &&
!sanitize.isSanitizerEnabled(tsan) &&
!sanitize.isSanitizerEnabled(Fuzzer)
}
@@ -787,7 +787,7 @@
switch t {
case Asan:
sanitize.Properties.Sanitize.Address = boolPtr(b)
- case hwasan:
+ case Hwasan:
sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
case tsan:
sanitize.Properties.Sanitize.Thread = boolPtr(b)
@@ -902,7 +902,7 @@
if d, ok := child.(PlatformSanitizeable); ok && d.SanitizePropDefined() &&
!d.SanitizeNever() &&
!d.IsSanitizerExplicitlyDisabled(t) {
- if t == cfi || t == hwasan || t == scs {
+ if t == cfi || t == Hwasan || t == scs {
if d.StaticallyLinked() && d.SanitizerSupported(t) {
// Rust does not support some of these sanitizers, so we need to check if it's
// supported before setting this true.
@@ -1286,7 +1286,7 @@
// For cfi/scs/hwasan, we can export both sanitized and un-sanitized variants
// to Make, because the sanitized version has a different suffix in name.
// For other types of sanitizers, suppress the variation that is disabled.
- if t != cfi && t != scs && t != hwasan {
+ if t != cfi && t != scs && t != Hwasan {
if isSanitizerEnabled {
modules[0].(PlatformSanitizeable).SetPreventInstall()
modules[0].(PlatformSanitizeable).SetHideFromMake()
@@ -1300,7 +1300,7 @@
if c.StaticallyLinked() && c.ExportedToMake() {
if t == cfi {
cfiStaticLibs(mctx.Config()).add(c, c.Module().Name())
- } else if t == hwasan {
+ } else if t == Hwasan {
hwasanStaticLibs(mctx.Config()).add(c, c.Module().Name())
}
}
@@ -1417,7 +1417,7 @@
func hwasanStaticLibs(config android.Config) *sanitizerStaticLibsMap {
return config.Once(hwasanStaticLibsKey, func() interface{} {
- return newSanitizerStaticLibsMap(hwasan)
+ return newSanitizerStaticLibsMap(Hwasan)
}).(*sanitizerStaticLibsMap)
}
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 3d31be4..3437d77 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -196,7 +196,7 @@
if m.sanitize != nil {
// scs and hwasan export both sanitized and unsanitized variants for static and header
// Always use unsanitized variants of them.
- for _, t := range []SanitizerType{scs, hwasan} {
+ for _, t := range []SanitizerType{scs, Hwasan} {
if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
return false
}
diff --git a/rust/androidmk.go b/rust/androidmk.go
index b0e6967..dea32a3 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -70,6 +70,11 @@
// If the compiler is disabled, this is a SourceProvider.
mod.SubAndroidMk(&ret, mod.sourceProvider)
}
+
+ if mod.sanitize != nil {
+ mod.SubAndroidMk(&ret, mod.sanitize)
+ }
+
ret.SubName += mod.Properties.SubName
return []android.AndroidMkEntries{ret}
diff --git a/rust/config/global.go b/rust/config/global.go
index 9208ddb..18776ab 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.50.0"
+ RustDefaultVersion = "1.51.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2018"
Stdlibs = []string{
diff --git a/rust/config/lints.go b/rust/config/lints.go
index 7c05e4f..ef6b315 100644
--- a/rust/config/lints.go
+++ b/rust/config/lints.go
@@ -54,6 +54,7 @@
"-A clippy::type-complexity",
"-A clippy::unnecessary-wraps",
"-A clippy::unusual-byte-groupings",
+ "-A clippy::upper-case-acronyms",
}
// Rust lints for vendor code.
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 2498aa1..ae3eff0 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -23,11 +23,12 @@
)
type SanitizeProperties struct {
- // enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer
+ // enable AddressSanitizer, HWAddressSanitizer, and others.
Sanitize struct {
- Address *bool `android:"arch_variant"`
- Fuzzer *bool `android:"arch_variant"`
- Never *bool `android:"arch_variant"`
+ Address *bool `android:"arch_variant"`
+ Hwaddress *bool `android:"arch_variant"`
+ Fuzzer *bool `android:"arch_variant"`
+ Never *bool `android:"arch_variant"`
}
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
@@ -43,7 +44,6 @@
"-C llvm-args=-sanitizer-coverage-level=3",
"-C llvm-args=-sanitizer-coverage-trace-compares",
"-C llvm-args=-sanitizer-coverage-inline-8bit-counters",
- "-C llvm-args=-sanitizer-coverage-stack-depth",
"-C llvm-args=-sanitizer-coverage-trace-geps",
"-C llvm-args=-sanitizer-coverage-prune-blocks=0",
"-Z sanitizer=address",
@@ -57,6 +57,11 @@
"-Z sanitizer=address",
}
+var hwasanFlags = []string{
+ "-Z sanitizer=hwaddress",
+ "-C target-feature=+tagged-globals",
+}
+
func boolPtr(v bool) *bool {
if v {
return &v
@@ -83,6 +88,15 @@
if ctx.Os() == android.Android && Bool(s.Address) {
sanitize.Properties.SanitizerEnabled = true
}
+
+ // HWASan requires AArch64 hardware feature (top-byte-ignore).
+ if ctx.Arch().ArchType != android.Arm64 {
+ s.Hwaddress = nil
+ }
+
+ if ctx.Os() == android.Android && Bool(s.Hwaddress) {
+ sanitize.Properties.SanitizerEnabled = true
+ }
}
type sanitize struct {
@@ -99,6 +113,9 @@
if Bool(sanitize.Properties.Sanitize.Address) {
flags.RustFlags = append(flags.RustFlags, asanFlags...)
}
+ if Bool(sanitize.Properties.Sanitize.Hwaddress) {
+ flags.RustFlags = append(flags.RustFlags, hwasanFlags...)
+ }
return flags, deps
}
@@ -111,11 +128,38 @@
if !mod.Enabled() {
return
}
+
+ variations := mctx.Target().Variations()
+ var depTag blueprint.DependencyTag
+ var deps []string
+
if Bool(mod.sanitize.Properties.Sanitize.Fuzzer) || Bool(mod.sanitize.Properties.Sanitize.Address) {
- mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
- {Mutator: "link", Variation: "shared"},
- }...), cc.SharedDepTag(), config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan"))
+ variations = append(variations,
+ blueprint.Variation{Mutator: "link", Variation: "shared"})
+ depTag = cc.SharedDepTag()
+ deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")}
+ } else if mod.IsSanitizerEnabled(cc.Hwasan) {
+ // TODO(b/180495975): HWASan for static Rust binaries isn't supported yet.
+ if binary, ok := mod.compiler.(*binaryDecorator); ok {
+ if Bool(binary.Properties.Static_executable) {
+ mctx.ModuleErrorf("HWASan is not supported for static Rust executables yet.")
+ }
+ }
+
+ if mod.StaticallyLinked() {
+ variations = append(variations,
+ blueprint.Variation{Mutator: "link", Variation: "static"})
+ depTag = cc.StaticDepTag(false)
+ deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan_static")}
+ } else {
+ variations = append(variations,
+ blueprint.Variation{Mutator: "link", Variation: "shared"})
+ depTag = cc.SharedDepTag()
+ deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")}
+ }
}
+
+ mctx.AddFarVariationDependencies(variations, depTag, deps...)
}
}
@@ -128,6 +172,9 @@
case cc.Asan:
sanitize.Properties.Sanitize.Address = boolPtr(b)
sanitizerSet = true
+ case cc.Hwasan:
+ sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
+ sanitizerSet = true
default:
panic(fmt.Errorf("setting unsupported sanitizerType %d", t))
}
@@ -169,11 +216,23 @@
return sanitize.Properties.Sanitize.Fuzzer
case cc.Asan:
return sanitize.Properties.Sanitize.Address
+ case cc.Hwasan:
+ return sanitize.Properties.Sanitize.Hwaddress
default:
return nil
}
}
+func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ // Add a suffix for hwasan rlib libraries to allow surfacing both the sanitized and
+ // non-sanitized variants to make without a name conflict.
+ if entries.Class == "RLIB_LIBRARIES" || entries.Class == "STATIC_LIBRARIES" {
+ if sanitize.isSanitizerEnabled(cc.Hwasan) {
+ entries.SubName += ".hwasan"
+ }
+ }
+}
+
func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool {
if mod.Host() {
return false
@@ -183,6 +242,8 @@
return true
case cc.Asan:
return true
+ case cc.Hwasan:
+ return true
default:
return false
}