Merge "re-trigger symlink-forest if bazel.list changes"
diff --git a/android/arch.go b/android/arch.go
index 086e945..6acf9cf 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -16,6 +16,7 @@
import (
"encoding"
+ "encoding/json"
"fmt"
"reflect"
"runtime"
@@ -1681,10 +1682,10 @@
// archConfig describes a built-in configuration.
type archConfig struct {
- arch string
- archVariant string
- cpuVariant string
- abi []string
+ Arch string `json:"arch"`
+ ArchVariant string `json:"arch_variant"`
+ CpuVariant string `json:"cpu_variant"`
+ Abi []string `json:"abis"`
}
// getNdkAbisConfig returns the list of archConfigs that are used for building
@@ -1713,8 +1714,8 @@
var ret []Target
for _, config := range archConfigs {
- arch, err := decodeArch(Android, config.arch, &config.archVariant,
- &config.cpuVariant, config.abi)
+ arch, err := decodeArch(Android, config.Arch, &config.ArchVariant,
+ &config.CpuVariant, config.Abi)
if err != nil {
return nil, err
}
@@ -2284,6 +2285,14 @@
return starlark_fmt.PrintDict(valDict, 0)
}
+func printArchConfigList(arches []archConfig) string {
+ jsonOut, err := json.MarshalIndent(arches, "", starlark_fmt.Indention(1))
+ if err != nil {
+ panic(fmt.Errorf("Error converting arch configs %#v to json: %q", arches, err))
+ }
+ return fmt.Sprintf("json.decode('''%s''')", string(jsonOut))
+}
+
func StarlarkArchConfigurations() string {
return fmt.Sprintf(`
_arch_to_variants = %s
@@ -2294,13 +2303,21 @@
_android_arch_feature_for_arch_variant = %s
+_aml_arches = %s
+
+_ndk_arches = %s
+
arch_to_variants = _arch_to_variants
arch_to_cpu_variants = _arch_to_cpu_variants
arch_to_features = _arch_to_features
android_arch_feature_for_arch_variants = _android_arch_feature_for_arch_variant
+aml_arches = _aml_arches
+ndk_arches = _ndk_arches
`, printArchTypeStarlarkDict(archVariants),
printArchTypeStarlarkDict(cpuVariants),
printArchTypeStarlarkDict(archFeatures),
printArchTypeNestedStarlarkDict(androidArchFeatureMap),
+ printArchConfigList(getAmlAbisConfig()),
+ printArchConfigList(getNdkAbisConfig()),
)
}
diff --git a/android/gen_notice.go b/android/gen_notice.go
index 008aac5..28fddbc 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -61,6 +61,9 @@
if mod == nil {
continue
}
+ if !mod.Enabled() { // don't depend on variants without build rules
+ continue
+ }
modules = append(modules, mod)
}
}
diff --git a/android/sdk.go b/android/sdk.go
index bd2f5d1..fc0a84e 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -232,12 +232,6 @@
// relative path) and add the dest to the zip.
CopyToSnapshot(src Path, dest string)
- // EmptyFile returns the path to an empty file.
- //
- // This can be used by sdk member types that need to create an empty file in the snapshot, simply
- // pass the value returned from this to the CopyToSnapshot() method.
- EmptyFile() Path
-
// UnzipToSnapshot generates a rule that will unzip the supplied zip into the snapshot relative
// directory destDir.
UnzipToSnapshot(zipPath Path, destDir string)
@@ -264,6 +258,14 @@
// See sdk/update.go for more information.
AddPrebuiltModule(member SdkMember, moduleType string) BpModule
+ // AddInternalModule creates a new module in the generated Android.bp file that can only be
+ // referenced by one of the other modules in the snapshot.
+ //
+ // The created module's name is constructed by concatenating the name of this member and the
+ // nameSuffix, separated by "-". It also has the visibility property set to "//visibility:private"
+ // to prevent it from being inadvertently accessed from outside the snapshot.
+ AddInternalModule(properties SdkMemberProperties, moduleType string, nameSuffix string) BpModule
+
// SdkMemberReferencePropertyTag returns a property tag to use when adding a property to a
// BpModule that contains references to other sdk members.
//
@@ -922,6 +924,12 @@
//
// Contains common properties that apply across many different member types.
type SdkMemberPropertiesBase struct {
+ // The name of the member.
+ //
+ // Ignore this property during optimization. This is needed because this property is the same for
+ // all variants of a member and so would be optimized away if it was not ignored.
+ MemberName string `sdk:"ignore"`
+
// The number of unique os types supported by the member variants.
//
// If a member has a variant with more than one os type then it will need to differentiate
@@ -945,6 +953,10 @@
Compile_multilib string `android:"arch_variant"`
}
+func (b *SdkMemberPropertiesBase) Name() string {
+ return b.MemberName
+}
+
// OsPrefix returns the os prefix to use for any file paths in the sdk.
//
// Is an empty string if the member only provides variants for a single os type, otherwise
@@ -970,6 +982,8 @@
// Base returns the base structure.
Base() *SdkMemberPropertiesBase
+ Name() string
+
// PopulateFromVariant populates this structure with information from a module variant.
//
// It will typically be called once for each variant of a member module that the SDK depends upon.
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index 825be7f..67208b2 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -32,7 +32,6 @@
riscv64Ldflags = []string{
"-Wl,--hash-style=gnu",
- "-Wl,-z,separate-code",
}
riscv64Lldflags = append(riscv64Ldflags,
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 028ca44..e158814 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -111,7 +111,6 @@
func newContext(configuration android.Config) *android.Context {
ctx := android.NewContext(configuration)
- ctx.Register()
ctx.SetNameInterface(newNameResolver(configuration))
ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
return ctx
@@ -153,7 +152,7 @@
// Bazel-enabled mode. Attaches a mutator to queue Bazel requests, adds a
// BeforePrepareBuildActionsHook to invoke Bazel, and then uses Bazel metadata
// for modules that should be handled by Bazel.
-func runMixedModeBuild(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) {
+func runMixedModeBuild(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) string {
ctx.EventHandler.Begin("mixed_build")
defer ctx.EventHandler.End("mixed_build")
@@ -176,6 +175,7 @@
ninjaDeps = append(ninjaDeps, globListFiles...)
writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
+ return cmdlineArgs.OutFile
}
// Run the code-generation phase to convert BazelTargetModules to BUILD files.
@@ -194,12 +194,11 @@
// Run the code-generation phase to convert API contributions to BUILD files.
// Return marker file for the new synthetic workspace
-func runApiBp2build(configuration android.Config, extraNinjaDeps []string) string {
- // Create a new context and register mutators that are only meaningful to API export
- ctx := android.NewContext(configuration)
+func runApiBp2build(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) string {
ctx.EventHandler.Begin("api_bp2build")
defer ctx.EventHandler.End("api_bp2build")
- ctx.SetNameInterface(newNameResolver(configuration))
+ // Do not allow missing dependencies.
+ ctx.SetAllowMissingDependencies(false)
ctx.RegisterForApiBazelConversion()
// Register the Android.bp files in the tree
@@ -337,61 +336,77 @@
// output file of the specific activity.
func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, metricsDir string) string {
if configuration.BuildMode == android.SymlinkForest {
- runSymlinkForestCreation(configuration, extraNinjaDeps, metricsDir)
- return symlinkForestMarker
+ return runSymlinkForestCreation(configuration, ctx, extraNinjaDeps, metricsDir)
} else if configuration.BuildMode == android.Bp2build {
// Run the alternate pipeline of bp2build mutators and singleton to convert
// Blueprint to BUILD files before everything else.
- runBp2Build(configuration, extraNinjaDeps, metricsDir)
- return bp2buildMarker
- } else if configuration.IsMixedBuildsEnabled() {
- runMixedModeBuild(configuration, ctx, extraNinjaDeps)
+ return runBp2Build(configuration, ctx, extraNinjaDeps, metricsDir)
} else if configuration.BuildMode == android.ApiBp2build {
- return runApiBp2build(configuration, extraNinjaDeps)
+ outputFile := runApiBp2build(configuration, ctx, extraNinjaDeps)
+ writeMetrics(configuration, ctx.EventHandler, metricsDir)
+ return outputFile
} else {
- var stopBefore bootstrap.StopBefore
- if configuration.BuildMode == android.GenerateModuleGraph {
- stopBefore = bootstrap.StopBeforeWriteNinja
- } else if configuration.BuildMode == android.GenerateQueryView || configuration.BuildMode == android.GenerateDocFile {
- stopBefore = bootstrap.StopBeforePrepareBuildActions
+ ctx.Register()
+
+ var outputFile string
+ if configuration.IsMixedBuildsEnabled() {
+ outputFile = runMixedModeBuild(configuration, ctx, extraNinjaDeps)
} else {
- stopBefore = bootstrap.DoEverything
+ outputFile = runSoongOnlyBuild(configuration, ctx, extraNinjaDeps)
}
- ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs, stopBefore, ctx.Context, configuration)
- ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+ writeMetrics(configuration, ctx.EventHandler, metricsDir)
- globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
- ninjaDeps = append(ninjaDeps, globListFiles...)
+ return outputFile
+ }
+}
- // Convert the Soong module graph into Bazel BUILD files.
- if configuration.BuildMode == android.GenerateQueryView {
- queryviewMarkerFile := bazelQueryViewDir + ".marker"
- runQueryView(bazelQueryViewDir, queryviewMarkerFile, configuration, ctx)
- writeDepFile(queryviewMarkerFile, ctx.EventHandler, ninjaDeps)
- return queryviewMarkerFile
- } else if configuration.BuildMode == android.GenerateModuleGraph {
- writeJsonModuleGraphAndActions(ctx, moduleGraphFile, moduleActionsFile)
- writeDepFile(moduleGraphFile, ctx.EventHandler, ninjaDeps)
- return moduleGraphFile
- } else if configuration.BuildMode == android.GenerateDocFile {
- // TODO: we could make writeDocs() return the list of documentation files
- // written and add them to the .d file. Then soong_docs would be re-run
- // whenever one is deleted.
- if err := writeDocs(ctx, shared.JoinPath(topDir, docFile)); err != nil {
- fmt.Fprintf(os.Stderr, "error building Soong documentation: %s\n", err)
- os.Exit(1)
- }
- writeDepFile(docFile, ctx.EventHandler, ninjaDeps)
- return docFile
- } else {
- // The actual output (build.ninja) was written in the RunBlueprint() call
- // above
- writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
- }
+// runSoongOnlyBuild runs the standard Soong build in a number of different modes.
+func runSoongOnlyBuild(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) string {
+ ctx.EventHandler.Begin("soong_build")
+ defer ctx.EventHandler.End("soong_build")
+
+ var stopBefore bootstrap.StopBefore
+ if configuration.BuildMode == android.GenerateModuleGraph {
+ stopBefore = bootstrap.StopBeforeWriteNinja
+ } else if configuration.BuildMode == android.GenerateQueryView || configuration.BuildMode == android.GenerateDocFile {
+ stopBefore = bootstrap.StopBeforePrepareBuildActions
+ } else {
+ stopBefore = bootstrap.DoEverything
}
- return cmdlineArgs.OutFile
+ ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs, stopBefore, ctx.Context, configuration)
+ ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+
+ globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
+ ninjaDeps = append(ninjaDeps, globListFiles...)
+
+ // Convert the Soong module graph into Bazel BUILD files.
+ if configuration.BuildMode == android.GenerateQueryView {
+ queryviewMarkerFile := bazelQueryViewDir + ".marker"
+ runQueryView(bazelQueryViewDir, queryviewMarkerFile, configuration, ctx)
+ writeDepFile(queryviewMarkerFile, ctx.EventHandler, ninjaDeps)
+ return queryviewMarkerFile
+ } else if configuration.BuildMode == android.GenerateModuleGraph {
+ writeJsonModuleGraphAndActions(ctx, moduleGraphFile, moduleActionsFile)
+ writeDepFile(moduleGraphFile, ctx.EventHandler, ninjaDeps)
+ return moduleGraphFile
+ } else if configuration.BuildMode == android.GenerateDocFile {
+ // TODO: we could make writeDocs() return the list of documentation files
+ // written and add them to the .d file. Then soong_docs would be re-run
+ // whenever one is deleted.
+ if err := writeDocs(ctx, shared.JoinPath(topDir, docFile)); err != nil {
+ fmt.Fprintf(os.Stderr, "error building Soong documentation: %s\n", err)
+ os.Exit(1)
+ }
+ writeDepFile(docFile, ctx.EventHandler, ninjaDeps)
+ return docFile
+ } else {
+ // The actual output (build.ninja) was written in the RunBlueprint() call
+ // above
+ writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
+ return cmdlineArgs.OutFile
+ }
}
// soong_ui dumps the available environment variables to
@@ -451,13 +466,9 @@
logDir := availableEnv["LOG_DIR"]
ctx := newContext(configuration)
- ctx.EventHandler.Begin("soong_build")
finalOutputFile := doChosenActivity(ctx, configuration, extraNinjaDeps, logDir)
- ctx.EventHandler.End("soong_build")
- writeMetrics(configuration, ctx.EventHandler, logDir)
-
writeUsedEnvironmentFile(configuration, finalOutputFile)
}
@@ -602,9 +613,7 @@
// Ideally, bp2build would write a file that contains instructions to the
// symlink tree creation binary. Then the latter would not need to depend on
// the very heavy-weight machinery of soong_build .
-func runSymlinkForestCreation(configuration android.Config, extraNinjaDeps []string, metricsDir string) {
- eventHandler := &metrics.EventHandler{}
-
+func runSymlinkForestCreation(configuration android.Config, ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
var ninjaDeps []string
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
@@ -631,13 +640,13 @@
// Such a directory SHOULD be added to `ninjaDeps` so that a child directory
// or file created/deleted under it would trigger an update of the symlink
// forest.
- eventHandler.Do("symlink_forest", func() {
+ ctx.EventHandler.Do("symlink_forest", func() {
symlinkForestDeps := bp2build.PlantSymlinkForest(
configuration.IsEnvTrue("BP2BUILD_VERBOSE"), topDir, workspaceRoot, generatedRoot, excludes)
ninjaDeps = append(ninjaDeps, symlinkForestDeps...)
})
- writeDepFile(symlinkForestMarker, eventHandler, ninjaDeps)
+ writeDepFile(symlinkForestMarker, ctx.EventHandler, ninjaDeps)
touch(shared.JoinPath(topDir, symlinkForestMarker))
codegenMetrics := bp2build.ReadCodegenMetrics(metricsDir)
if codegenMetrics == nil {
@@ -647,27 +656,24 @@
//TODO (usta) we cannot determine if we loaded a stale file, i.e. from an unrelated prior
//invocation of codegen. We should simply use a separate .pb file
}
- writeBp2BuildMetrics(codegenMetrics, eventHandler, metricsDir)
+ writeBp2BuildMetrics(codegenMetrics, ctx.EventHandler, metricsDir)
+
+ return symlinkForestMarker
}
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
-func runBp2Build(configuration android.Config, extraNinjaDeps []string, metricsDir string) {
+func runBp2Build(configuration android.Config, ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
var codegenMetrics *bp2build.CodegenMetrics
- eventHandler := &metrics.EventHandler{}
- eventHandler.Do("bp2build", func() {
-
- // Register an alternate set of singletons and mutators for bazel
- // conversion for Bazel conversion.
- bp2buildCtx := android.NewContext(configuration)
+ ctx.EventHandler.Do("bp2build", func() {
// Propagate "allow misssing dependencies" bit. This is normally set in
- // newContext(), but we create bp2buildCtx without calling that method.
- bp2buildCtx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
- bp2buildCtx.SetNameInterface(newNameResolver(configuration))
- bp2buildCtx.RegisterForBazelConversion()
- bp2buildCtx.SetModuleListFile(cmdlineArgs.ModuleListFile)
+ // newContext(), but we create ctx without calling that method.
+ ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
+ ctx.SetNameInterface(newNameResolver(configuration))
+ ctx.RegisterForBazelConversion()
+ ctx.SetModuleListFile(cmdlineArgs.ModuleListFile)
var ninjaDeps []string
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
@@ -675,25 +681,25 @@
// Run the loading and analysis pipeline to prepare the graph of regular
// Modules parsed from Android.bp files, and the BazelTargetModules mapped
// from the regular Modules.
- eventHandler.Do("bootstrap", func() {
+ ctx.EventHandler.Do("bootstrap", func() {
blueprintArgs := cmdlineArgs
- bootstrapDeps := bootstrap.RunBlueprint(blueprintArgs, bootstrap.StopBeforePrepareBuildActions, bp2buildCtx.Context, configuration)
+ bootstrapDeps := bootstrap.RunBlueprint(blueprintArgs, bootstrap.StopBeforePrepareBuildActions, ctx.Context, configuration)
ninjaDeps = append(ninjaDeps, bootstrapDeps...)
})
- globListFiles := writeBuildGlobsNinjaFile(bp2buildCtx, configuration.SoongOutDir(), configuration)
+ globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
ninjaDeps = append(ninjaDeps, globListFiles...)
// Run the code-generation phase to convert BazelTargetModules to BUILD files
// and print conversion codegenMetrics to the user.
- codegenContext := bp2build.NewCodegenContext(configuration, bp2buildCtx, bp2build.Bp2Build)
- eventHandler.Do("codegen", func() {
+ codegenContext := bp2build.NewCodegenContext(configuration, ctx, bp2build.Bp2Build)
+ ctx.EventHandler.Do("codegen", func() {
codegenMetrics = bp2build.Codegen(codegenContext)
})
ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
- writeDepFile(bp2buildMarker, eventHandler, ninjaDeps)
+ writeDepFile(bp2buildMarker, ctx.EventHandler, ninjaDeps)
touch(shared.JoinPath(topDir, bp2buildMarker))
})
@@ -703,7 +709,8 @@
if configuration.IsEnvTrue("BP2BUILD_VERBOSE") {
codegenMetrics.Print()
}
- writeBp2BuildMetrics(codegenMetrics, eventHandler, metricsDir)
+ writeBp2BuildMetrics(codegenMetrics, ctx.EventHandler, metricsDir)
+ return bp2buildMarker
}
// Write Bp2Build metrics into $LOG_DIR
diff --git a/java/base.go b/java/base.go
index 602e8d8..5d24981 100644
--- a/java/base.go
+++ b/java/base.go
@@ -868,7 +868,7 @@
flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
sdkVersion := (j.SdkVersion(ctx)).Kind
- defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform))
+ defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule))
if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
flags = append(flags, "-t")
}
diff --git a/java/invalid_implementation_jar.sh b/java/invalid_implementation_jar.sh
new file mode 100755
index 0000000..3820058
--- /dev/null
+++ b/java/invalid_implementation_jar.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+# Copyright 2022 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.
+
+# Script to detect and report an attempt to access an invalid implementation
+# jar.
+
+MOD=$1
+
+cat <<EOF
+
+ $MOD is a java_library that generates a jar file which must not be accessed
+ from outside the mainline module that provides it. If you are seeing this
+ message it means that you are incorrectly attempting to use the jar file
+ from a java_import prebuilt of $MOD.
+
+ This is most likely due to an incorrect dependency on $MOD in an Android.mk
+ or Android.bp file. Please remove that dependency and replace with
+ something more appropriate, e.g. a dependency on an API provided by the
+ module.
+
+ If you do not know where the extraneous dependency was added then you can
+ run the following command to find a list of all the paths from the target
+ which you are trying to build to the target which produced this error.
+
+ prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-\${TARGET_PRODUCT}.ninja -t path <target> <invalid-jar>
+
+ Where <target> is the build target you specified on the command line which
+ produces this error and <invalid-jar> is the rule that failed with this
+ message. If you are specifying multiple build targets then you will need to
+ run the above command for every target until you find the cause.
+
+ The command will output one (of the possibly many) dependency paths from
+ <target> to <invalid-jar>, one file/phony target per line. e.g. it may
+ output something like this:
+
+ ....
+ out/soong/.intermediates/acme/broken/android_common/combined/broken.jar
+ out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/prebuilt_core-libart/android_common/combined/core-libart.jar
+ out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/art-module-sdk_core-libart-error/gen/this-file-will-never-be-created.jar
+
+ The last line is the failing target, the second to last line is a dependency
+ from the core-libart java_import onto the failing target, the third to last
+ line is the source of the dependency so you should look in acme/Android.bp
+ file for the "broken" module.
+
+EOF
+
+exit 1
diff --git a/java/java.go b/java/java.go
index b6fc6b8..3471abb 100644
--- a/java/java.go
+++ b/java/java.go
@@ -86,11 +86,11 @@
var (
// Supports adding java header libraries to module_exports and sdk.
javaHeaderLibsSdkMemberType = &librarySdkMemberType{
- android.SdkMemberTypeBase{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
PropertyName: "java_header_libs",
SupportsSdk: true,
},
- func(_ android.SdkMemberContext, j *Library) android.Path {
+ jarToExportGetter: func(_ android.SdkMemberContext, j *Library) android.Path {
headerJars := j.HeaderJars()
if len(headerJars) != 1 {
panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
@@ -98,8 +98,8 @@
return headerJars[0]
},
- sdkSnapshotFilePathForJar,
- copyEverythingToSnapshot,
+ snapshotPathGetter: sdkSnapshotFilePathForJar,
+ onlyCopyJarToSnapshot: copyEverythingToSnapshot,
}
// Export implementation classes jar as part of the sdk.
@@ -113,12 +113,12 @@
// Supports adding java implementation libraries to module_exports but not sdk.
javaLibsSdkMemberType = &librarySdkMemberType{
- android.SdkMemberTypeBase{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
PropertyName: "java_libs",
},
- exportImplementationClassesJar,
- sdkSnapshotFilePathForJar,
- copyEverythingToSnapshot,
+ jarToExportGetter: exportImplementationClassesJar,
+ snapshotPathGetter: sdkSnapshotFilePathForJar,
+ onlyCopyJarToSnapshot: copyEverythingToSnapshot,
}
snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool {
@@ -143,11 +143,11 @@
// necessary. The java_boot_libs property to allow those modules to be exported as part of the
// sdk/module_exports without exposing any unnecessary information.
javaBootLibsSdkMemberType = &librarySdkMemberType{
- android.SdkMemberTypeBase{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
PropertyName: "java_boot_libs",
SupportsSdk: true,
},
- func(ctx android.SdkMemberContext, j *Library) android.Path {
+ jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path {
if snapshotRequiresImplementationJar(ctx) {
return exportImplementationClassesJar(ctx, j)
}
@@ -156,9 +156,9 @@
// jar for use by dexpreopting and boot jars package check. They do not need to provide an
// actual implementation jar but the java_import will need a file that exists so just copy an
// empty file. Any attempt to use that file as a jar will cause a build error.
- return ctx.SnapshotBuilder().EmptyFile()
+ return nil
},
- func(ctx android.SdkMemberContext, osPrefix, name string) string {
+ snapshotPathGetter: func(ctx android.SdkMemberContext, osPrefix, name string) string {
if snapshotRequiresImplementationJar(ctx) {
return sdkSnapshotFilePathForJar(ctx, osPrefix, name)
}
@@ -168,7 +168,7 @@
// TODO(b/175714559): Provide a proper error message in Soong not ninja.
return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
},
- onlyCopyJarToSnapshot,
+ onlyCopyJarToSnapshot: onlyCopyJarToSnapshot,
}
// Supports adding java systemserver libraries to module_exports and sdk.
@@ -182,27 +182,27 @@
// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
// the sdk/module_exports without exposing any unnecessary information.
javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
- android.SdkMemberTypeBase{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
PropertyName: "java_systemserver_libs",
SupportsSdk: true,
// This was only added in Tiramisu.
SupportedBuildReleaseSpecification: "Tiramisu+",
},
- func(ctx android.SdkMemberContext, j *Library) android.Path {
+ jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path {
// Java systemserver libs are only provided in the SDK to provide access to their dex
// implementation jar for use by dexpreopting. They do not need to provide an actual
// implementation jar but the java_import will need a file that exists so just copy an empty
// file. Any attempt to use that file as a jar will cause a build error.
- return ctx.SnapshotBuilder().EmptyFile()
+ return nil
},
- func(_ android.SdkMemberContext, osPrefix, name string) string {
+ snapshotPathGetter: func(_ android.SdkMemberContext, osPrefix, name string) string {
// Create a special name for the implementation jar to try and provide some useful information
// to a developer that attempts to compile against this.
// TODO(b/175714559): Provide a proper error message in Soong not ninja.
return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
},
- onlyCopyJarToSnapshot,
+ onlyCopyJarToSnapshot: onlyCopyJarToSnapshot,
}
// Supports adding java test libraries to module_exports but not sdk.
@@ -232,7 +232,7 @@
ImplementationAndResourcesJars android.Paths
// ImplementationJars is a list of jars that contain the implementations of classes in the
- //module.
+ // module.
ImplementationJars android.Paths
// ResourceJars is a list of jars that contain the resources included in the module.
@@ -718,7 +718,8 @@
android.SdkMemberTypeBase
// Function to retrieve the appropriate output jar (implementation or header) from
- // the library.
+ // the library, if this returns nil then it is assumed that the snapshot must not provide access
+ // to the jar.
jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path
// Function to compute the snapshot relative path to which the named library's
@@ -755,7 +756,11 @@
type librarySdkMemberProperties struct {
android.SdkMemberPropertiesBase
- JarToExport android.Path `android:"arch_variant"`
+ JarToExport android.Path `android:"arch_variant"`
+
+ // The path to a script to use when the jar is invalid.
+ InvalidJarScript android.Path
+
AidlIncludeDirs android.Paths
// The list of permitted packages that need to be passed to the prebuilts as they are used to
@@ -766,7 +771,15 @@
func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
j := variant.(*Library)
- p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
+ memberType := ctx.MemberType().(*librarySdkMemberType)
+ p.JarToExport = memberType.jarToExportGetter(ctx, j)
+
+ // If no jar was provided for export then disallow access to it completely.
+ if p.JarToExport == nil {
+ // Copy the script to prevent access to the jar into the snapshot.
+ p.InvalidJarScript = android.PathForSource(ctx.SdkModuleContext(),
+ "build/soong/java/invalid_implementation_jar.sh")
+ }
p.AidlIncludeDirs = j.AidlIncludeDirs()
@@ -789,6 +802,21 @@
propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
}
+ if scriptSrc := p.InvalidJarScript; scriptSrc != nil {
+ // Copy the script to prevent access to the jar into the snapshot.
+ scriptDest := filepath.Join("scripts", scriptSrc.Base())
+ builder.CopyToSnapshot(scriptSrc, scriptDest)
+
+ // Generate a genrule module that will invoke the script passing in the module name.
+ genrule := builder.AddInternalModule(p, "genrule", "error")
+ genRuleName := genrule.Name()
+ genrule.AddProperty("out", []string{"this-file-will-never-be-created.jar"})
+ genrule.AddProperty("tool_files", []string{scriptDest})
+ genrule.AddProperty("cmd", fmt.Sprintf("$(location %s) %s", scriptDest, p.Name()))
+
+ propertySet.AddPropertyWithTag("jars", []string{":" + genRuleName}, builder.SdkMemberReferencePropertyTag(true))
+ }
+
if len(p.PermittedPackages) > 0 {
propertySet.AddProperty("permitted_packages", p.PermittedPackages)
}
@@ -1650,7 +1678,7 @@
}
func (j *Import) commonBuildActions(ctx android.ModuleContext) {
- //TODO(b/231322772) these should come from Bazel once available
+ // TODO(b/231322772) these should come from Bazel once available
j.sdkVersion = j.SdkVersion(ctx)
j.minSdkVersion = j.MinSdkVersion(ctx)
@@ -2253,7 +2281,7 @@
resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources))
}
- //TODO(b/179889880) handle case where glob includes files outside package
+ // TODO(b/179889880) handle case where glob includes files outside package
resDeps := ResourceDirsToFiles(
ctx,
m.properties.Java_resource_dirs,
@@ -2401,7 +2429,7 @@
}
epEnabled := m.properties.Errorprone.Enabled
- //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable
+ // TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable
if Bool(epEnabled) {
javacopts = append(javacopts, m.properties.Errorprone.Javacflags...)
}
@@ -2637,7 +2665,7 @@
HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile),
ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile),
ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile),
- //TODO(b/240308299) include AIDL information from Bazel
+ // TODO(b/240308299) include AIDL information from Bazel
})
i.maybeInstall(ctx, jarName, outputFile)
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 1b64130..58c1647 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -169,7 +169,15 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["com.android.art"],
- jars: ["java_boot_libs/snapshot/jars/are/invalid/core1.jar"],
+ jars: [":mysdk_core1-error"],
+}
+
+genrule {
+ name: "mysdk_core1-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) core1",
}
java_import {
@@ -177,7 +185,15 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["com.android.art"],
- jars: ["java_boot_libs/snapshot/jars/are/invalid/core2.jar"],
+ jars: [":mysdk_core2-error"],
+}
+
+genrule {
+ name: "mysdk_core2-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) core2",
}
`),
checkAllCopyRules(`
@@ -187,8 +203,7 @@
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core1.jar
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core2.jar
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
`),
snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
@@ -357,10 +372,18 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
+ jars: [":mysdk_mybootlib-error"],
permitted_packages: ["mybootlib"],
}
+genrule {
+ name: "mysdk_mybootlib-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) mybootlib",
+}
+
java_sdk_library_import {
name: "myothersdklibrary",
prefer: false,
@@ -467,7 +490,7 @@
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
.intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -487,7 +510,7 @@
.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
.intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -876,10 +899,18 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
+ jars: [":mysdk_mybootlib-error"],
permitted_packages: ["mybootlib"],
}
+genrule {
+ name: "mysdk_mybootlib-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) mybootlib",
+}
+
java_sdk_library_import {
name: "mynewlibrary",
prefer: false,
@@ -930,7 +961,7 @@
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
.intermediates/mynewlibrary.stubs/android_common/javac/mynewlibrary.stubs.jar -> sdk_library/public/mynewlibrary-stubs.jar
.intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_api.txt -> sdk_library/public/mynewlibrary.txt
.intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_removed.txt -> sdk_library/public/mynewlibrary-removed.txt
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 51903ce3..c6cb6c2 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -19,11 +19,13 @@
"testing"
"android/soong/android"
+ "android/soong/genrule"
"android/soong/java"
)
var prepareForSdkTestWithJava = android.GroupFixturePreparers(
java.PrepareForTestWithJavaBuildComponents,
+ genrule.PrepareForTestWithGenRuleBuildComponents,
PrepareForTestWithSdkBuildComponents,
// Ensure that all source paths are provided. This helps ensure that the snapshot generation is
@@ -34,6 +36,7 @@
// Files needs by most of the tests.
android.MockFS{
"Test.java": nil,
+ "build/soong/java/invalid_implementation_jar.sh": nil,
}.AddToFixture(),
)
@@ -288,18 +291,26 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
- jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"],
+ jars: [":mysdk_myjavalib-error"],
permitted_packages: ["pkg.myjavalib"],
}
+
+genrule {
+ name: "mysdk_myjavalib-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) myjavalib",
+}
`),
checkAllCopyRules(`
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
`),
)
}
func TestSnapshotWithJavaBootLibrary_UpdatableMedia(t *testing.T) {
- runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedCopyRule string) {
+ runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedGenRule, expectedCopyRule string) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
android.FixtureMergeEnv(map[string]string{
@@ -334,20 +345,27 @@
jars: ["%s"],
permitted_packages: ["pkg.media"],
}
-`, expectedJarPath)),
+%s`, expectedJarPath, expectedGenRule)),
checkAllCopyRules(expectedCopyRule),
)
}
t.Run("updatable-media in S", func(t *testing.T) {
- runTest(t, "S", "java/updatable-media.jar", `
+ runTest(t, "S", "java/updatable-media.jar", "", `
.intermediates/updatable-media/android_common/package-check/updatable-media.jar -> java/updatable-media.jar
`)
})
t.Run("updatable-media in T", func(t *testing.T) {
- runTest(t, "Tiramisu", "java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar", `
-.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar
+ runTest(t, "Tiramisu", ":mysdk_updatable-media-error", `
+genrule {
+ name: "mysdk_updatable-media-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) updatable-media",
+}`, `
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
`)
})
}
@@ -389,12 +407,20 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
- jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
+ jars: [":myexports_myjavalib-error"],
permitted_packages: ["pkg.myjavalib"],
}
+
+genrule {
+ name: "myexports_myjavalib-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) myjavalib",
+}
`),
checkAllCopyRules(`
-.intermediates/myexports/common_os/empty -> java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar
+build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
`),
)
}
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index 1ac405d..9540a6b 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -119,10 +119,18 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+ jars: [":mysdk_mylib-error"],
permitted_packages: ["mylib"],
}
+genrule {
+ name: "mysdk_mylib-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) mylib",
+}
+
prebuilt_systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment",
prefer: false,
@@ -180,10 +188,18 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+ jars: [":mysdk_mylib-error"],
permitted_packages: ["mylib"],
}
+genrule {
+ name: "mysdk_mylib-error",
+ visibility: ["//visibility:private"],
+ out: ["this-file-will-never-be-created.jar"],
+ tool_files: ["scripts/invalid_implementation_jar.sh"],
+ cmd: "$(location scripts/invalid_implementation_jar.sh) mylib",
+}
+
prebuilt_systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment",
prefer: false,
diff --git a/sdk/update.go b/sdk/update.go
index 92a13fa..6ebbf09 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1049,9 +1049,6 @@
filesToZip android.Paths
zipsToMerge android.Paths
- // The path to an empty file.
- emptyFile android.WritablePath
-
prebuiltModules map[string]*bpModule
prebuiltOrder []*bpModule
@@ -1111,19 +1108,6 @@
s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
}
-func (s *snapshotBuilder) EmptyFile() android.Path {
- if s.emptyFile == nil {
- ctx := s.ctx
- s.emptyFile = android.PathForModuleOut(ctx, "empty")
- s.ctx.Build(pctx, android.BuildParams{
- Rule: android.Touch,
- Output: s.emptyFile,
- })
- }
-
- return s.emptyFile
-}
-
func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType string) android.BpModule {
name := member.Name()
if s.prebuiltModules[name] != nil {
@@ -1200,6 +1184,24 @@
return m
}
+func (s *snapshotBuilder) AddInternalModule(properties android.SdkMemberProperties, moduleType string, nameSuffix string) android.BpModule {
+ name := properties.Name() + "-" + nameSuffix
+
+ if s.prebuiltModules[name] != nil {
+ panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
+ }
+
+ m := s.bpFile.newModule(moduleType)
+ m.AddProperty("name", name)
+ m.AddProperty("visibility", []string{"//visibility:private"})
+
+ s.prebuiltModules[name] = m
+ s.prebuiltOrder = append(s.prebuiltOrder, m)
+
+ s.allMembersByName[name] = struct{}{}
+ return m
+}
+
func addHostDeviceSupportedProperties(deviceSupported bool, hostSupported bool, bpModule *bpModule) {
// If neither device or host is supported then this module does not support either so will not
// recognize the properties.
@@ -1230,18 +1232,23 @@
// Get a name for sdk snapshot member. If the member is private then generate a snapshot specific
// name. As part of the processing this checks to make sure that any required members are part of
// the snapshot.
-func (s *snapshotBuilder) snapshotSdkMemberName(name string, required bool) string {
+func (s *snapshotBuilder) snapshotSdkMemberName(reference string, required bool) string {
+ prefix := ""
+ name := strings.TrimPrefix(reference, ":")
+ if name != reference {
+ prefix = ":"
+ }
if _, ok := s.allMembersByName[name]; !ok {
if required {
s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", name)
}
- return name
+ return reference
}
if s.isInternalMember(name) {
- return s.ctx.ModuleName() + "_" + name
+ return prefix + s.ctx.ModuleName() + "_" + name
} else {
- return name
+ return reference
}
}
@@ -2057,6 +2064,7 @@
variantPropertiesFactory := func() android.SdkMemberProperties {
properties := memberType.CreateVariantPropertiesStruct()
base := properties.Base()
+ base.MemberName = member.Name()
base.Os_count = osCount
return properties
}
diff --git a/ui/build/config.go b/ui/build/config.go
index de10112..896a854 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -896,6 +896,10 @@
return filepath.Join(c.OutDir(), "bazel")
}
+func (c *configImpl) bazelOutputBase() string {
+ return filepath.Join(c.BazelOutDir(), "output")
+}
+
func (c *configImpl) SoongOutDir() string {
return filepath.Join(c.OutDir(), "soong")
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 9900c9e..c0bee4e 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -418,7 +418,7 @@
// Bazel's HOME var is set to an output subdirectory which doesn't exist. This
// prevents Bazel from file I/O in the actual user HOME directory.
soongBuildEnv.Set("BAZEL_HOME", absPath(ctx, filepath.Join(config.BazelOutDir(), "bazelhome")))
- soongBuildEnv.Set("BAZEL_OUTPUT_BASE", filepath.Join(config.BazelOutDir(), "output"))
+ soongBuildEnv.Set("BAZEL_OUTPUT_BASE", config.bazelOutputBase())
soongBuildEnv.Set("BAZEL_WORKSPACE", absPath(ctx, "."))
soongBuildEnv.Set("BAZEL_METRICS_DIR", config.BazelMetricsDir())
soongBuildEnv.Set("LOG_DIR", config.LogsDir())
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 86c8568..2efc732 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -18,14 +18,44 @@
"bufio"
"fmt"
"path/filepath"
+ "regexp"
"runtime"
"sort"
"strings"
+ "sync"
"android/soong/ui/metrics"
"android/soong/ui/status"
)
+var (
+ // bazel output paths are in __main__/bazel-out/<config-specific-path>/bin
+ bazelOutputPathRegexOnce sync.Once
+ bazelOutputPathRegexp *regexp.Regexp
+)
+
+func bazelOutputPathPattern(config Config) *regexp.Regexp {
+ bazelOutputPathRegexOnce.Do(func() {
+ // Bazel output files are in <Bazel output base>/execroot/__main__/bazel-out/<config>/bin
+ bazelOutRoot := filepath.Join(regexp.QuoteMeta(config.bazelOutputBase()), "execroot", "__main__", "bazel-out")
+ bazelOutputPathRegexp = regexp.MustCompile(bazelOutRoot + "/[^/]+/bin")
+ })
+ return bazelOutputPathRegexp
+}
+
+func ignoreBazelPath(config Config, path string) bool {
+ bazelRoot := filepath.Join(config.bazelOutputBase(), "execroot")
+ // Don't check bazel output regexp unless it is Bazel path
+ if strings.HasPrefix(path, bazelRoot) {
+ bazelOutputRegexp := bazelOutputPathPattern(config)
+ // if the file is a bazel path that is _not_ a Bazel generated file output, we rely on Bazel to
+ // ensure the paths to exist. If it _is_ a Bazel output path, we expect that it should be built
+ // by Ninja.
+ return !bazelOutputRegexp.MatchString(path)
+ }
+ return false
+}
+
// Checks for files in the out directory that have a rule that depends on them but no rule to
// create them. This catches a common set of build failures where a rule to generate a file is
// deleted (either by deleting a module in an Android.mk file, or by modifying the build system
@@ -97,6 +127,10 @@
// full build rules in the primary build.ninja file.
continue
}
+
+ if ignoreBazelPath(config, line) {
+ continue
+ }
danglingRules[line] = true
}