Merge "Use aidl_library in cc libraries"
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 5291eca..10cf60a 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -29,6 +29,7 @@
"android/soong/bazel/cquery"
"android/soong/shared"
"android/soong/starlark_fmt"
+
"github.com/google/blueprint"
"github.com/google/blueprint/metrics"
@@ -700,9 +701,6 @@
// We don't need to set --host_platforms because it's set in bazelrc files
// that the bazel shell script wrapper passes
- // Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network.
- "--experimental_repository_disable_download",
-
// Suppress noise
"--ui_event_filters=-INFO",
"--noshow_progress",
diff --git a/android/config.go b/android/config.go
index 9e94e05..acadb3f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -183,6 +183,16 @@
return String(c.config.productVariables.DeviceMaxPageSizeSupported)
}
+// The release version passed to aconfig, derived from RELEASE_VERSION
+func (c Config) ReleaseVersion() string {
+ return c.config.productVariables.ReleaseVersion
+}
+
+// The flag values files passed to aconfig, derived from RELEASE_VERSION
+func (c Config) ReleaseDeviceConfigValueSets() []string {
+ return c.config.productVariables.ReleaseDeviceConfigValueSets
+}
+
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
diff --git a/android/variable.go b/android/variable.go
index bf66135..97171e7 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -473,6 +473,9 @@
ProductManufacturer string `json:",omitempty"`
ProductBrand string `json:",omitempty"`
BuildVersionTags []string `json:",omitempty"`
+
+ ReleaseVersion string `json:",omitempty"`
+ ReleaseDeviceConfigValueSets []string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 026734e..ff7ee35 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -404,7 +404,7 @@
///////////////////////////////////////////////////////////////////////////////////////////
// Inputs
- // Keys for apex_paylaod.img
+ // Keys for apex_payload.img
publicKeyFile android.Path
privateKeyFile android.Path
@@ -2606,8 +2606,45 @@
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
vctx.normalizeFileInfo(ctx)
if a.privateKeyFile == nil {
- ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
- return
+ if ctx.Config().AllowMissingDependencies() {
+ // TODO(b/266099037): a better approach for slim manifests.
+ ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
+ // Create placeholder paths for later stages that expect to see those paths,
+ // though they won't be used.
+ var unusedPath = android.PathForModuleOut(ctx, "nonexistentprivatekey")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: unusedPath,
+ Args: map[string]string{
+ "error": "Private key not available",
+ },
+ })
+ a.privateKeyFile = unusedPath
+ } else {
+ ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
+ return
+ }
+ }
+
+ if a.publicKeyFile == nil {
+ if ctx.Config().AllowMissingDependencies() {
+ // TODO(b/266099037): a better approach for slim manifests.
+ ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
+ // Create placeholder paths for later stages that expect to see those paths,
+ // though they won't be used.
+ var unusedPath = android.PathForModuleOut(ctx, "nonexistentpublickey")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: unusedPath,
+ Args: map[string]string{
+ "error": "Public key not available",
+ },
+ })
+ a.publicKeyFile = unusedPath
+ } else {
+ ctx.PropertyErrorf("key", "public_key for %q could not be found", String(a.overridableProperties.Key))
+ return
+ }
}
////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index e998ac8..17b1608 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -4601,3 +4601,59 @@
},
)
}
+
+func TestCcLibraryYaccConversion(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library is built from .y/.yy files",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: soongCcLibraryPreamble + `cc_library {
+ name: "a",
+ srcs: [
+ "a.cpp",
+ "a.yy",
+ ],
+ shared_libs: ["sharedlib"],
+ static_libs: ["staticlib"],
+ yacc: {
+ flags: ["someYaccFlag"],
+ gen_location_hh: true,
+ gen_position_hh: true,
+ },
+}
+cc_library_static {
+ name: "staticlib",
+ bazel_module: { bp2build_available: false },
+}
+cc_library {
+ name: "sharedlib",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_yacc_static_library", "a_yacc", AttrNameToString{
+ "src": `"a.yy"`,
+ "implementation_deps": `[":staticlib"]`,
+ "implementation_dynamic_deps": `[":sharedlib"]`,
+ "flags": `["someYaccFlag"]`,
+ "gen_location_hh": "True",
+ "gen_position_hh": "True",
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
+ "srcs": `["a.cpp"]`,
+ "implementation_deps": `[":staticlib"]`,
+ "implementation_dynamic_deps": `[":sharedlib"]`,
+ "implementation_whole_archive_deps": `[":a_yacc"]`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+ "srcs": `["a.cpp"]`,
+ "implementation_deps": `[":staticlib"]`,
+ "implementation_dynamic_deps": `[":sharedlib"]`,
+ "implementation_whole_archive_deps": `[":a_yacc"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 0f978a5..29e8494 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -38,6 +38,7 @@
protoSrcPartition = "proto"
aidlSrcPartition = "aidl"
syspropSrcPartition = "sysprop"
+ yaccSrcPartition = "yacc"
stubsSuffix = "_stub_libs_current"
)
@@ -154,6 +155,7 @@
// know the language of these sources until the genrule is executed.
cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
syspropSrcPartition: bazel.LabelPartition{Extensions: []string{".sysprop"}},
+ yaccSrcPartition: bazel.LabelPartition{Extensions: []string{".y", "yy"}},
}
return bazel.PartitionLabelListAttribute(ctx, &srcs, labels)
@@ -404,6 +406,12 @@
// Sysprop sources
syspropSrcs bazel.LabelListAttribute
+ // Yacc sources
+ yaccSrc *bazel.LabelAttribute
+ yaccFlags bazel.StringListAttribute
+ yaccGenLocationHeader bazel.BoolAttribute
+ yaccGenPositionHeader bazel.BoolAttribute
+
hdrs bazel.LabelListAttribute
rtti bazel.BoolAttribute
@@ -566,6 +574,12 @@
ca.asmSrcs = partitionedSrcs[asmSrcPartition]
ca.lSrcs = partitionedSrcs[lSrcPartition]
ca.llSrcs = partitionedSrcs[llSrcPartition]
+ if yacc := partitionedSrcs[yaccSrcPartition]; !yacc.IsEmpty() {
+ if len(yacc.Value.Includes) > 1 {
+ ctx.PropertyErrorf("srcs", "Found multiple yacc (.y/.yy) files in library")
+ }
+ ca.yaccSrc = bazel.MakeLabelAttribute(yacc.Value.Includes[0].Label)
+ }
ca.syspropSrcs = partitionedSrcs[syspropSrcPartition]
ca.absoluteIncludes.DeduplicateAxesFromBase()
@@ -744,6 +758,11 @@
if baseCompilerProps.Lex != nil {
compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags)
}
+ if baseCompilerProps.Yacc != nil {
+ compilerAttrs.yaccFlags.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Flags)
+ compilerAttrs.yaccGenLocationHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_location_hh)
+ compilerAttrs.yaccGenPositionHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_position_hh)
+ }
(&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, cfg, baseCompilerProps)
aidlLibs.Append(android.BazelLabelForModuleDeps(ctx, baseCompilerProps.Aidl.Libs))
}
@@ -836,6 +855,12 @@
}
}
+ // Create a cc_yacc_static_library if srcs contains .y/.yy files
+ // This internal target will produce an .a file that will be statically linked to the parent library
+ if yaccDep := bp2buildCcYaccLibrary(ctx, compilerAttrs, linkerAttrs); yaccDep != nil {
+ (&linkerAttrs).implementationWholeArchiveDeps.Add(yaccDep)
+ }
+
convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs)
(&compilerAttrs).srcs.Add(&convertedLSrcs.srcName)
(&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName)
@@ -874,6 +899,48 @@
}
}
+type ccYaccLibraryAttributes struct {
+ Src bazel.LabelAttribute
+ Flags bazel.StringListAttribute
+ Gen_location_hh bazel.BoolAttribute
+ Gen_position_hh bazel.BoolAttribute
+ Local_includes bazel.StringListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Implementation_dynamic_deps bazel.LabelListAttribute
+}
+
+func bp2buildCcYaccLibrary(ctx android.Bp2buildMutatorContext, ca compilerAttributes, la linkerAttributes) *bazel.LabelAttribute {
+ if ca.yaccSrc == nil {
+ return nil
+ }
+ yaccLibraryLabel := ctx.Module().Name() + "_yacc"
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_yacc_static_library",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_yacc_library.bzl",
+ },
+ android.CommonAttributes{
+ Name: yaccLibraryLabel,
+ },
+ &ccYaccLibraryAttributes{
+ Src: *ca.yaccSrc,
+ Flags: ca.yaccFlags,
+ Gen_location_hh: ca.yaccGenLocationHeader,
+ Gen_position_hh: ca.yaccGenPositionHeader,
+ Local_includes: ca.localIncludes,
+ Implementation_deps: la.implementationDeps,
+ Implementation_dynamic_deps: la.implementationDynamicDeps,
+ },
+ )
+
+ yaccLibrary := &bazel.LabelAttribute{
+ Value: &bazel.Label{
+ Label: ":" + yaccLibraryLabel,
+ },
+ }
+ return yaccLibrary
+}
+
// As a workaround for b/261657184, we are manually adding the default value
// of system_dynamic_deps for the linux_musl os.
// TODO: Solve this properly
diff --git a/cc/builder.go b/cc/builder.go
index fef00d4..f5e0dcc 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -125,6 +125,14 @@
},
"objcopyCmd", "prefix")
+ // Rule to run objcopy --remove-section=.llvm_addrsig on a partially linked object
+ noAddrSig = pctx.AndroidStaticRule("noAddrSig",
+ blueprint.RuleParams{
+ Command: "rm -f ${out} && $objcopyCmd --remove-section=.llvm_addrsig ${in} ${out}",
+ CommandDeps: []string{"$objcopyCmd"},
+ },
+ "objcopyCmd")
+
_ = pctx.SourcePathVariable("stripPath", "build/soong/scripts/strip.sh")
_ = pctx.SourcePathVariable("xzCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/xz")
_ = pctx.SourcePathVariable("createMiniDebugInfo", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/create_minidebuginfo")
@@ -1008,6 +1016,21 @@
})
}
+// Generate a rule for running objcopy --remove-section=.llvm_addrsig on a partially linked object
+func transformObjectNoAddrSig(ctx android.ModuleContext, inputFile android.Path, outputFile android.WritablePath) {
+ objcopyCmd := "${config.ClangBin}/llvm-objcopy"
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: noAddrSig,
+ Description: "remove addrsig " + outputFile.Base(),
+ Output: outputFile,
+ Input: inputFile,
+ Args: map[string]string{
+ "objcopyCmd": objcopyCmd,
+ },
+ })
+}
+
// Registers a build statement to invoke `strip` (to discard symbols and data from object files).
func transformStrip(ctx android.ModuleContext, inputFile android.Path,
outputFile android.WritablePath, flags StripFlags) {
diff --git a/cc/object.go b/cc/object.go
index 5d61872..ca14845 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -309,6 +309,8 @@
})
}
} else {
+ outputAddrSig := android.PathForModuleOut(ctx, "addrsig", outputName)
+
if String(object.Properties.Prefix_symbols) != "" {
input := android.PathForModuleOut(ctx, "unprefixed", outputName)
transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input,
@@ -316,7 +318,12 @@
output = input
}
- transformObjsToObj(ctx, objs.objFiles, builderFlags, output, flags.LdFlagsDeps)
+ transformObjsToObj(ctx, objs.objFiles, builderFlags, outputAddrSig, flags.LdFlagsDeps)
+
+ // ld -r reorders symbols and invalidates the .llvm_addrsig section, which then causes warnings
+ // if the resulting object is used with ld --icf=safe. Strip the .llvm_addrsig section to
+ // prevent the warnings.
+ transformObjectNoAddrSig(ctx, outputAddrSig, output)
}
ctx.CheckbuildFile(outputFile)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 10b09d3..cf6c1c7 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -133,6 +133,10 @@
ninjaDeps = append(ninjaDeps, writeBuildGlobsNinjaFile(ctx)...)
writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
+
+ if ctx.Config().IsEnvTrue("SOONG_GENERATES_NINJA_HINT") {
+ writeNinjaHint(ctx)
+ }
return cmdlineArgs.OutFile
}
@@ -455,6 +459,9 @@
// The actual output (build.ninja) was written in the RunBlueprint() call
// above
writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
+ if ctx.Config().IsEnvTrue("SOONG_GENERATES_NINJA_HINT") {
+ writeNinjaHint(ctx)
+ }
return cmdlineArgs.OutFile
}
}
@@ -535,9 +542,6 @@
} else {
finalOutputFile = runSoongOnlyBuild(ctx, extraNinjaDeps)
}
- if ctx.Config().IsEnvTrue("SOONG_GENERATES_NINJA_HINT") {
- writeNinjaHint(ctx)
- }
writeMetrics(configuration, ctx.EventHandler, metricsDir)
}
writeUsedEnvironmentFile(configuration)
diff --git a/device_config/Android.bp b/device_config/Android.bp
new file mode 100644
index 0000000..360b389
--- /dev/null
+++ b/device_config/Android.bp
@@ -0,0 +1,30 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-device_config",
+ pkgPath: "android/soong/device_config",
+ deps: [
+ "blueprint",
+ "blueprint-pathtools",
+ "sbox_proto",
+ "soong",
+ "soong-android",
+ "soong-bazel",
+ "soong-shared",
+ ],
+ srcs: [
+ "device_config_definitions.go",
+ "device_config_values.go",
+ "device_config_value_set.go",
+ "init.go",
+ //"testing.go"
+ ],
+ /*
+ testSrcs: [
+ "device_config_test.go",
+ ],
+ */
+ pluginFor: ["soong_build"],
+}
diff --git a/device_config/device_config_definitions.go b/device_config/device_config_definitions.go
new file mode 100644
index 0000000..c565766
--- /dev/null
+++ b/device_config/device_config_definitions.go
@@ -0,0 +1,150 @@
+// Copyright 2023 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 device_config
+
+import (
+ "android/soong/android"
+ "fmt"
+ "github.com/google/blueprint"
+ "strings"
+)
+
+type DefinitionsModule struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ // Properties for "device_config_definitions"
+ properties struct {
+ // aconfig files, relative to this Android.bp file
+ Srcs []string `android:"path"`
+
+ // Release config flag namespace
+ Namespace string
+
+ // Values from TARGET_RELEASE / RELEASE_DEVICE_CONFIG_VALUE_SETS
+ Values []string `blueprint:"mutated"`
+ }
+
+ intermediatePath android.WritablePath
+ srcJarPath android.WritablePath
+}
+
+func DefinitionsFactory() android.Module {
+ module := &DefinitionsModule{}
+
+ android.InitAndroidModule(module)
+ android.InitDefaultableModule(module)
+ module.AddProperties(&module.properties)
+ // TODO: bp2build
+ //android.InitBazelModule(module)
+
+ return module
+}
+
+type implicitValuesTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+var implicitValuesTag = implicitValuesTagType{}
+
+func (module *DefinitionsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // Validate Properties
+ if len(module.properties.Srcs) == 0 {
+ ctx.PropertyErrorf("srcs", "missing source files")
+ return
+ }
+ if len(module.properties.Namespace) == 0 {
+ ctx.PropertyErrorf("namespace", "missing namespace property")
+ }
+
+ // Add a dependency on the device_config_value_sets defined in
+ // RELEASE_DEVICE_CONFIG_VALUE_SETS, and add any device_config_values that
+ // match our namespace.
+ valuesFromConfig := ctx.Config().ReleaseDeviceConfigValueSets()
+ ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...)
+}
+
+func (module *DefinitionsModule) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case ".srcjar":
+ return []android.Path{module.srcJarPath}, nil
+ case "":
+ // The default output of this module is the intermediates format, which is
+ // not installable and in a private format that no other rules can handle
+ // correctly.
+ return []android.Path{module.intermediatePath}, nil
+ default:
+ return nil, fmt.Errorf("unsupported device_config_definitions module reference tag %q", tag)
+ }
+}
+
+func joinAndPrefix(prefix string, values []string) string {
+ var sb strings.Builder
+ for _, v := range values {
+ sb.WriteString(prefix)
+ sb.WriteString(v)
+ }
+ return sb.String()
+}
+
+func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Get the values that came from the global RELEASE_DEVICE_CONFIG_VALUE_SETS flag
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ if !ctx.OtherModuleHasProvider(dep, valueSetProviderKey) {
+ // Other modules get injected as dependencies too, for example the license modules
+ return
+ }
+ depData := ctx.OtherModuleProvider(dep, valueSetProviderKey).(valueSetProviderData)
+ valuesFiles, ok := depData.AvailableNamespaces[module.properties.Namespace]
+ if ok {
+ for _, path := range valuesFiles {
+ module.properties.Values = append(module.properties.Values, path.String())
+ }
+ }
+ })
+
+ // Intermediate format
+ inputFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs)
+ module.intermediatePath = android.PathForModuleOut(ctx, "intermediate.json")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfigRule,
+ Inputs: inputFiles,
+ Output: module.intermediatePath,
+ Description: "device_config_definitions",
+ Args: map[string]string{
+ "release_version": ctx.Config().ReleaseVersion(),
+ "namespace": module.properties.Namespace,
+ "values": joinAndPrefix(" --values ", module.properties.Values),
+ },
+ })
+
+ // Generated java inside a srcjar
+ module.srcJarPath = android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: srcJarRule,
+ Input: module.intermediatePath,
+ Output: module.srcJarPath,
+ Description: "device_config.srcjar",
+ })
+
+ // TODO: C++
+
+ // Phony target for debugging convenience
+ ctx.Build(pctx, android.BuildParams{
+ Rule: blueprint.Phony,
+ Output: android.PathForPhony(ctx, ctx.ModuleName()),
+ Inputs: []android.Path{module.srcJarPath}, // TODO: C++
+ })
+}
diff --git a/device_config/device_config_test.go b/device_config/device_config_test.go
new file mode 100644
index 0000000..91a06a7
--- /dev/null
+++ b/device_config/device_config_test.go
@@ -0,0 +1,61 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package device_config
+
+import (
+ "os"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func TestMain(m *testing.M) {
+ os.Exit(m.Run())
+}
+
+func test(t *testing.T, bp string) *android.TestResult {
+ t.Helper()
+
+ mockFS := android.MockFS{
+ "config.aconfig": nil,
+ }
+
+ result := android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithSyspropBuildComponents,
+ // TODO: Consider values files, although maybe in its own test
+ // android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // variables.ReleaseConfigValuesBasePaths = ...
+ //})
+ mockFS.AddToFixture(),
+ android.FixtureWithRootAndroidBp(bp),
+ ).RunTest(t)
+
+ return result
+}
+
+func TestOutputs(t *testing.T) {
+ /*result := */ test(t, `
+ device_config {
+ name: "my_device_config",
+ srcs: ["config.aconfig"],
+ }
+ `)
+
+ // TODO: Make sure it exports a .srcjar, which is used by java libraries
+ // TODO: Make sure it exports an intermediates file
+ // TODO: Make sure the intermediates file is propagated to the Android.mk file
+}
diff --git a/device_config/device_config_value_set.go b/device_config/device_config_value_set.go
new file mode 100644
index 0000000..e406d20
--- /dev/null
+++ b/device_config/device_config_value_set.go
@@ -0,0 +1,92 @@
+// Copyright 2023 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 device_config
+
+import (
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+// Properties for "device_config_value_set"
+type ValueSetModule struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ properties struct {
+ // device_config_values modules
+ Values []string
+ }
+}
+
+func ValueSetFactory() android.Module {
+ module := &ValueSetModule{}
+
+ android.InitAndroidModule(module)
+ android.InitDefaultableModule(module)
+ module.AddProperties(&module.properties)
+ // TODO: bp2build
+ //android.InitBazelModule(module)
+
+ return module
+}
+
+// Dependency tag for values property
+type valueSetType struct {
+ blueprint.BaseDependencyTag
+}
+
+var valueSetTag = valueSetType{}
+
+// Provider published by device_config_value_set
+type valueSetProviderData struct {
+ // The namespace of each of the
+ // (map of namespace --> device_config_module)
+ AvailableNamespaces map[string]android.Paths
+}
+
+var valueSetProviderKey = blueprint.NewProvider(valueSetProviderData{})
+
+func (module *ValueSetModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ deps := ctx.AddDependency(ctx.Module(), valueSetTag, module.properties.Values...)
+ for _, dep := range deps {
+ _, ok := dep.(*ValuesModule)
+ if !ok {
+ ctx.PropertyErrorf("values", "values must be a device_config_values module")
+ return
+ }
+ }
+}
+
+func (module *ValueSetModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Accumulate the namespaces of the values modules listed, and set that as an
+ // valueSetProviderKey provider that device_config modules can read and use
+ // to append values to their aconfig actions.
+ namespaces := make(map[string]android.Paths)
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ if !ctx.OtherModuleHasProvider(dep, valuesProviderKey) {
+ // Other modules get injected as dependencies too, for example the license modules
+ return
+ }
+ depData := ctx.OtherModuleProvider(dep, valuesProviderKey).(valuesProviderData)
+
+ srcs := make([]android.Path, len(depData.Values))
+ copy(srcs, depData.Values)
+ namespaces[depData.Namespace] = srcs
+
+ })
+ ctx.SetProvider(valueSetProviderKey, valueSetProviderData{
+ AvailableNamespaces: namespaces,
+ })
+}
diff --git a/device_config/device_config_values.go b/device_config/device_config_values.go
new file mode 100644
index 0000000..110f12a
--- /dev/null
+++ b/device_config/device_config_values.go
@@ -0,0 +1,70 @@
+// Copyright 2023 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 device_config
+
+import (
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+// Properties for "device_config_value"
+type ValuesModule struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ properties struct {
+ // aconfig files, relative to this Android.bp file
+ Srcs []string `android:"path"`
+
+ // Release config flag namespace
+ Namespace string
+ }
+}
+
+func ValuesFactory() android.Module {
+ module := &ValuesModule{}
+
+ android.InitAndroidModule(module)
+ android.InitDefaultableModule(module)
+ module.AddProperties(&module.properties)
+ // TODO: bp2build
+ //android.InitBazelModule(module)
+
+ return module
+}
+
+// Provider published by device_config_value_set
+type valuesProviderData struct {
+ // The namespace that this values module values
+ Namespace string
+
+ // The values aconfig files, relative to the root of the tree
+ Values android.Paths
+}
+
+var valuesProviderKey = blueprint.NewProvider(valuesProviderData{})
+
+func (module *ValuesModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if len(module.properties.Namespace) == 0 {
+ ctx.PropertyErrorf("namespace", "missing namespace property")
+ }
+
+ // Provide the our source files list to the device_config_value_set as a list of files
+ providerData := valuesProviderData{
+ Namespace: module.properties.Namespace,
+ Values: android.PathsForModuleSrc(ctx, module.properties.Srcs),
+ }
+ ctx.SetProvider(valuesProviderKey, providerData)
+}
diff --git a/device_config/init.go b/device_config/init.go
new file mode 100644
index 0000000..0a4645b
--- /dev/null
+++ b/device_config/init.go
@@ -0,0 +1,70 @@
+// Copyright 2023 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 device_config
+
+import (
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+var (
+ pctx = android.NewPackageContext("android/soong/device_config")
+
+ // For device_config_definitions: Generate cache file
+ // TODO: Restat
+ aconfigRule = pctx.AndroidStaticRule("aconfig",
+ blueprint.RuleParams{
+ Command: `${aconfig} create-cache` +
+ ` --namespace ${namespace}` +
+ ` --declarations ${in}` +
+ ` ${values}` +
+ ` --cache ${out}.tmp` +
+ ` && ( if cmp -s ${out}.tmp ; then rm ${out}.tmp ; else mv ${out}.tmp ${out} ; fi )`,
+ // ` --build-id ${release_version}` +
+ CommandDeps: []string{
+ "${aconfig}",
+ },
+ Restat: true,
+ }, "release_version", "namespace", "values")
+
+ // For device_config_definitions: Generate java file
+ srcJarRule = pctx.AndroidStaticRule("aconfig_srcjar",
+ blueprint.RuleParams{
+ Command: `rm -rf ${out}.tmp` +
+ ` && mkdir -p ${out}.tmp` +
+ ` && ${aconfig} create-java-lib` +
+ ` --cache ${in}` +
+ ` --out ${out}.tmp` +
+ ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
+ ` && rm -rf ${out}.tmp`,
+ CommandDeps: []string{
+ "$aconfig",
+ "$soong_zip",
+ },
+ Restat: true,
+ })
+)
+
+func init() {
+ registerBuildComponents(android.InitRegistrationContext)
+}
+
+func registerBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("device_config_definitions", DefinitionsFactory)
+ ctx.RegisterModuleType("device_config_values", ValuesFactory)
+ ctx.RegisterModuleType("device_config_value_set", ValueSetFactory)
+ pctx.HostBinToolVariable("aconfig", "aconfig")
+ pctx.HostBinToolVariable("soong_zip", "soong_zip")
+}
diff --git a/device_config/testing.go b/device_config/testing.go
new file mode 100644
index 0000000..f054476
--- /dev/null
+++ b/device_config/testing.go
@@ -0,0 +1,19 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package device_config
+
+import "android/soong/android"
+
+var PrepareForTestWithSyspropBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents)
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 6817dce..3e1bbde 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -652,9 +652,7 @@
prop := snapshot.SnapshotJsonFlags{}
propOut := snapshotLibOut + ".json"
prop.InitBaseSnapshotProps(m)
- if m.subdirProperties.Relative_install_path != nil {
- prop.RelativeInstallPath = *m.subdirProperties.Relative_install_path
- }
+ prop.RelativeInstallPath = m.SubDir()
if m.properties.Filename != nil {
prop.Filename = *m.properties.Filename
diff --git a/java/app_test.go b/java/app_test.go
index daff94c..8a69a03 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -443,9 +443,9 @@
inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
var crtbeginFound, crtendFound bool
expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
- "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
+ "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
expectedCrtEnd := ctx.ModuleForTests("crtend_so",
- "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
+ "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
implicits := []string{}
for _, input := range inputs {
implicits = append(implicits, input.String())
diff --git a/java/dex.go b/java/dex.go
index f7c1361..7e7da00 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -161,7 +161,7 @@
"$r8Template": &remoteexec.REParams{
Labels: map[string]string{"type": "compile", "compiler": "r8"},
Inputs: []string{"$implicits", "${config.R8Jar}"},
- OutputFiles: []string{"${outUsage}"},
+ OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}"},
ExecStrategy: "${config.RER8ExecStrategy}",
ToolchainInputs: []string{"${config.JavaCmd}"},
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
@@ -399,13 +399,16 @@
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
}
ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "r8",
- Output: javalibJar,
- ImplicitOutputs: android.WritablePaths{proguardDictionary, proguardUsageZip},
- Input: dexParams.classesJar,
- Implicits: r8Deps,
- Args: args,
+ Rule: rule,
+ Description: "r8",
+ Output: javalibJar,
+ ImplicitOutputs: android.WritablePaths{
+ proguardDictionary,
+ proguardUsageZip,
+ proguardConfiguration},
+ Input: dexParams.classesJar,
+ Implicits: r8Deps,
+ Args: args,
})
} else {
d8Flags, d8Deps := d8Flags(dexParams.flags)
diff --git a/ui/build/config.go b/ui/build/config.go
index 8ec9680..6b6ce71 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -316,8 +316,9 @@
func NewConfig(ctx Context, args ...string) Config {
ret := &configImpl{
- environ: OsEnvironment(),
- sandboxConfig: &SandboxConfig{},
+ environ: OsEnvironment(),
+ sandboxConfig: &SandboxConfig{},
+ ninjaWeightListSource: HINT_FROM_SOONG,
}
// Default matching ninja