Merge "Add custom java_sdk_library info to the SDK info file"
diff --git a/android/Android.bp b/android/Android.bp
index d583703..8eb55d2 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -49,6 +49,7 @@
"expand.go",
"filegroup.go",
"fixture.go",
+ "gen_notice.go",
"hooks.go",
"image.go",
"license.go",
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 9aae6fd..622c3c4 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -227,7 +227,7 @@
"prebuilts/bundletool":/* recursive = */ true,
"prebuilts/gcc":/* recursive = */ true,
- "prebuilts/build-tools":/* recursive = */ false,
+ "prebuilts/build-tools":/* recursive = */ true,
"prebuilts/jdk/jdk11":/* recursive = */ false,
"prebuilts/sdk":/* recursive = */ false,
"prebuilts/sdk/current/extras/app-toolkit":/* recursive = */ false,
diff --git a/android/gen_notice.go b/android/gen_notice.go
new file mode 100644
index 0000000..f514975
--- /dev/null
+++ b/android/gen_notice.go
@@ -0,0 +1,207 @@
+// Copyright 2020 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 android
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ RegisterGenNoticeBuildComponents(InitRegistrationContext)
+}
+
+// Register the gen_notice module type.
+func RegisterGenNoticeBuildComponents(ctx RegistrationContext) {
+ ctx.RegisterSingletonType("gen_notice_build_rules", GenNoticeBuildRulesFactory)
+ ctx.RegisterModuleType("gen_notice", GenNoticeFactory)
+}
+
+type genNoticeBuildRules struct{}
+
+func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) {
+ ctx.VisitAllModules(func(m Module) {
+ gm, ok := m.(*genNoticeModule)
+ if !ok {
+ return
+ }
+ if len(gm.missing) > 0 {
+ missingReferencesRule(ctx, gm)
+ return
+ }
+ out := BuildNoticeTextOutputFromLicenseMetadata
+ if proptools.Bool(gm.properties.Xml) {
+ out = BuildNoticeXmlOutputFromLicenseMetadata
+ } else if proptools.Bool(gm.properties.Html) {
+ out = BuildNoticeHtmlOutputFromLicenseMetadata
+ }
+ defaultName := ""
+ if len(gm.properties.For) > 0 {
+ defaultName = gm.properties.For[0]
+ }
+
+ modules := make([]Module, 0)
+ for _, name := range gm.properties.For {
+ mods := ctx.ModuleVariantsFromName(gm, name)
+ for _, mod := range mods {
+ if mod == nil {
+ continue
+ }
+ modules = append(modules, mod)
+ }
+ }
+ if ctx.Failed() {
+ return
+ }
+ out(ctx, gm.output, proptools.StringDefault(gm.properties.ArtifactName, defaultName), "", modules...)
+ })
+}
+
+func GenNoticeBuildRulesFactory() Singleton {
+ return &genNoticeBuildRules{}
+}
+
+type genNoticeProperties struct {
+ // For specifies the modules for which to generate a notice file.
+ For []string
+ // ArtifactName specifies the internal name to use for the notice file.
+ // It appears in the "used by:" list for targets whose entire name is stripped by --strip_prefix.
+ ArtifactName *string
+ // Stem specifies the base name of the output file.
+ Stem *string `android:"arch_variant"`
+ // Html indicates an html-format file is needed. The default is text. Can be Html or Xml but not both.
+ Html *bool
+ // Xml indicates an xml-format file is needed. The default is text. Can be Html or Xml but not both.
+ Xml *bool
+ // Gzipped indicates the output file must be compressed with gzip. Will append .gz to suffix if not there.
+ Gzipped *bool
+ // Suffix specifies the file extension to use. Defaults to .html for html, .xml for xml, or no extension for text.
+ Suffix *string
+ // Visibility specifies where this license can be used
+ Visibility []string
+}
+
+type genNoticeModule struct {
+ ModuleBase
+ DefaultableModuleBase
+
+ properties genNoticeProperties
+
+ output OutputPath
+ missing []string
+}
+
+func (m *genNoticeModule) DepsMutator(ctx BottomUpMutatorContext) {
+ if proptools.Bool(m.properties.Html) && proptools.Bool(m.properties.Xml) {
+ ctx.ModuleErrorf("can be html or xml but not both")
+ }
+ if !ctx.Config().AllowMissingDependencies() {
+ var missing []string
+ // Verify the modules for which to generate notices exist.
+ for _, otherMod := range m.properties.For {
+ if !ctx.OtherModuleExists(otherMod) {
+ missing = append(missing, otherMod)
+ }
+ }
+ if len(missing) == 1 {
+ ctx.PropertyErrorf("for", "no %q module exists", missing[0])
+ } else if len(missing) > 1 {
+ ctx.PropertyErrorf("for", "modules \"%s\" do not exist", strings.Join(missing, "\", \""))
+ }
+ }
+}
+
+func (m *genNoticeModule) getStem() string {
+ stem := m.base().BaseModuleName()
+ if m.properties.Stem != nil {
+ stem = proptools.String(m.properties.Stem)
+ }
+ return stem
+}
+
+func (m *genNoticeModule) getSuffix() string {
+ suffix := ""
+ if m.properties.Suffix == nil {
+ if proptools.Bool(m.properties.Html) {
+ suffix = ".html"
+ } else if proptools.Bool(m.properties.Xml) {
+ suffix = ".xml"
+ }
+ } else {
+ suffix = proptools.String(m.properties.Suffix)
+ }
+ if proptools.Bool(m.properties.Gzipped) && !strings.HasSuffix(suffix, ".gz") {
+ suffix += ".gz"
+ }
+ return suffix
+}
+
+func (m *genNoticeModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ if ctx.Config().AllowMissingDependencies() {
+ // Verify the modules for which to generate notices exist.
+ for _, otherMod := range m.properties.For {
+ if !ctx.OtherModuleExists(otherMod) {
+ m.missing = append(m.missing, otherMod)
+ }
+ }
+ m.missing = append(m.missing, ctx.GetMissingDependencies()...)
+ m.missing = FirstUniqueStrings(m.missing)
+ }
+ out := m.getStem() + m.getSuffix()
+ m.output = PathForModuleOut(ctx, out).OutputPath
+}
+
+func GenNoticeFactory() Module {
+ module := &genNoticeModule{}
+
+ base := module.base()
+ module.AddProperties(&base.nameProperties, &module.properties)
+
+ // The visibility property needs to be checked and parsed by the visibility module.
+ setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility)
+
+ initAndroidModuleBase(module)
+ InitDefaultableModule(module)
+
+ return module
+}
+
+var _ OutputFileProducer = (*genNoticeModule)(nil)
+
+// Implements OutputFileProducer
+func (m *genNoticeModule) OutputFiles(tag string) (Paths, error) {
+ if tag == "" {
+ return Paths{m.output}, nil
+ }
+ return nil, fmt.Errorf("unrecognized tag %q", tag)
+}
+
+// missingReferencesRule emits an ErrorRule for missing module references.
+func missingReferencesRule(ctx BuilderContext, m *genNoticeModule) {
+ if len(m.missing) < 1 {
+ panic(fmt.Errorf("missing references rule requested with no missing references"))
+ }
+
+ ctx.Build(pctx, BuildParams{
+ Rule: ErrorRule,
+ Output: m.output,
+ Description: "notice for " + proptools.StringDefault(m.properties.ArtifactName, "container"),
+ Args: map[string]string{
+ "error": m.Name() + " references missing module(s): " + strings.Join(m.missing, ", "),
+ },
+ })
+}
diff --git a/android/licenses.go b/android/licenses.go
index bd14b26..81c557e 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -303,6 +303,7 @@
switch reflect.TypeOf(module).String() {
case "*android.licenseModule": // is a license, doesn't need one
case "*android.licenseKindModule": // is a license, doesn't need one
+ case "*android.genNoticeModule": // contains license texts as data
case "*android.NamespaceModule": // just partitions things, doesn't add anything
case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
diff --git a/android/notices.go b/android/notices.go
index 2a4c17c..b16dc58 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -15,31 +15,86 @@
package android
import (
+ "fmt"
+ "path/filepath"
"strings"
)
-// BuildNoticeTextOutputFromLicenseMetadata writes out a notice text file based on the module's
-// generated license metadata file.
-func BuildNoticeTextOutputFromLicenseMetadata(ctx ModuleContext, outputFile WritablePath) {
- depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
- rule := NewRuleBuilder(pctx, ctx)
- rule.Command().
- BuiltTool("textnotice").
- FlagWithOutput("-o ", outputFile).
- FlagWithDepFile("-d ", depsFile).
- Input(ctx.Module().base().licenseMetadataFile)
- rule.Build("text_notice", "container notice file")
+func modulesOutputDirs(ctx BuilderContext, modules ...Module) []string {
+ dirs := make([]string, 0, len(modules))
+ for _, module := range modules {
+ paths, err := outputFilesForModule(ctx, module, "")
+ if err != nil {
+ continue
+ }
+ for _, path := range paths {
+ if path != nil {
+ dirs = append(dirs, filepath.Dir(path.String()))
+ }
+ }
+ }
+ return SortedUniqueStrings(dirs)
}
-// BuildNoticeHtmlOutputFromLicenseMetadata writes out a notice text file based on the module's
-// generated license metadata file.
-func BuildNoticeHtmlOutputFromLicenseMetadata(ctx ModuleContext, outputFile WritablePath) {
+func modulesLicenseMetadata(ctx BuilderContext, modules ...Module) Paths {
+ result := make(Paths, 0, len(modules))
+ for _, module := range modules {
+ if mf := module.base().licenseMetadataFile; mf != nil {
+ result = append(result, mf)
+ }
+ }
+ return result
+}
+
+// buildNoticeOutputFromLicenseMetadata writes out a notice file.
+func buildNoticeOutputFromLicenseMetadata(ctx BuilderContext, tool, name string, outputFile WritablePath, libraryName, stripPrefix string, modules ...Module) {
depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
rule := NewRuleBuilder(pctx, ctx)
- rule.Command().
- BuiltTool("htmlnotice").
+ if len(modules) == 0 {
+ if mctx, ok := ctx.(ModuleContext); ok {
+ modules = []Module{mctx.Module()}
+ } else {
+ panic(fmt.Errorf("%s %q needs a module to generate the notice for", name, libraryName))
+ }
+ }
+ if libraryName == "" {
+ libraryName = modules[0].Name()
+ }
+ cmd := rule.Command().
+ BuiltTool(tool).
FlagWithOutput("-o ", outputFile).
- FlagWithDepFile("-d ", depsFile).
- Input(ctx.Module().base().licenseMetadataFile)
- rule.Build("html_notice", "container notice file")
+ FlagWithDepFile("-d ", depsFile)
+ if stripPrefix != "" {
+ cmd = cmd.FlagWithArg("--strip_prefix ", stripPrefix)
+ }
+ outputs := modulesOutputDirs(ctx, modules...)
+ if len(outputs) > 0 {
+ cmd = cmd.FlagForEachArg("--strip_prefix ", outputs)
+ }
+ if libraryName != "" {
+ cmd = cmd.FlagWithArg("--product ", libraryName)
+ }
+ cmd = cmd.Inputs(modulesLicenseMetadata(ctx, modules...))
+ rule.Build(name, "container notice file")
+}
+
+// BuildNoticeTextOutputFromLicenseMetadata writes out a notice text file based
+// on the license metadata files for the input `modules` defaulting to the
+// current context module if none given.
+func BuildNoticeTextOutputFromLicenseMetadata(ctx BuilderContext, outputFile WritablePath, libraryName, stripPrefix string, modules ...Module) {
+ buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice", outputFile, libraryName, stripPrefix, modules...)
+}
+
+// BuildNoticeHtmlOutputFromLicenseMetadata writes out a notice text file based
+// on the license metadata files for the input `modules` defaulting to the
+// current context module if none given.
+func BuildNoticeHtmlOutputFromLicenseMetadata(ctx BuilderContext, outputFile WritablePath, libraryName, stripPrefix string, modules ...Module) {
+ buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice", outputFile, libraryName, stripPrefix, modules...)
+}
+
+// BuildNoticeXmlOutputFromLicenseMetadata writes out a notice text file based
+// on the license metadata files for the input `modules` defaulting to the
+// current context module if none given.
+func BuildNoticeXmlOutputFromLicenseMetadata(ctx BuilderContext, outputFile WritablePath, libraryName, stripPrefix string, modules ...Module) {
+ buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice", outputFile, libraryName, stripPrefix, modules...)
}
diff --git a/android/singleton.go b/android/singleton.go
index 7ff96c9..ec7f63e 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -29,6 +29,10 @@
ModuleType(module blueprint.Module) string
BlueprintFile(module blueprint.Module) string
+ // ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules.
+ // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context.
+ ModuleVariantsFromName(referer Module, name string) []Module
+
// ModuleProvider returns the value, if any, for the provider for a module. If the value for the
// provider was not set it returns the zero value of the type of the provider, which means the
// return value can always be type-asserted to the type of the provider. The return value should
@@ -251,3 +255,29 @@
func (s *singletonContextAdaptor) FinalModule(module Module) Module {
return s.SingletonContext.FinalModule(module).(Module)
}
+
+func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
+ // get qualified module name for visibility enforcement
+ qualified := createQualifiedModuleName(s.ModuleName(referer), s.ModuleDir(referer))
+
+ modules := s.SingletonContext.ModuleVariantsFromName(referer, name)
+ result := make([]Module, 0, len(modules))
+ for _, m := range modules {
+ if module, ok := m.(Module); ok {
+ // enforce visibility
+ depName := s.ModuleName(module)
+ depDir := s.ModuleDir(module)
+ depQualified := qualifiedModuleName{depDir, depName}
+ // Targets are always visible to other targets in their own package.
+ if depQualified.pkg != qualified.pkg {
+ rule := effectiveVisibilityRules(s.Config(), depQualified)
+ if !rule.matches(qualified) {
+ s.ModuleErrorf(referer, "references %s which is not visible to this module\nYou may need to add %q to its visibility", depQualified, "//"+s.ModuleDir(m))
+ continue
+ }
+ }
+ result = append(result, module)
+ }
+ }
+ return result
+}
diff --git a/android/visibility.go b/android/visibility.go
index 5d1be6b..b209599 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -234,7 +234,7 @@
// Checks the per-module visibility rule lists before defaults expansion.
func visibilityRuleChecker(ctx BottomUpMutatorContext) {
- qualified := createQualifiedModuleName(ctx)
+ qualified := createQualifiedModuleName(ctx.ModuleName(), ctx.ModuleDir())
if m, ok := ctx.Module().(Module); ok {
visibilityProperties := m.visibilityProperties()
for _, p := range visibilityProperties {
@@ -435,7 +435,7 @@
return
}
- qualified := createQualifiedModuleName(ctx)
+ qualified := createQualifiedModuleName(ctx.ModuleName(), ctx.ModuleDir())
// Visit all the dependencies making sure that this module has access to them all.
ctx.VisitDirectDeps(func(dep Module) {
@@ -486,9 +486,7 @@
return rule
}
-func createQualifiedModuleName(ctx BaseModuleContext) qualifiedModuleName {
- moduleName := ctx.ModuleName()
- dir := ctx.ModuleDir()
+func createQualifiedModuleName(moduleName, dir string) qualifiedModuleName {
qualified := qualifiedModuleName{dir, moduleName}
return qualified
}
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
index f050a2e..c61afcb 100644
--- a/android_sdk/sdk_repo_host.go
+++ b/android_sdk/sdk_repo_host.go
@@ -107,6 +107,7 @@
func (s *sdkRepoHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
dir := android.PathForModuleOut(ctx, "zip")
+ outputZipFile := dir.Join(ctx, "output.zip")
builder := android.NewRuleBuilder(pctx, ctx).
Sbox(dir, android.PathForModuleOut(ctx, "out.sbox.textproto")).
SandboxInputs()
@@ -123,7 +124,7 @@
s.CopySpecsToDir(ctx, builder, packageSpecs, dir)
noticeFile := android.PathForModuleOut(ctx, "NOTICES.txt")
- android.BuildNoticeTextOutputFromLicenseMetadata(ctx, noticeFile)
+ android.BuildNoticeTextOutputFromLicenseMetadata(ctx, noticeFile, "", outputZipFile.String())
builder.Command().Text("cp").
Input(noticeFile).
Text(filepath.Join(dir.String(), "NOTICE.txt"))
@@ -209,7 +210,6 @@
}
// Zip up our temporary directory as the sdk-repo
- outputZipFile := dir.Join(ctx, "output.zip")
builder.Command().
BuiltTool("soong_zip").
FlagWithOutput("-o ", outputZipFile).
diff --git a/apex/builder.go b/apex/builder.go
index abbf8ad..f959b7a 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -618,7 +618,7 @@
// Create a NOTICE file, and embed it as an asset file in the APEX.
a.htmlGzNotice = android.PathForModuleOut(ctx, "NOTICE.html.gz")
- android.BuildNoticeHtmlOutputFromLicenseMetadata(ctx, a.htmlGzNotice)
+ android.BuildNoticeHtmlOutputFromLicenseMetadata(ctx, a.htmlGzNotice, "", unsignedOutputFile.String())
noticeAssetPath := android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Text("cp").
diff --git a/bazel/aquery.go b/bazel/aquery.go
index fe0a390..ee09d0b 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -49,7 +49,7 @@
// AqueryDepset is a depset definition from Bazel's aquery response. This is
// akin to the `depSetOfFiles` in the response proto, except:
// * direct artifacts are enumerated by full path instead of by ID
-// * has a hash of the depset contents, instead of an int ID (for determinism)
+// * it has a hash of the depset contents, instead of an int ID (for determinism)
// A depset is a data structure for efficient transitive handling of artifact
// paths. A single depset consists of one or more artifact paths and one or
// more "child" depsets.
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
index 7d48191..818d7ae 100644
--- a/bp2build/symlink_forest.go
+++ b/bp2build/symlink_forest.go
@@ -95,13 +95,19 @@
return fi.IsDir()
}
- fi2, err := os.Stat(path)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Cannot stat '%s': %s\n", path, err)
+ fi2, statErr := os.Stat(path)
+ if statErr == nil {
+ return fi2.IsDir()
+ }
+
+ // Check if this is a dangling symlink. If so, treat it like a file, not a dir.
+ _, lstatErr := os.Lstat(path)
+ if lstatErr != nil {
+ fmt.Fprintf(os.Stderr, "Cannot stat or lstat '%s': %s\n%s\n", path, statErr, lstatErr)
os.Exit(1)
}
- return fi2.IsDir()
+ return false
}
// Recursively plants a symlink forest at forestDir. The symlink tree will
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 19855fa..a2041f4 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -684,6 +684,13 @@
la.additionalLinkerInputs.SetSelectValue(axis, config, bazel.LabelList{Includes: []bazel.Label{label}})
linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label))
}
+
+ if props.Dynamic_list != nil {
+ label := android.BazelLabelForModuleSrcSingle(ctx, *props.Dynamic_list)
+ la.additionalLinkerInputs.SetSelectValue(axis, config, bazel.LabelList{Includes: []bazel.Label{label}})
+ linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--dynamic-list,$(location %s)", label.Label))
+ }
+
la.linkopts.SetSelectValue(axis, config, linkerFlags)
la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 2951b5a..fb24624 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4041,7 +4041,7 @@
conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
- cflags := []string{"-Wall", "-Werror", "-std=candcpp"}
+ cflags := []string{"-Werror", "-std=candcpp"}
cstd := []string{"-std=gnu11", "-std=conly"}
cppstd := []string{"-std=gnu++17", "-std=cpp", "-fno-rtti"}
diff --git a/cc/compiler.go b/cc/compiler.go
index eb5458f..773a642 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -589,10 +589,9 @@
addToModuleList(ctx, modulesUsingWnoErrorKey, module)
} else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) {
if warningsAreAllowed(ctx.ModuleDir()) {
- addToModuleList(ctx, modulesAddedWallKey, module)
- flags.Local.CFlags = append([]string{"-Wall"}, flags.Local.CFlags...)
+ addToModuleList(ctx, modulesWarningsAllowedKey, module)
} else {
- flags.Local.CFlags = append([]string{"-Wall", "-Werror"}, flags.Local.CFlags...)
+ flags.Local.CFlags = append([]string{"-Werror"}, flags.Local.CFlags...)
}
}
}
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 1f90843..826197a 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -35,14 +35,22 @@
"bugprone-*",
"cert-*",
"clang-diagnostic-unused-command-line-argument",
- "google-*",
+ // Select only google-* checks that do not have thousands of warnings.
+ // Add more such checks when we clean up source code.
+ // "google-build-using-namespace",
+ // "google-default-arguments",
+ // "google-explicit-constructor",
+ // "google-global-names-in-headers",
+ // "google-runtime-int",
+ "google-build-explicit-make-pair",
+ "google-build-namespaces",
+ "google-runtime-operator",
+ "google-upgrade-*",
"misc-*",
"performance-*",
"portability-*",
"-bugprone-easily-swappable-parameters",
"-bugprone-narrowing-conversions",
- "-google-readability*",
- "-google-runtime-references",
"-misc-no-recursion",
"-misc-non-private-member-variables-in-classes",
"-misc-unused-parameters",
@@ -79,13 +87,10 @@
return strings.Join([]string{
"-*",
"clang-diagnostic-unused-command-line-argument",
- "google*",
- "-google-build-using-namespace",
- "-google-default-arguments",
- "-google-explicit-constructor",
- "-google-readability*",
- "-google-runtime-int",
- "-google-runtime-references",
+ "google-build-explicit-make-pair",
+ "google-build-namespaces",
+ "google-runtime-operator",
+ "google-upgrade-*",
}, ",")
})
diff --git a/cc/linkable.go b/cc/linkable.go
index 6bec30c..04eab39 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -22,16 +22,16 @@
// than left undefined.
IsSanitizerExplicitlyDisabled(t SanitizerType) bool
- // SanitizeDep returns the value of the SanitizeDep flag, which is set if a module is a dependency of a
- // sanitized module.
- SanitizeDep() bool
+ // SanitizeDep returns true if the module is statically linked into another that is sanitized
+ // with the given sanitizer.
+ SanitizeDep(t SanitizerType) bool
+
+ // SetSanitizeDep marks a module as a static dependency of another module to be sanitized.
+ SetSanitizeDep(t SanitizerType)
// SetSanitizer enables or disables the specified sanitizer type if it's supported, otherwise this should panic.
SetSanitizer(t SanitizerType, b bool)
- // SetSanitizerDep returns true if the module is statically linked.
- SetSanitizeDep(b bool)
-
// StaticallyLinked returns true if the module is statically linked.
StaticallyLinked() bool
diff --git a/cc/makevars.go b/cc/makevars.go
index 6752f8c..8154436 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -25,7 +25,7 @@
)
var (
- modulesAddedWallKey = android.NewOnceKey("ModulesAddedWall")
+ modulesWarningsAllowedKey = android.NewOnceKey("ModulesWarningsAllowed")
modulesUsingWnoErrorKey = android.NewOnceKey("ModulesUsingWnoError")
modulesMissingProfileFileKey = android.NewOnceKey("ModulesMissingProfileFile")
)
@@ -119,7 +119,7 @@
ctx.Strict("LSDUMP_PATHS", strings.Join(lsdumpPaths, " "))
ctx.Strict("ANDROID_WARNING_ALLOWED_PROJECTS", makeStringOfWarningAllowedProjects())
- ctx.Strict("SOONG_MODULES_ADDED_WALL", makeStringOfKeys(ctx, modulesAddedWallKey))
+ ctx.Strict("SOONG_MODULES_WARNINGS_ALLOWED", makeStringOfKeys(ctx, modulesWarningsAllowedKey))
ctx.Strict("SOONG_MODULES_USING_WNO_ERROR", makeStringOfKeys(ctx, modulesUsingWnoErrorKey))
ctx.Strict("SOONG_MODULES_MISSING_PGO_PROFILE_FILE", makeStringOfKeys(ctx, modulesMissingProfileFileKey))
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 53169de..87cee9f 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -276,7 +276,7 @@
type SanitizeProperties struct {
Sanitize SanitizeUserProps `android:"arch_variant"`
SanitizerEnabled bool `blueprint:"mutated"`
- SanitizeDep bool `blueprint:"mutated"`
+ SanitizeDepTypes []SanitizerType `blueprint:"mutated"`
MinimalRuntimeDep bool `blueprint:"mutated"`
BuiltinsDep bool `blueprint:"mutated"`
UbsanRuntimeDep bool `blueprint:"mutated"`
@@ -944,7 +944,7 @@
// determine defaultVariation in sanitizerMutator below.
// Instead, just mark SanitizeDep to forcefully create cfi variant.
enabled = true
- c.SetSanitizeDep(true)
+ c.SetSanitizeDep(t)
}
if enabled {
isSanitizableDependencyTag := c.SanitizableDepTagChecker()
@@ -959,32 +959,30 @@
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.
- d.SetSanitizeDep(true)
+ d.SetSanitizeDep(t)
}
} else {
- d.SetSanitizeDep(true)
+ d.SetSanitizeDep(t)
}
}
return true
})
}
- } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
+ } else if jniSanitizeable, ok := mctx.Module().(JniSanitizeable); ok {
// If it's a Java module with native dependencies through jni,
// set the sanitizer for them
- if jniSanitizeable, ok := mctx.Module().(JniSanitizeable); ok {
- if jniSanitizeable.IsSanitizerEnabledForJni(mctx, t.name()) {
- mctx.VisitDirectDeps(func(child android.Module) {
- if c, ok := child.(PlatformSanitizeable); ok &&
- mctx.OtherModuleDependencyTag(child) == JniFuzzLibTag &&
- c.SanitizePropDefined() &&
- !c.SanitizeNever() &&
- !c.IsSanitizerExplicitlyDisabled(t) {
- c.SetSanitizeDep(true)
- }
- })
- }
+ if jniSanitizeable.IsSanitizerEnabledForJni(mctx, t.name()) {
+ mctx.VisitDirectDeps(func(child android.Module) {
+ if c, ok := child.(PlatformSanitizeable); ok &&
+ mctx.OtherModuleDependencyTag(child) == JniFuzzLibTag &&
+ c.SanitizePropDefined() &&
+ !c.SanitizeNever() &&
+ !c.IsSanitizerExplicitlyDisabled(t) {
+ c.SetSanitizeDep(t)
+ }
+ })
}
-
+ } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
// If an APEX module includes a lib which is enabled for a sanitizer T, then
// the APEX module is also enabled for the same sanitizer type.
mctx.VisitDirectDeps(func(child android.Module) {
@@ -1317,8 +1315,14 @@
return c.sanitize.isSanitizerEnabled(t)
}
-func (c *Module) SanitizeDep() bool {
- return c.sanitize.Properties.SanitizeDep
+func (c *Module) SanitizeDep(t SanitizerType) bool {
+ for _, e := range c.sanitize.Properties.SanitizeDepTypes {
+ if t == e {
+ return true
+ }
+ }
+
+ return false
}
func (c *Module) StaticallyLinked() bool {
@@ -1337,9 +1341,9 @@
}
}
-func (c *Module) SetSanitizeDep(b bool) {
- if c.sanitize != nil {
- c.sanitize.Properties.SanitizeDep = b
+func (c *Module) SetSanitizeDep(t SanitizerType) {
+ if !c.SanitizeDep(t) {
+ c.sanitize.Properties.SanitizeDepTypes = append(c.sanitize.Properties.SanitizeDepTypes, t)
}
}
@@ -1356,7 +1360,7 @@
if c.Binary() && c.IsSanitizerEnabled(t) {
modules := mctx.CreateVariations(t.variationName())
modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
- } else if c.IsSanitizerEnabled(t) || c.SanitizeDep() {
+ } else if c.IsSanitizerEnabled(t) || c.SanitizeDep(t) {
isSanitizerEnabled := c.IsSanitizerEnabled(t)
if c.StaticallyLinked() || c.Header() || t == Fuzzer {
// Static and header libs are split into non-sanitized and sanitized variants.
@@ -1378,8 +1382,6 @@
modules := mctx.CreateVariations("", t.variationName())
modules[0].(PlatformSanitizeable).SetSanitizer(t, false)
modules[1].(PlatformSanitizeable).SetSanitizer(t, true)
- modules[0].(PlatformSanitizeable).SetSanitizeDep(false)
- modules[1].(PlatformSanitizeable).SetSanitizeDep(false)
if mctx.Device() && t.incompatibleWithCfi() && cfiSupported {
// TODO: Make sure that cfi mutator runs "after" any of the sanitizers that
@@ -1412,7 +1414,6 @@
// Shared libs are not split. Only the sanitized variant is created.
modules := mctx.CreateVariations(t.variationName())
modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
- modules[0].(PlatformSanitizeable).SetSanitizeDep(false)
// locate the asan libraries under /data/asan
if mctx.Device() && t == Asan && isSanitizerEnabled {
@@ -1426,7 +1427,6 @@
}
}
}
- c.SetSanitizeDep(false)
} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok && sanitizeable.IsSanitizerEnabled(mctx, t.name()) {
// APEX and Java fuzz modules fall here
sanitizeable.AddSanitizerDependencies(mctx, t.name())
@@ -1529,12 +1529,10 @@
if !Bool(sanitize.Properties.Sanitize.Address) &&
!Bool(sanitize.Properties.Sanitize.Hwaddress) &&
!Bool(sanitize.Properties.Sanitize.Fuzzer) &&
-
(Bool(sanitize.Properties.Sanitize.Integer_overflow) ||
len(sanitize.Properties.Sanitize.Misc_undefined) > 0 ||
Bool(sanitize.Properties.Sanitize.Undefined) ||
Bool(sanitize.Properties.Sanitize.All_undefined)) &&
-
!(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
Bool(sanitize.Properties.Sanitize.Diag.Cfi) ||
Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
diff --git a/java/androidmk.go b/java/androidmk.go
index 439b1d1..330e594 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -324,7 +324,7 @@
}
func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
- if app.hideApexVariantFromMake || app.appProperties.HideFromMake {
+ if app.hideApexVariantFromMake || app.IsHideFromMake() {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Disabled: true,
}}
@@ -424,8 +424,8 @@
func (a *AndroidApp) getOverriddenPackages() []string {
var overridden []string
- if len(a.appProperties.Overrides) > 0 {
- overridden = append(overridden, a.appProperties.Overrides...)
+ if len(a.overridableAppProperties.Overrides) > 0 {
+ overridden = append(overridden, a.overridableAppProperties.Overrides...)
}
// When APK name is overridden via PRODUCT_PACKAGE_NAME_OVERRIDES
// ensure that the original name is overridden.
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 246c0eb..197da4f 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -206,3 +206,49 @@
t.Errorf("Unexpected flag value - expected: %q, actual: %q", expected, actual)
}
}
+
+func TestGetOverriddenPackages(t *testing.T) {
+ ctx, _ := testJava(
+ t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ overrides: ["qux"]
+ }
+
+ override_android_app {
+ name: "foo_override",
+ base: "foo",
+ overrides: ["bar"]
+ }
+ `)
+
+ expectedVariants := []struct {
+ name string
+ moduleName string
+ variantName string
+ overrides []string
+ }{
+ {
+ name: "foo",
+ moduleName: "foo",
+ variantName: "android_common",
+ overrides: []string{"qux"},
+ },
+ {
+ name: "foo",
+ moduleName: "foo_override",
+ variantName: "android_common_foo_override",
+ overrides: []string{"bar", "foo"},
+ },
+ }
+
+ for _, expected := range expectedVariants {
+ mod := ctx.ModuleForTests(expected.name, expected.variantName).Module()
+ entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
+ actual := entries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
+
+ android.AssertDeepEquals(t, "overrides property", expected.overrides, actual)
+ }
+}
diff --git a/java/app.go b/java/app.go
index 5f14cef..da496f1 100755
--- a/java/app.go
+++ b/java/app.go
@@ -63,13 +63,6 @@
// list of resource labels to generate individual resource packages
Package_splits []string
- // Names of modules to be overridden. Listed modules can only be other binaries
- // (in Make or Soong).
- // This does not completely prevent installation of the overridden binaries, but if both
- // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
- // from PRODUCT_PACKAGES.
- Overrides []string
-
// list of native libraries that will be provided in or alongside the resulting jar
Jni_libs []string `android:"arch_variant"`
@@ -106,7 +99,6 @@
// cc.Coverage related properties
PreventInstall bool `blueprint:"mutated"`
- HideFromMake bool `blueprint:"mutated"`
IsCoverageVariant bool `blueprint:"mutated"`
// Whether this app is considered mainline updatable or not. When set to true, this will enforce
@@ -133,6 +125,13 @@
// Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
Rename_resources_package *bool
+
+ // Names of modules to be overridden. Listed modules can only be other binaries
+ // (in Make or Soong).
+ // This does not completely prevent installation of the overridden binaries, but if both
+ // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
+ // from PRODUCT_PACKAGES.
+ Overrides []string
}
type AndroidApp struct {
@@ -582,18 +581,6 @@
}
a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
- if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
- noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
- android.BuildNoticeHtmlOutputFromLicenseMetadata(ctx, noticeFile)
- noticeAssetPath := android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
- builder := android.NewRuleBuilder(pctx, ctx)
- builder.Command().Text("cp").
- Input(noticeFile).
- Output(noticeAssetPath)
- builder.Build("notice_dir", "Building notice dir")
- a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
- }
-
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
// Process all building blocks, from AAPT to certificates.
@@ -667,6 +654,18 @@
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
}
+ if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
+ noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
+ android.BuildNoticeHtmlOutputFromLicenseMetadata(ctx, noticeFile, "", a.outputFile.String())
+ noticeAssetPath := android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("cp").
+ Input(noticeFile).
+ Output(noticeAssetPath)
+ builder.Build("notice_dir", "Building notice dir")
+ a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
+ }
+
for _, split := range a.aapt.splits {
// Sign the split APKs
packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
@@ -880,10 +879,6 @@
a.appProperties.PreventInstall = true
}
-func (a *AndroidApp) HideFromMake() {
- a.appProperties.HideFromMake = true
-}
-
func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
a.appProperties.IsCoverageVariant = coverage
}
@@ -913,7 +908,7 @@
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
- android.InitOverridableModule(module, &module.appProperties.Overrides)
+ android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
android.InitApexModule(module)
android.InitBazelModule(module)
@@ -1037,7 +1032,7 @@
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
- android.InitOverridableModule(module, &module.appProperties.Overrides)
+ android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
return module
}
diff --git a/java/app_test.go b/java/app_test.go
index b83a333..c4ac4df 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1966,7 +1966,7 @@
// Check if the overrides field values are correctly aggregated.
mod := variant.Module().(*AndroidApp)
- android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.appProperties.Overrides)
+ android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
// Test Overridable property: Logging_parent
logging_parent := mod.aapt.LoggingParent
@@ -1984,6 +1984,99 @@
}
}
+func TestOverrideAndroidAppOverrides(t *testing.T) {
+ ctx, _ := testJava(
+ t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ overrides: ["qux"]
+ }
+
+ android_app {
+ name: "bar",
+ srcs: ["b.java"],
+ sdk_version: "current",
+ overrides: ["foo"]
+ }
+
+ override_android_app {
+ name: "foo_override",
+ base: "foo",
+ overrides: ["bar"]
+ }
+ `)
+
+ expectedVariants := []struct {
+ name string
+ moduleName string
+ variantName string
+ overrides []string
+ }{
+ {
+ name: "foo",
+ moduleName: "foo",
+ variantName: "android_common",
+ overrides: []string{"qux"},
+ },
+ {
+ name: "bar",
+ moduleName: "bar",
+ variantName: "android_common",
+ overrides: []string{"foo"},
+ },
+ {
+ name: "foo",
+ moduleName: "foo_override",
+ variantName: "android_common_foo_override",
+ overrides: []string{"bar", "foo"},
+ },
+ }
+ for _, expected := range expectedVariants {
+ variant := ctx.ModuleForTests(expected.name, expected.variantName)
+
+ // Check if the overrides field values are correctly aggregated.
+ mod := variant.Module().(*AndroidApp)
+ android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
+ }
+}
+
+func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
+ result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
+ t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }
+
+ override_android_app {
+ name: "bar",
+ base: "foo",
+ }
+
+ android_app_import {
+ name: "bar",
+ prefer: true,
+ apk: "bar.apk",
+ presigned: true,
+ }
+ `)
+
+ // An app that has an override that also has a prebuilt should not be hidden.
+ foo := result.ModuleForTests("foo", "android_common")
+ if foo.Module().IsHideFromMake() {
+ t.Errorf("expected foo to have HideFromMake false")
+ }
+
+ // An override that also has a prebuilt should be hidden.
+ barOverride := result.ModuleForTests("foo", "android_common_bar")
+ if !barOverride.Module().IsHideFromMake() {
+ t.Errorf("expected bar override variant of foo to have HideFromMake true")
+ }
+}
+
func TestOverrideAndroidAppStem(t *testing.T) {
ctx, _ := testJava(t, `
android_app {
@@ -2164,9 +2257,9 @@
// Check if the overrides field values are correctly aggregated.
mod := variant.Module().(*AndroidTest)
- if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
+ if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) {
t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
- expected.overrides, mod.appProperties.Overrides)
+ expected.overrides, mod.overridableAppProperties.Overrides)
}
// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
diff --git a/java/fuzz.go b/java/fuzz.go
index 584c80b..cf2c981 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -50,9 +50,10 @@
jniFilePaths android.Paths
}
-// IsSanitizerEnabled implemented to make JavaFuzzLibrary implement
-// cc.Sanitizeable
-func (j *JavaFuzzLibrary) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
+// IsSanitizerEnabledForJni implemented to make JavaFuzzLibrary implement
+// cc.JniSanitizeable. It returns a bool for whether a cc dependency should be
+// sanitized for the given sanitizer or not.
+func (j *JavaFuzzLibrary) IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool {
for _, s := range j.jniProperties.Sanitizers {
if sanitizerName == s {
return true
@@ -61,26 +62,6 @@
return false
}
-// IsSanitizerEnabledForJni implemented to make JavaFuzzLibrary implement
-// cc.JniSanitizeable. It returns a bool for whether a cc dependency should be
-// sanitized for the given sanitizer or not.
-func (j *JavaFuzzLibrary) IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool {
- return j.IsSanitizerEnabled(ctx, sanitizerName)
-}
-
-// EnableSanitizer implemented to make JavaFuzzLibrary implement
-// cc.Sanitizeable
-func (j *JavaFuzzLibrary) EnableSanitizer(sanitizerName string) {
-}
-
-// AddSanitizerDependencies implemented to make JavaFuzzLibrary implement
-// cc.Sanitizeable
-func (j *JavaFuzzLibrary) AddSanitizerDependencies(mctx android.BottomUpMutatorContext, sanitizerName string) {
-}
-
-// To verify that JavaFuzzLibrary implements cc.Sanitizeable
-var _ cc.Sanitizeable = (*JavaFuzzLibrary)(nil)
-
func (j *JavaFuzzLibrary) DepsMutator(mctx android.BottomUpMutatorContext) {
if len(j.jniProperties.Jni_libs) > 0 {
if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
diff --git a/java/java.go b/java/java.go
index 079d4b9..4476cec 100644
--- a/java/java.go
+++ b/java/java.go
@@ -592,12 +592,14 @@
}
j.checkSdkVersions(ctx)
- j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
- ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
- j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
- j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
- j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ if ctx.Device() {
+ j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
+ ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
+ j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
+ j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
+ j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ }
j.compile(ctx, nil)
// Collect the module directory for IDE info in java/jdeps.go.
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 39aaf33..aadc00f 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -49,8 +49,8 @@
Memtag_heap *bool `android:"arch_variant"`
}
}
- SanitizerEnabled bool `blueprint:"mutated"`
- SanitizeDep bool `blueprint:"mutated"`
+ SanitizerEnabled bool `blueprint:"mutated"`
+ SanitizeDepTypes []cc.SanitizerType `blueprint:"mutated"`
// Used when we need to place libraries in their own directory, such as ASAN.
InSanitizerDir bool `blueprint:"mutated"`
@@ -444,8 +444,14 @@
return mod.sanitize.isSanitizerExplicitlyDisabled(t)
}
-func (mod *Module) SanitizeDep() bool {
- return mod.sanitize.Properties.SanitizeDep
+func (mod *Module) SanitizeDep(t cc.SanitizerType) bool {
+ for _, e := range mod.sanitize.Properties.SanitizeDepTypes {
+ if t == e {
+ return true
+ }
+ }
+
+ return false
}
func (mod *Module) SetSanitizer(t cc.SanitizerType, b bool) {
@@ -454,8 +460,10 @@
}
}
-func (mod *Module) SetSanitizeDep(b bool) {
- mod.sanitize.Properties.SanitizeDep = b
+func (c *Module) SetSanitizeDep(t cc.SanitizerType) {
+ if !c.SanitizeDep(t) {
+ c.sanitize.Properties.SanitizeDepTypes = append(c.sanitize.Properties.SanitizeDepTypes, t)
+ }
}
func (mod *Module) StaticallyLinked() bool {
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 74e49aa..78ddced 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -169,3 +169,29 @@
}
test_cc_correctness
+
+# Regression test for the following failure during symlink forest creation:
+#
+# Cannot stat '/tmp/st.rr054/foo/bar/unresolved_symlink': stat /tmp/st.rr054/foo/bar/unresolved_symlink: no such file or directory
+#
+function test_bp2build_null_build_with_unresolved_symlink_in_source() {
+ setup
+
+ mkdir -p foo/bar
+ ln -s /tmp/non-existent foo/bar/unresolved_symlink
+ cat > foo/bar/Android.bp <<'EOF'
+filegroup {
+ name: "fg",
+ srcs: ["unresolved_symlink/non-existent-file.txt"],
+ }
+EOF
+
+ run_soong bp2build
+
+ dest=$(readlink -f out/soong/workspace/foo/bar/unresolved_symlink)
+ if [[ "$dest" != "/tmp/non-existent" ]]; then
+ fail "expected to plant an unresolved symlink out/soong/workspace/foo/bar/unresolved_symlink that resolves to /tmp/non-existent"
+ fi
+}
+
+test_bp2build_null_build_with_unresolved_symlink_in_source
diff --git a/tests/lib.sh b/tests/lib.sh
index 7fd970a..abe84d3 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -127,6 +127,10 @@
}
run_bazel() {
+ # Remove the ninja_build output marker file to communicate to buildbot that this is not a regular Ninja build, and its
+ # output should not be parsed as such.
+ rm -rf out/ninja_build
+
tools/bazel "$@"
}