Merge "Revert "ATest: GTest auto gen config support run_test_as in Android.bp .""
diff --git a/Android.bp b/Android.bp
index 2037818..5faefe6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -173,6 +173,7 @@
testSrcs: [
"cc/cc_test.go",
"cc/gen_test.go",
+ "cc/genrule_test.go",
"cc/library_test.go",
"cc/test_data_test.go",
"cc/util_test.go",
@@ -348,6 +349,7 @@
],
srcs: [
"apex/apex.go",
+ "apex/key.go",
],
pluginFor: ["soong_build"],
}
@@ -481,7 +483,7 @@
}
cc_genrule {
- name: "host_bionic_linker_script",
+ name: "host_bionic_linker_flags",
host_supported: true,
device_supported: false,
target: {
@@ -496,7 +498,7 @@
},
},
tools: ["extract_linker"],
- cmd: "$(location) -T $(out) $(in)",
+ cmd: "$(location) -f $(out) $(in)",
srcs: [":linker"],
- out: ["linker.script"],
+ out: ["linker.flags"],
}
diff --git a/android/androidmk.go b/android/androidmk.go
index 5df4a85..7030523 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -215,7 +215,7 @@
}
- if amod.Arch().ArchType != ctx.Config().Targets[amod.Os().Class][0].Arch.ArchType {
+ if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
prefix = "2ND_" + prefix
}
}
diff --git a/android/arch.go b/android/arch.go
index 6516558..2543fca 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -194,7 +194,7 @@
NoOsType OsType
Linux = NewOsType("linux_glibc", Host, false)
Darwin = NewOsType("darwin", Host, false)
- LinuxBionic = NewOsType("linux_bionic", Host, true)
+ LinuxBionic = NewOsType("linux_bionic", Host, false)
Windows = NewOsType("windows", HostCross, true)
Android = NewOsType("android", Device, false)
@@ -325,37 +325,46 @@
return
}
- osClasses := base.OsClassSupported()
-
var moduleTargets []Target
moduleMultiTargets := make(map[int][]Target)
primaryModules := make(map[int]bool)
+ osClasses := base.OsClassSupported()
- for _, class := range osClasses {
- classTargets := mctx.Config().Targets[class]
- if len(classTargets) == 0 {
+ for _, os := range osTypeList {
+ supportedClass := false
+ for _, osClass := range osClasses {
+ if os.Class == osClass {
+ supportedClass = true
+ }
+ }
+ if !supportedClass {
+ continue
+ }
+
+ osTargets := mctx.Config().Targets[os]
+ if len(osTargets) == 0 {
continue
}
// only the primary arch in the recovery partition
- if module.InstallInRecovery() {
- classTargets = []Target{mctx.Config().Targets[Device][0]}
+ if os == Android && module.InstallInRecovery() {
+ osTargets = []Target{osTargets[0]}
}
prefer32 := false
if base.prefer32 != nil {
- prefer32 = base.prefer32(mctx, base, class)
+ prefer32 = base.prefer32(mctx, base, os.Class)
}
- multilib, extraMultilib := decodeMultilib(base, class)
- targets, err := decodeMultilibTargets(multilib, classTargets, prefer32)
+ multilib, extraMultilib := decodeMultilib(base, os.Class)
+ targets, err := decodeMultilibTargets(multilib, osTargets, prefer32)
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
var multiTargets []Target
if extraMultilib != "" {
- multiTargets, err = decodeMultilibTargets(extraMultilib, classTargets, prefer32)
+ multiTargets, err = decodeMultilibTargets(extraMultilib, osTargets, prefer32)
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
@@ -839,17 +848,17 @@
}
if (arch.ArchType == X86 && (hasArmAbi(arch) ||
- hasArmAndroidArch(ctx.Config().Targets[Device]))) ||
+ hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
(arch.ArchType == Arm &&
- hasX86AndroidArch(ctx.Config().Targets[Device])) {
+ hasX86AndroidArch(ctx.Config().Targets[Android])) {
field := "Arm_on_x86"
prefix := "target.arm_on_x86"
a.appendProperties(ctx, genProps, targetProp, field, prefix)
}
if (arch.ArchType == X86_64 && (hasArmAbi(arch) ||
- hasArmAndroidArch(ctx.Config().Targets[Device]))) ||
+ hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
(arch.ArchType == Arm &&
- hasX8664AndroidArch(ctx.Config().Targets[Device])) {
+ hasX8664AndroidArch(ctx.Config().Targets[Android])) {
field := "Arm_on_x86_64"
prefix := "target.arm_on_x86_64"
a.appendProperties(ctx, genProps, targetProp, field, prefix)
@@ -874,10 +883,10 @@
}
// Convert the arch product variables into a list of targets for each os class structs
-func decodeTargetProductVariables(config *config) (map[OsClass][]Target, error) {
+func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) {
variables := config.productVariables
- targets := make(map[OsClass][]Target)
+ targets := make(map[OsType][]Target)
var targetErr error
addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi *[]string) {
@@ -891,7 +900,7 @@
return
}
- targets[os.Class] = append(targets[os.Class],
+ targets[os] = append(targets[os],
Target{
Os: os,
Arch: arch,
@@ -938,7 +947,7 @@
variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
variables.DeviceSecondaryAbi)
- deviceArches := targets[Device]
+ deviceArches := targets[Android]
if deviceArches[0].Arch.ArchType.Multilib == deviceArches[1].Arch.ArchType.Multilib {
deviceArches[1].Arch.Native = false
}
@@ -1012,6 +1021,7 @@
{"arm", "armv7-a-neon", "cortex-a72", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "cortex-a73", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "cortex-a75", []string{"armeabi-v7a"}},
+ {"arm", "armv7-a-neon", "cortex-a76", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "denver", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "krait", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "kryo", []string{"armeabi-v7a"}},
@@ -1025,6 +1035,7 @@
{"arm64", "armv8-a", "exynos-m1", []string{"arm64-v8a"}},
{"arm64", "armv8-a", "exynos-m2", []string{"arm64-v8a"}},
{"arm64", "armv8-2a", "cortex-a75", []string{"arm64-v8a"}},
+ {"arm64", "armv8-2a", "cortex-a76", []string{"arm64-v8a"}},
{"mips", "mips32-fp", "", []string{"mips"}},
{"mips", "mips32r2-fp", "", []string{"mips"}},
{"mips", "mips32r2-fp-xburst", "", []string{"mips"}},
diff --git a/android/config.go b/android/config.go
index 5da1e0b..3b7b477 100644
--- a/android/config.go
+++ b/android/config.go
@@ -41,7 +41,6 @@
// config file. These will be included in the config struct.
type FileConfigurableOptions struct {
Mega_device *bool `json:",omitempty"`
- Ndk_abis *bool `json:",omitempty"`
Host_bionic *bool `json:",omitempty"`
}
@@ -90,7 +89,7 @@
ConfigFileName string
ProductVariablesFileName string
- Targets map[OsClass][]Target
+ Targets map[OsType][]Target
BuildOsVariant string
BuildOsCommonVariant string
@@ -230,18 +229,18 @@
testConfig := TestConfig(buildDir, env)
config := testConfig.config
- config.Targets = map[OsClass][]Target{
- Device: []Target{
+ config.Targets = map[OsType][]Target{
+ Android: []Target{
{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}},
{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}},
},
- Host: []Target{
+ BuildOs: []Target{
{BuildOs, Arch{ArchType: X86_64}},
{BuildOs, Arch{ArchType: X86}},
},
}
- config.BuildOsVariant = config.Targets[Host][0].String()
+ config.BuildOsVariant = config.Targets[BuildOs][0].String()
return testConfig
}
@@ -299,21 +298,21 @@
var archConfig []archConfig
if Bool(config.Mega_device) {
archConfig = getMegaDeviceConfig()
- } else if Bool(config.Ndk_abis) {
+ } else if config.NdkAbis() {
archConfig = getNdkAbisConfig()
}
if archConfig != nil {
- deviceTargets, err := decodeArchSettings(archConfig)
+ androidTargets, err := decodeArchSettings(archConfig)
if err != nil {
return Config{}, err
}
- targets[Device] = deviceTargets
+ targets[Android] = androidTargets
}
config.Targets = targets
- config.BuildOsVariant = targets[Host][0].String()
- config.BuildOsCommonVariant = getCommonTargets(targets[Host])[0].String()
+ config.BuildOsVariant = targets[BuildOs][0].String()
+ config.BuildOsCommonVariant = getCommonTargets(targets[BuildOs])[0].String()
if err := config.fromEnv(); err != nil {
return Config{}, err
@@ -587,7 +586,7 @@
}
func (c *config) DevicePrimaryArchType() ArchType {
- return c.Targets[Device][0].Arch.ArchType
+ return c.Targets[Android][0].Arch.ArchType
}
func (c *config) SkipDeviceInstall() bool {
@@ -624,7 +623,7 @@
}
func (c *config) Android64() bool {
- for _, t := range c.Targets[Device] {
+ for _, t := range c.Targets[Android] {
if t.Arch.ArchType.Multilib == "lib64" {
return true
}
@@ -646,10 +645,6 @@
return c.targetOpenJDK9
}
-func (c *config) UseClangLld() bool {
- return Bool(c.productVariables.UseClangLld)
-}
-
func (c *config) ClangTidy() bool {
return Bool(c.productVariables.ClangTidy)
}
@@ -667,8 +662,8 @@
func (c *config) LibartImgDeviceBaseAddress() string {
archType := Common
- if len(c.Targets[Device]) > 0 {
- archType = c.Targets[Device][0].Arch.ArchType
+ if len(c.Targets[Android]) > 0 {
+ archType = c.Targets[Android][0].Arch.ArchType
}
switch archType {
default:
@@ -715,7 +710,7 @@
func (c *deviceConfig) Arches() []Arch {
var arches []Arch
- for _, target := range c.config.Targets[Device] {
+ for _, target := range c.config.Targets[Android] {
arches = append(arches, target.Arch)
}
return arches
@@ -866,6 +861,10 @@
return ok
}
+func (c *config) NdkAbis() bool {
+ return Bool(c.productVariables.Ndk_abis)
+}
+
func stringSlice(s *[]string) []string {
if s != nil {
return *s
diff --git a/android/module.go b/android/module.go
index 9d9d9a9..556c73d 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1071,10 +1071,10 @@
}
func (a *androidBaseContextImpl) PrimaryArch() bool {
- if len(a.config.Targets[a.target.Os.Class]) <= 1 {
+ if len(a.config.Targets[a.target.Os]) <= 1 {
return true
}
- return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
+ return a.target.Arch.ArchType == a.config.Targets[a.target.Os][0].Arch.ArchType
}
func (a *androidBaseContextImpl) AConfig() Config {
diff --git a/android/paths.go b/android/paths.go
index daaf857..b22e3c7 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -725,46 +725,6 @@
return PathForOutput(ctx, ".intermediates", path)
}
-// DistPath is a Path representing a file path rooted from the dist directory
-type DistPath struct {
- basePath
-}
-
-func (p DistPath) withRel(rel string) DistPath {
- p.basePath = p.basePath.withRel(rel)
- return p
-}
-
-var _ Path = DistPath{}
-
-// PathForDist joins the provided paths and returns a DistPath that is
-// validated to not escape the dist dir.
-// On error, it will return a usable, but invalid DistPath, and report a ModuleError.
-func PathForDist(ctx PathContext, pathComponents ...string) DistPath {
- path, err := validatePath(pathComponents...)
- if err != nil {
- reportPathError(ctx, err)
- }
- return DistPath{basePath{path, ctx.Config(), ""}}
-}
-
-func (p DistPath) writablePath() {}
-
-func (p DistPath) Valid() bool {
- return p.config.productVariables.DistDir != nil && *p.config.productVariables.DistDir != ""
-}
-
-func (p DistPath) String() string {
- if !p.Valid() {
- panic("Requesting an invalid path")
- }
- return filepath.Join(*p.config.productVariables.DistDir, p.path)
-}
-
-func (p DistPath) RelPathString() string {
- return p.path
-}
-
// ModuleSrcPath is a Path representing a file rooted from a module's local source dir
type ModuleSrcPath struct {
SourcePath
diff --git a/android/variable.go b/android/variable.go
index 5c4d491..2eb9900 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -201,8 +201,6 @@
ProductPath *string `json:",omitempty"`
ProductServicesPath *string `json:",omitempty"`
- UseClangLld *bool `json:",omitempty"`
-
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
@@ -228,7 +226,6 @@
Product_is_iot *bool `json:",omitempty"`
DeviceKernelHeaders []string `json:",omitempty"`
- DistDir *string `json:",omitempty"`
ExtraVndkVersions []string `json:",omitempty"`
@@ -242,6 +239,8 @@
BoardPlatPrivateSepolicyDirs []string `json:",omitempty"`
VendorVars map[string]map[string]string `json:",omitempty"`
+
+ Ndk_abis *bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 10e5b0a..b3d5aec 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -51,6 +51,7 @@
"LOCAL_MODULE_HOST_OS": hostOs,
"LOCAL_SANITIZE": sanitize(""),
"LOCAL_SANITIZE_DIAG": sanitize("diag."),
+ "LOCAL_STRIP_MODULE": strip(),
"LOCAL_CFLAGS": cflags,
"LOCAL_UNINSTALLABLE_MODULE": invert("installable"),
"LOCAL_PROGUARD_ENABLED": proguardEnabled,
@@ -81,7 +82,6 @@
map[string]string{
"LOCAL_MODULE": "name",
"LOCAL_CXX_STL": "stl",
- "LOCAL_STRIP_MODULE": "strip",
"LOCAL_MULTILIB": "compile_multilib",
"LOCAL_ARM_MODE_HACK": "instruction_set",
"LOCAL_SDK_VERSION": "sdk_version",
@@ -463,6 +463,29 @@
}
}
+func strip() func(ctx variableAssignmentContext) error {
+ return func(ctx variableAssignmentContext) error {
+ val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.StringType)
+ if err != nil {
+ return err
+ }
+
+ if _, ok := val.(*bpparser.String); !ok {
+ return fmt.Errorf("unsupported strip expression")
+ }
+
+ bpTrue := &bpparser.Bool{
+ Value: true,
+ }
+ v := val.(*bpparser.String).Value
+ sub := (map[string]string{"false": "none", "true": "all", "keep_symbols": "keep_symbols"})[v]
+ if sub == "" {
+ return fmt.Errorf("unexpected strip option: %s", v)
+ }
+ return setVariable(ctx.file, false, ctx.prefix, "strip."+sub, bpTrue, true)
+ }
+}
+
func prebuiltClass(ctx variableAssignmentContext) error {
class := ctx.mkvalue.Value(ctx.file.scope)
if v, ok := prebuiltTypes[class]; ok {
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index 80e7a75..0f6c5ac 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -692,6 +692,47 @@
}
`,
},
+ {
+ desc: "LOCAL_STRIP_MODULE",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtest
+LOCAL_STRIP_MODULE := false
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtest2
+LOCAL_STRIP_MODULE := true
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtest3
+LOCAL_STRIP_MODULE := keep_symbols
+include $(BUILD_SHARED_LIBRARY)
+`,
+ expected: `
+cc_library_shared {
+ name: "libtest",
+ strip: {
+ none: true,
+ }
+}
+
+cc_library_shared {
+ name: "libtest2",
+ strip: {
+ all: true,
+ }
+}
+
+cc_library_shared {
+ name: "libtest3",
+ strip: {
+ keep_symbols: true,
+ }
+}
+`,
+ },
}
func TestEndToEnd(t *testing.T) {
diff --git a/apex/apex.go b/apex/apex.go
index 68d9cb8..5390114 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -75,6 +75,7 @@
executableTag = dependencyTag{name: "executable"}
javaLibTag = dependencyTag{name: "javaLib"}
prebuiltTag = dependencyTag{name: "prebuilt"}
+ keyTag = dependencyTag{name: "key"}
)
func init() {
@@ -112,7 +113,7 @@
apexBundleName := mctx.Module().Name()
mctx.WalkDeps(func(child, parent android.Module) bool {
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() {
- moduleName := am.Name()
+ moduleName := am.Name() + "-" + am.Target().String()
bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]
if !ok {
bundleNames = make(map[string]bool)
@@ -130,7 +131,7 @@
// Create apex variations if a module is included in APEX(s).
func apexMutator(mctx android.BottomUpMutatorContext) {
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
- moduleName := am.Name()
+ moduleName := am.Name() + "-" + am.Target().String()
if bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]; ok {
variations := []string{"platform"}
for bn := range bundleNames {
@@ -172,6 +173,9 @@
// List of prebuilt files that are embedded inside this APEX bundle
Prebuilts []string
+
+ // Name of the apex_key module that provides the private key to sign APEX
+ Key *string
}
type apexBundle struct {
@@ -185,14 +189,6 @@
}
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
- // Native shared libs are added for all architectures of the device
- // i.e., native_shared_lib_modules: ["libc"] adds both 64 and 32 variation
- // of the module
- arches := ctx.DeviceConfig().Arches()
- if len(arches) == 0 {
- panic("device build with no primary arch")
- }
-
for _, arch := range ctx.MultiTargets() {
// Use *FarVariation* to be able to depend on modules having
// conflicting variations with this module. This is required since
@@ -208,16 +204,21 @@
{Mutator: "arch", Variation: arch.String()},
{Mutator: "image", Variation: "core"},
}, executableTag, a.properties.Binaries...)
-
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "arch", Variation: "android_common"},
- }, javaLibTag, a.properties.Java_libs...)
-
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "arch", Variation: "android_common"},
- }, prebuiltTag, a.properties.Prebuilts...)
}
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "arch", Variation: "android_common"},
+ }, javaLibTag, a.properties.Java_libs...)
+
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "arch", Variation: "android_common"},
+ }, prebuiltTag, a.properties.Prebuilts...)
+
+ if String(a.properties.Key) == "" {
+ ctx.ModuleErrorf("key is missing")
+ return
+ }
+ ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
}
func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) {
@@ -259,34 +260,52 @@
// files to copy -> dir in apex
copyManifest := make(map[android.Path]string)
+ var keyFile android.Path
+
ctx.WalkDeps(func(child, parent android.Module) bool {
if _, ok := parent.(*apexBundle); ok {
// direct dependencies
depTag := ctx.OtherModuleDependencyTag(child)
+ depName := ctx.OtherModuleName(child)
switch depTag {
case sharedLibTag:
if cc, ok := child.(*cc.Module); ok {
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
copyManifest[fileToCopy] = dirInApex
return true
+ } else {
+ ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
}
case executableTag:
if cc, ok := child.(*cc.Module); ok {
fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
copyManifest[fileToCopy] = dirInApex
return true
+ } else {
+ ctx.PropertyErrorf("binaries", "%q is not a cc_binary module", depName)
}
case javaLibTag:
if java, ok := child.(*java.Library); ok {
fileToCopy, dirInApex := getCopyManifestForJavaLibrary(java)
copyManifest[fileToCopy] = dirInApex
return true
+ } else {
+ ctx.PropertyErrorf("java_libs", "%q is not a java_library module", depName)
}
case prebuiltTag:
if prebuilt, ok := child.(*android.PrebuiltEtc); ok {
fileToCopy, dirInApex := getCopyManifestForPrebuiltEtc(prebuilt)
copyManifest[fileToCopy] = dirInApex
return true
+ } else {
+ ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
+ }
+ case keyTag:
+ if key, ok := child.(*apexKey); ok {
+ keyFile = key.private_key_file
+ return false
+ } else {
+ ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
}
}
} else {
@@ -330,8 +349,6 @@
manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json"))
fileContexts := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.File_contexts, "file_contexts"))
- // TODO(b/114488804) make this customizable
- key := android.PathForSource(ctx, "system/apex/apexer/testdata/testkey.pem")
a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix)
@@ -351,7 +368,7 @@
copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path)
}
implicitInputs := append(android.Paths(nil), filesToCopy...)
- implicitInputs = append(implicitInputs, cannedFsConfig, manifest, fileContexts, key)
+ implicitInputs = append(implicitInputs, cannedFsConfig, manifest, fileContexts, keyFile)
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
@@ -365,7 +382,7 @@
"manifest": manifest.String(),
"file_contexts": fileContexts.String(),
"canned_fs_config": cannedFsConfig.String(),
- "key": key.String(),
+ "key": keyFile.String(),
},
})
@@ -382,6 +399,7 @@
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString()))
fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name+apexSuffix)
+ fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", String(a.properties.Key))
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
}}
}
diff --git a/apex/key.go b/apex/key.go
new file mode 100644
index 0000000..ff348a8
--- /dev/null
+++ b/apex/key.go
@@ -0,0 +1,88 @@
+// Copyright (C) 2018 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 apex
+
+import (
+ "fmt"
+ "io"
+
+ "android/soong/android"
+ "github.com/google/blueprint/proptools"
+)
+
+var String = proptools.String
+
+func init() {
+ android.RegisterModuleType("apex_key", apexKeyFactory)
+}
+
+type apexKey struct {
+ android.ModuleBase
+
+ properties apexKeyProperties
+
+ public_key_file android.Path
+ private_key_file android.Path
+
+ keyName string
+}
+
+type apexKeyProperties struct {
+ // Path to the public key file in avbpubkey format. Installed to the device.
+ // Base name of the file is used as the ID for the key.
+ Public_key *string
+ // Path to the private key file in pem format. Used to sign APEXs.
+ Private_key *string
+}
+
+func apexKeyFactory() android.Module {
+ module := &apexKey{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidModule(module)
+ return module
+}
+
+func (m *apexKey) DepsMutator(ctx android.BottomUpMutatorContext) {
+}
+
+func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ m.public_key_file = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
+ m.private_key_file = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
+
+ pubKeyName := m.public_key_file.Base()[0 : len(m.public_key_file.Base())-len(m.public_key_file.Ext())]
+ privKeyName := m.private_key_file.Base()[0 : len(m.private_key_file.Base())-len(m.private_key_file.Ext())]
+
+ if pubKeyName != privKeyName {
+ ctx.ModuleErrorf("public_key %q (keyname:%q) and private_key %q (keyname:%q) do not have same keyname",
+ m.public_key_file.String(), pubKeyName, m.private_key_file, privKeyName)
+ return
+ }
+ m.keyName = pubKeyName
+
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "etc/security/apex"), m.keyName, m.public_key_file)
+}
+
+func (m *apexKey) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(m.public_key_file),
+ Extra: []android.AndroidMkExtraFunc{
+ func(w io.Writer, outputFile android.Path) {
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_OUT)/etc/security/apex")
+ fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.keyName)
+ },
+ },
+ }
+}
diff --git a/build_test.bash b/build_test.bash
index 4c43224..ee979e7 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -27,6 +27,10 @@
# that's detected in the Go code, which skips calculating the startup time.
export TRACE_BEGIN_SOONG=$(date +%s%N)
+# Remove BUILD_NUMBER so that incremental builds on build servers don't
+# re-read makefiles every time.
+unset BUILD_NUMBER
+
export TOP=$(cd $(dirname ${BASH_SOURCE[0]})/../..; PWD= /bin/pwd)
cd "${TOP}"
source "${TOP}/build/soong/scripts/microfactory.bash"
diff --git a/cc/binary.go b/cc/binary.go
index 5fa501e..15db2ad 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -15,6 +15,8 @@
package cc
import (
+ "github.com/google/blueprint"
+
"android/soong/android"
)
@@ -154,7 +156,8 @@
}
if ctx.Os() == android.LinuxBionic && !binary.static() {
- deps.LinkerScript = "host_bionic_linker_script"
+ deps.DynamicLinker = "linker"
+ deps.LinkerFlagsFile = "host_bionic_linker_flags"
}
}
@@ -244,14 +247,23 @@
switch ctx.Os() {
case android.Android:
flags.DynamicLinker = "/system/bin/linker"
+ if flags.Toolchain.Is64Bit() {
+ flags.DynamicLinker += "64"
+ }
case android.LinuxBionic:
flags.DynamicLinker = ""
default:
ctx.ModuleErrorf("unknown dynamic linker")
}
- if flags.Toolchain.Is64Bit() {
- flags.DynamicLinker += "64"
- }
+ }
+
+ if ctx.Os() == android.LinuxBionic {
+ // Use the dlwrap entry point, but keep _start around so
+ // that it can be used by host_bionic_inject
+ flags.LdFlags = append(flags.LdFlags,
+ "-Wl,--entry=__dlwrap__start",
+ "-Wl,--undefined=_start",
+ )
}
}
@@ -262,7 +274,6 @@
"-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
)
-
}
} else {
if binary.static() {
@@ -288,13 +299,15 @@
sharedLibs := deps.SharedLibs
sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
- if deps.LinkerScript.Valid() {
- flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+deps.LinkerScript.String())
- linkerDeps = append(linkerDeps, deps.LinkerScript.Path())
+ if deps.LinkerFlagsFile.Valid() {
+ flags.LdFlags = append(flags.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")")
+ linkerDeps = append(linkerDeps, deps.LinkerFlagsFile.Path())
}
if flags.DynamicLinker != "" {
- flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
+ } else if ctx.toolchain().Bionic() && !binary.static() {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--no-dynamic-linker")
}
builderFlags := flagsToBuilderFlags(flags)
@@ -323,6 +336,17 @@
binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
}
+ if ctx.Os() == android.LinuxBionic && !binary.static() {
+ injectedOutputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "prelinker", fileName)
+
+ if !deps.DynamicLinker.Valid() {
+ panic("Non-static host bionic modules must have a dynamic linker")
+ }
+
+ binary.injectHostBionicLinkerSymbols(ctx, outputFile, deps.DynamicLinker.Path(), injectedOutputFile)
+ }
+
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
@@ -367,3 +391,26 @@
func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
return binary.toolPath
}
+
+func init() {
+ pctx.HostBinToolVariable("hostBionicSymbolsInjectCmd", "host_bionic_inject")
+}
+
+var injectHostBionicSymbols = pctx.AndroidStaticRule("injectHostBionicSymbols",
+ blueprint.RuleParams{
+ Command: "$hostBionicSymbolsInjectCmd -i $in -l $linker -o $out",
+ CommandDeps: []string{"$hostBionicSymbolsInjectCmd"},
+ }, "linker")
+
+func (binary *binaryDecorator) injectHostBionicLinkerSymbols(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: injectHostBionicSymbols,
+ Description: "inject host bionic symbols",
+ Input: in,
+ Implicit: linker,
+ Output: out,
+ Args: map[string]string{
+ "linker": linker.String(),
+ },
+ })
+}
diff --git a/cc/builder.go b/cc/builder.go
index d9a6cae..3d12538 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -191,11 +191,8 @@
func(ctx android.PackageRuleContext) blueprint.RuleParams {
// TODO(b/78139997): Add -check-all-apis back
commandStr := "($sAbiDiffer $allowFlags -lib $libName -arch $arch -o ${out} -new $in -old $referenceDump)"
- distAbiDiffDir := android.PathForDist(ctx, "abidiffs")
commandStr += "|| (echo ' ---- Please update abi references by running $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l ${libName} ----'"
- if distAbiDiffDir.Valid() {
- commandStr += " && (mkdir -p " + distAbiDiffDir.String() + " && cp ${out} " + distAbiDiffDir.String() + ")"
- }
+ commandStr += " && (mkdir -p $$DIST_DIR/abidiffs && cp ${out} $$DIST_DIR/abidiff/)"
commandStr += " && exit 1)"
return blueprint.RuleParams{
Command: commandStr,
diff --git a/cc/cc.go b/cc/cc.go
index 6320b9c..8b68489 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -83,7 +83,10 @@
ReexportGeneratedHeaders []string
CrtBegin, CrtEnd string
- LinkerScript string
+
+ // Used for host bionic
+ LinkerFlagsFile string
+ DynamicLinker string
}
type PathDeps struct {
@@ -108,7 +111,12 @@
// Paths to crt*.o files
CrtBegin, CrtEnd android.OptionalPath
- LinkerScript android.OptionalPath
+
+ // Path to the file container flags to use with the linker
+ LinkerFlagsFile android.OptionalPath
+
+ // Path to the dynamic linker binary
+ DynamicLinker android.OptionalPath
}
type Flags struct {
@@ -306,7 +314,8 @@
objDepTag = dependencyTag{name: "obj"}
crtBeginDepTag = dependencyTag{name: "crtbegin"}
crtEndDepTag = dependencyTag{name: "crtend"}
- linkerScriptDepTag = dependencyTag{name: "linker script"}
+ linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
+ dynamicLinkerDepTag = dependencyTag{name: "dynamic linker"}
reuseObjTag = dependencyTag{name: "reuse objects"}
ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
@@ -1062,8 +1071,11 @@
if deps.CrtEnd != "" {
actx.AddVariationDependencies(nil, crtEndDepTag, deps.CrtEnd)
}
- if deps.LinkerScript != "" {
- actx.AddDependency(c, linkerScriptDepTag, deps.LinkerScript)
+ if deps.LinkerFlagsFile != "" {
+ actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
+ }
+ if deps.DynamicLinker != "" {
+ actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
}
version := ctx.sdkVersion()
@@ -1257,13 +1269,13 @@
} else {
ctx.ModuleErrorf("module %q is not a genrule", depName)
}
- case linkerScriptDepTag:
+ case linkerFlagsDepTag:
if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
files := genRule.GeneratedSourceFiles()
if len(files) == 1 {
- depPaths.LinkerScript = android.OptionalPathForPath(files[0])
+ depPaths.LinkerFlagsFile = android.OptionalPathForPath(files[0])
} else if len(files) > 1 {
- ctx.ModuleErrorf("module %q can only generate a single file if used for a linker script", depName)
+ ctx.ModuleErrorf("module %q can only generate a single file if used for a linker flag file", depName)
}
} else {
ctx.ModuleErrorf("module %q is not a genrule", depName)
@@ -1358,6 +1370,8 @@
depPaths.CrtBegin = linkFile
case crtEndDepTag:
depPaths.CrtEnd = linkFile
+ case dynamicLinkerDepTag:
+ depPaths.DynamicLinker = linkFile
}
switch depTag {
diff --git a/cc/compiler.go b/cc/compiler.go
index 68d8593..5ac5d79 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -224,6 +224,10 @@
deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
}
+ if compiler.hasSrcExt(".sysprop") {
+ deps.SharedLibs = append(deps.SharedLibs, "libbase")
+ }
+
if Bool(compiler.Properties.Openmp) {
deps.StaticLibs = append(deps.StaticLibs, "libomp")
}
@@ -387,7 +391,7 @@
flags.GlobalFlags = append([]string{"${config.ClangExternalCflags}"}, flags.GlobalFlags...)
}
- if ctx.Device() {
+ if tc.Bionic() {
if Bool(compiler.Properties.Rtti) {
flags.CppFlags = append(flags.CppFlags, "-frtti")
} else {
@@ -489,6 +493,11 @@
flags = rsFlags(ctx, flags, &compiler.Properties)
}
+ if compiler.hasSrcExt(".sysprop") {
+ flags.GlobalFlags = append(flags.GlobalFlags,
+ "-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
+ }
+
if len(compiler.Properties.Srcs) > 0 {
module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
if inList("-Wno-error", flags.CFlags) || inList("-Wno-error", flags.CppFlags) {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index cacd287..bcff775 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -25,6 +25,11 @@
arm64Cflags = []string{
// Help catch common 32/64-bit errors.
"-Werror=implicit-function-declaration",
+
+ // Prevent use of x18 register.
+ // TODO(pcc): Remove this flag once we upgrade past LLVM r340889
+ // which does this by default on Android.
+ "-ffixed-x18",
}
arm64ArchVariantCflags = map[string][]string{
@@ -60,6 +65,11 @@
// core (cortex-a55) and is sensitive to ordering.
"-mcpu=cortex-a55",
},
+ "cortex-a76": []string{
+ // Use the cortex-a55 since it is similar to the little
+ // core (cortex-a55) and is sensitive to ordering.
+ "-mcpu=cortex-a55",
+ },
"kryo": []string{
"-mcpu=kryo",
},
@@ -85,6 +95,7 @@
"cortex-a72",
"cortex-a73",
"cortex-a75",
+ "cortex-a76",
"kryo",
"exynos-m1",
"exynos-m2",
@@ -136,6 +147,7 @@
"cortex-a72": "${config.Arm64ClangCortexA53Cflags}",
"cortex-a73": "${config.Arm64ClangCortexA53Cflags}",
"cortex-a75": "${config.Arm64ClangCortexA55Cflags}",
+ "cortex-a76": "${config.Arm64ClangCortexA55Cflags}",
"kryo": "${config.Arm64ClangKryoCflags}",
"exynos-m1": "${config.Arm64ClangExynosM1Cflags}",
"exynos-m2": "${config.Arm64ClangExynosM2Cflags}",
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 95c9495..75f5962 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -117,6 +117,15 @@
// better solution comes around. See Bug 27340895
"-D__ARM_FEATURE_LPAE=1",
},
+ "cortex-a76": []string{
+ "-mcpu=cortex-a55",
+ "-mfpu=neon-fp-armv8",
+ // Fake an ARM compiler flag as these processors support LPAE which GCC/clang
+ // don't advertise.
+ // TODO This is a hack and we need to add it for each processor that supports LPAE until some
+ // better solution comes around. See Bug 27340895
+ "-D__ARM_FEATURE_LPAE=1",
+ },
"krait": []string{
"-mcpu=krait",
"-mfpu=neon-vfpv4",
@@ -162,6 +171,7 @@
"cortex-a72",
"cortex-a73",
"cortex-a75",
+ "cortex-a76",
"krait",
"kryo",
"exynos-m1",
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 5cf2421..5c82604 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -92,12 +92,7 @@
"-Wl,-m,aarch64_elf64_le_vec",
})
-var ClangLibToolingUnknownCflags = []string{
- // Remove -flto and other flto dependent flags.
- "-flto*",
- "-fsanitize*",
- "-fwhole-program-vtables",
-}
+var ClangLibToolingUnknownCflags []string = nil
func init() {
pctx.StaticVariable("ClangExtraCflags", strings.Join([]string{
@@ -179,6 +174,11 @@
// this new warning are fixed.
"-Wno-null-pointer-arithmetic",
+ // http://b/72330874 Disable -Wenum-compare until the instances detected by this new
+ // warning are fixed.
+ "-Wno-enum-compare",
+ "-Wno-enum-compare-switch",
+
// Disable c++98-specific warning since Android is not concerned with C++98
// compatibility.
"-Wno-c++98-compat-extra-semi",
@@ -196,11 +196,9 @@
"-Wno-dangling-field",
}, " "))
- // Extra cflags for projects under external/ directory to disable warnings that are infeasible
- // to fix in all the external projects and their upstream repos.
+ // Extra cflags for projects under external/ directory
pctx.StaticVariable("ClangExtraExternalCflags", strings.Join([]string{
- "-Wno-enum-compare",
- "-Wno-enum-compare-switch",
+ // TODO(yikong): Move -Wno flags here
}, " "))
}
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 8a12523..5fb88e6 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -139,6 +139,10 @@
return true
}
+func (toolchainLinuxBionic) LibclangRuntimeLibraryArch() string {
+ return "x86_64"
+}
+
var toolchainLinuxBionicSingleton Toolchain = &toolchainLinuxBionic{}
func linuxBionicToolchainFactory(arch android.Arch) Toolchain {
diff --git a/cc/gen.go b/cc/gen.go
index 487f662..29a2bb2 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -19,6 +19,8 @@
// functions.
import (
+ "path/filepath"
+
"github.com/google/blueprint"
"android/soong/android"
@@ -30,6 +32,7 @@
pctx.SourcePathVariable("yaccDataDir", "prebuilts/build-tools/common/bison")
pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
+ pctx.HostBinToolVariable("syspropCmd", "sysprop_cpp")
}
var (
@@ -55,6 +58,13 @@
},
"aidlFlags", "outDir")
+ sysprop = pctx.AndroidStaticRule("sysprop",
+ blueprint.RuleParams{
+ Command: "$syspropCmd --header-output-dir=$headerOutDir --source-output-dir=$srcOutDir --include-name=$includeName $in",
+ CommandDeps: []string{"$syspropCmd"},
+ },
+ "headerOutDir", "srcOutDir", "includeName")
+
windmc = pctx.AndroidStaticRule("windmc",
blueprint.RuleParams{
Command: "$windmcCmd -r$$(dirname $out) -h$$(dirname $out) $in",
@@ -82,7 +92,6 @@
}
func genAidl(ctx android.ModuleContext, aidlFile android.Path, outFile android.ModuleGenPath, aidlFlags string) android.Paths {
-
ctx.Build(pctx, android.BuildParams{
Rule: aidl,
Description: "aidl " + aidlFile.Rel(),
@@ -107,6 +116,26 @@
})
}
+func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Path) {
+ headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h")
+ cppFile := android.PathForModuleGen(ctx, "sysprop", syspropFile.Rel()+".cpp")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: sysprop,
+ Description: "sysprop " + syspropFile.Rel(),
+ Output: cppFile,
+ ImplicitOutput: headerFile,
+ Input: syspropFile,
+ Args: map[string]string{
+ "headerOutDir": filepath.Dir(headerFile.String()),
+ "srcOutDir": filepath.Dir(cppFile.String()),
+ "includeName": syspropFile.Rel() + ".h",
+ },
+ })
+
+ return cppFile, headerFile
+}
+
func genWinMsg(ctx android.ModuleContext, srcFile android.Path, flags builderFlags) (android.Path, android.Path) {
headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
@@ -169,6 +198,10 @@
rcFile, headerFile := genWinMsg(ctx, srcFile, buildFlags)
srcFiles[i] = rcFile
deps = append(deps, headerFile)
+ case ".sysprop":
+ cppFile, headerFile := genSysprop(ctx, srcFile)
+ srcFiles[i] = cppFile
+ deps = append(deps, headerFile)
}
}
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
new file mode 100644
index 0000000..92024ac
--- /dev/null
+++ b/cc/genrule_test.go
@@ -0,0 +1,88 @@
+// Copyright 2018 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 cc
+
+import (
+ "reflect"
+ "testing"
+
+ "android/soong/android"
+)
+
+func testGenruleContext(config android.Config, bp string,
+ fs map[string][]byte) *android.TestContext {
+
+ ctx := android.NewTestArchContext()
+ ctx.RegisterModuleType("cc_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
+ ctx.Register()
+
+ mockFS := map[string][]byte{
+ "Android.bp": []byte(bp),
+ "tool": nil,
+ "foo": nil,
+ "bar": nil,
+ }
+
+ for k, v := range fs {
+ mockFS[k] = v
+ }
+
+ ctx.MockFileSystem(mockFS)
+
+ return ctx
+}
+
+func TestArchGenruleCmd(t *testing.T) {
+ config := android.TestArchConfig(buildDir, nil)
+ bp := `
+ cc_genrule {
+ name: "gen",
+ tool_files: ["tool"],
+ cmd: "$(location tool) $(in) $(out)",
+ arch: {
+ arm: {
+ srcs: ["foo"],
+ out: ["out_arm"],
+ },
+ arm64: {
+ srcs: ["bar"],
+ out: ["out_arm64"],
+ },
+ },
+ }
+ `
+
+ ctx := testGenruleContext(config, bp, nil)
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ if errs == nil {
+ _, errs = ctx.PrepareBuildActions(config)
+ }
+ if errs != nil {
+ t.Fatal(errs)
+ }
+
+ gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out_arm")
+ expected := []string{"foo"}
+ if !reflect.DeepEqual(expected, gen.Inputs.Strings()) {
+ t.Errorf(`want arm inputs %v, got %v`, expected, gen.Inputs.Strings())
+ }
+
+ gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm64")
+ expected = []string{"bar"}
+ if !reflect.DeepEqual(expected, gen.Inputs.Strings()) {
+ t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Inputs.Strings())
+ }
+}
diff --git a/cc/library.go b/cc/library.go
index 9eb3f47..920292d 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -678,6 +678,14 @@
}
}
+ if library.baseCompiler.hasSrcExt(".sysprop") {
+ flags := []string{
+ "-I" + android.PathForModuleGen(ctx, "sysprop", "include").String(),
+ }
+ library.reexportFlags(flags)
+ library.reuseExportedFlags = append(library.reuseExportedFlags, flags...)
+ }
+
return out
}
diff --git a/cc/linker.go b/cc/linker.go
index 2e1828a..28f4747 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -289,7 +289,7 @@
if linker.Properties.Use_clang_lld != nil {
return Bool(linker.Properties.Use_clang_lld)
}
- return ctx.Config().UseClangLld()
+ return true
}
// ModuleContext extends BaseModuleContext
diff --git a/cc/lto.go b/cc/lto.go
index fd2a869..d9d2662 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -76,7 +76,7 @@
if lto.Properties.Use_clang_lld != nil {
return Bool(lto.Properties.Use_clang_lld)
}
- return ctx.Config().UseClangLld()
+ return true
}
func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
@@ -113,6 +113,13 @@
flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-inline-threshold=0")
flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-unroll-threshold=0")
}
+
+ if ctx.Arch().ArchType == android.Arm64 {
+ // Prevent use of x18 register on arm64.
+ // TODO(pcc): Remove this flag once we upgrade past LLVM r340889
+ // which does this by default on Android.
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-mattr=+reserve-x18")
+ }
}
return flags
}
diff --git a/cc/makevars.go b/cc/makevars.go
index b590786..32674a9 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -172,13 +172,13 @@
sort.Strings(ndkMigratedLibs)
ctx.Strict("NDK_MIGRATED_LIBS", strings.Join(ndkMigratedLibs, " "))
- hostTargets := ctx.Config().Targets[android.Host]
+ hostTargets := ctx.Config().Targets[android.BuildOs]
makeVarsToolchain(ctx, "", hostTargets[0])
if len(hostTargets) > 1 {
makeVarsToolchain(ctx, "2ND_", hostTargets[1])
}
- crossTargets := ctx.Config().Targets[android.HostCross]
+ crossTargets := ctx.Config().Targets[android.Windows]
if len(crossTargets) > 0 {
makeVarsToolchain(ctx, "", crossTargets[0])
if len(crossTargets) > 1 {
@@ -186,7 +186,7 @@
}
}
- deviceTargets := ctx.Config().Targets[android.Device]
+ deviceTargets := ctx.Config().Targets[android.Android]
makeVarsToolchain(ctx, "", deviceTargets[0])
if len(deviceTargets) > 1 {
makeVarsToolchain(ctx, "2ND_", deviceTargets[1])
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 1cd4829..a7d6e04 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -134,7 +134,7 @@
// but keep them when doing regular platform build.
// Ndk_abis property is only set to true with build/soong/scripts/build-ndk-prebuilts.sh
// TODO: Revert this once MIPS is supported in NDK again.
- if Bool(ctx.AConfig().Ndk_abis) && strings.Contains(ctx.ModuleName(), "mips") {
+ if ctx.Config().NdkAbis() && strings.Contains(ctx.ModuleName(), "mips") {
return
}
@@ -278,11 +278,7 @@
module.AddProperties(&module.properties)
- // Host module rather than device module because device module install steps
- // do not get run when embedded in make. We're not any of the existing
- // module types that can be exposed via the Android.mk exporter, so just use
- // a host module.
- android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
+ android.InitAndroidModule(module)
return module
}
@@ -362,11 +358,7 @@
module.AddProperties(&module.properties)
- // Host module rather than device module because device module install steps
- // do not get run when embedded in make. We're not any of the existing
- // module types that can be exposed via the Android.mk exporter, so just use
- // a host module.
- android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
+ android.InitAndroidModule(module)
return module
}
diff --git a/cc/sabi.go b/cc/sabi.go
index 72a3c5c..4a86499 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -73,17 +73,6 @@
flags.ToolingCFlags = filterOutWithPrefix(flags.CFlags, config.ClangLibToolingUnknownCflags)
flags.ToolingCppFlags = filterOutWithPrefix(flags.CppFlags, config.ClangLibToolingUnknownCflags)
- // RSClang does not support recent mcpu option likes exynos-m2.
- // So we need overriding mcpu option when we want to use it.
- mappedArch := map[string]string{
- "exynos-m2": "cortex-a53",
- "cortex-a55": "cortex-a53",
- "cortex-a75": "cortex-a57",
- }
- if arch, ok := mappedArch[ctx.Arch().CpuVariant]; ok {
- flags.ToolingCFlags = append(flags.ToolingCFlags, "-mcpu="+arch)
- }
-
return flags
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 330a5e3..527ae33 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -471,6 +471,13 @@
diagSanitizers = append(diagSanitizers, "cfi")
}
+ if ctx.Arch().ArchType == android.Arm64 {
+ // Prevent use of x18 register on arm64.
+ // TODO(pcc): Remove this flag once we upgrade past LLVM r340889
+ // which does this by default on Android.
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-mattr=+reserve-x18")
+ }
+
if ctx.staticBinary() {
_, flags.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.CFlags)
_, flags.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.LdFlags)
diff --git a/cc/vndk.go b/cc/vndk.go
index 5a24a98..1a9b77a 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -15,6 +15,7 @@
package cc
import (
+ "errors"
"sort"
"strings"
"sync"
@@ -151,38 +152,42 @@
}
// Check the dependencies of VNDK shared libraries.
- if !vndkIsVndkDepAllowed(vndk, to.vndkdep) {
- ctx.ModuleErrorf("(%s) should not link to %q (%s)",
- vndk.typeName(), to.Name(), to.vndkdep.typeName())
+ if err := vndkIsVndkDepAllowed(vndk, to.vndkdep); err != nil {
+ ctx.ModuleErrorf("(%s) should not link to %q (%s): %v",
+ vndk.typeName(), to.Name(), to.vndkdep.typeName(), err)
return
}
}
-func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) bool {
+func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error {
// Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
if from.isVndkExt() {
if from.isVndkSp() {
- // VNDK-SP-Ext may depend on VNDK-SP, VNDK-SP-Ext, or vendor libs (excluding
- // VNDK and VNDK-Ext).
- return to.isVndkSp() || !to.isVndk()
+ if to.isVndk() && !to.isVndkSp() {
+ return errors.New("VNDK-SP extensions must not depend on VNDK or VNDK extensions")
+ }
+ return nil
}
// VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
- return true
+ return nil
}
if from.isVndk() {
if to.isVndkExt() {
- // VNDK-core and VNDK-SP must not depend on VNDK extensions.
- return false
+ return errors.New("VNDK-core and VNDK-SP must not depend on VNDK extensions")
}
if from.isVndkSp() {
- // VNDK-SP must only depend on VNDK-SP.
- return to.isVndkSp()
+ if !to.isVndkSp() {
+ return errors.New("VNDK-SP must only depend on VNDK-SP")
+ }
+ return nil
}
- // VNDK-core may depend on VNDK-core or VNDK-SP.
- return to.isVndk()
+ if !to.isVndk() {
+ return errors.New("VNDK-core must only depend on VNDK-core or VNDK-SP")
+ }
+ return nil
}
// Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
- return true
+ return nil
}
var (
diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go
index 3f24ab2..ea0bf4e 100644
--- a/cmd/extract_linker/main.go
+++ b/cmd/extract_linker/main.go
@@ -13,7 +13,7 @@
// limitations under the License.
// This tool extracts ELF LOAD segments from our linker binary, and produces an
-// assembly file and linker script which will embed those segments as sections
+// assembly file and linker flags which will embed those segments as sections
// in another binary.
package main
@@ -26,38 +26,15 @@
"io/ioutil"
"log"
"os"
- "text/template"
+ "strings"
)
-var linkerScriptTemplate = template.Must(template.New("linker_script").Parse(`
-ENTRY(__dlwrap__start)
-SECTIONS {
- __dlwrap_original_start = _start;
- /DISCARD/ : { *(.interp) }
-
-{{range .}}
- . = {{ printf "0x%x" .Vaddr }};
- {{.Name}} : { KEEP(*({{.Name}})) }
-{{end}}
-
- .text : { *(.text .text.*) }
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .data : { *(.data .data.* .gnu.linkonce.d.*) }
- .bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) }
-}
-`))
-
-type LinkerSection struct {
- Name string
- Vaddr uint64
-}
-
func main() {
var asmPath string
- var scriptPath string
+ var flagsPath string
flag.StringVar(&asmPath, "s", "", "Path to save the assembly file")
- flag.StringVar(&scriptPath, "T", "", "Path to save the linker script")
+ flag.StringVar(&flagsPath, "f", "", "Path to save the linker flags")
flag.Parse()
f, err := os.Open(flag.Arg(0))
@@ -72,19 +49,21 @@
}
asm := &bytes.Buffer{}
-
- fmt.Fprintln(asm, ".globl __dlwrap_linker_entry")
- fmt.Fprintf(asm, ".set __dlwrap_linker_entry, 0x%x\n\n", ef.Entry)
-
baseLoadAddr := uint64(0x1000)
- sections := []LinkerSection{}
load := 0
+ linkFlags := []string{}
+
+ fmt.Fprintln(asm, ".globl __dlwrap_linker_offset")
+ fmt.Fprintf(asm, ".set __dlwrap_linker_offset, 0x%x\n", baseLoadAddr)
+
for _, prog := range ef.Progs {
if prog.Type != elf.PT_LOAD {
continue
}
sectionName := fmt.Sprintf(".linker.sect%d", load)
+ symName := fmt.Sprintf("__dlwrap_linker_sect%d", load)
+
flags := ""
if prog.Flags&elf.PF_W != 0 {
flags += "w"
@@ -94,10 +73,12 @@
}
fmt.Fprintf(asm, ".section %s, \"a%s\"\n", sectionName, flags)
- if load == 0 {
- fmt.Fprintln(asm, ".globl __dlwrap_linker_code_start")
- fmt.Fprintln(asm, "__dlwrap_linker_code_start:")
- }
+ fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName)
+
+ linkFlags = append(linkFlags,
+ fmt.Sprintf("-Wl,--undefined=%s", symName),
+ fmt.Sprintf("-Wl,--section-start=%s=0x%x",
+ sectionName, baseLoadAddr+prog.Vaddr))
buffer, _ := ioutil.ReadAll(prog.Open())
bytesToAsm(asm, buffer)
@@ -113,11 +94,6 @@
}
fmt.Fprintln(asm)
- sections = append(sections, LinkerSection{
- Name: sectionName,
- Vaddr: baseLoadAddr + prog.Vaddr,
- })
-
load += 1
}
@@ -127,13 +103,10 @@
}
}
- if scriptPath != "" {
- buf := &bytes.Buffer{}
- if err := linkerScriptTemplate.Execute(buf, sections); err != nil {
- log.Fatalf("Failed to create linker script: %v", err)
- }
- if err := ioutil.WriteFile(scriptPath, buf.Bytes(), 0777); err != nil {
- log.Fatalf("Unable to write %q: %v", scriptPath, err)
+ if flagsPath != "" {
+ flags := strings.Join(linkFlags, " ")
+ if err := ioutil.WriteFile(flagsPath, []byte(flags), 0777); err != nil {
+ log.Fatalf("Unable to write %q: %v", flagsPath, err)
}
}
}
diff --git a/cmd/symbol_inject/Android.bp b/cmd/host_bionic_inject/Android.bp
similarity index 63%
copy from cmd/symbol_inject/Android.bp
copy to cmd/host_bionic_inject/Android.bp
index a2ea12b..acce683 100644
--- a/cmd/symbol_inject/Android.bp
+++ b/cmd/host_bionic_inject/Android.bp
@@ -13,20 +13,7 @@
// limitations under the License.
blueprint_go_binary {
- name: "symbol_inject",
- srcs: [
- "symbol_inject.go",
- "elf.go",
- "macho.go",
- "pe.go",
- ],
- testSrcs: [
- "elf_symboldata_test.go",
- "elf_test.go",
- "macho_symboldata_test.go",
- "macho_test.go",
- "pe_symboldata_test.go",
- "pe_test.go",
- "symbol_inject_test.go",
- ],
+ name: "host_bionic_inject",
+ deps: ["soong-symbol_inject"],
+ srcs: ["host_bionic_inject.go"],
}
diff --git a/cmd/host_bionic_inject/host_bionic_inject.go b/cmd/host_bionic_inject/host_bionic_inject.go
new file mode 100644
index 0000000..0dabbba
--- /dev/null
+++ b/cmd/host_bionic_inject/host_bionic_inject.go
@@ -0,0 +1,174 @@
+// Copyright 2018 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.
+
+// Verifies a host bionic executable with an embedded linker, then injects
+// the address of the _start function for the linker_wrapper to use.
+package main
+
+import (
+ "debug/elf"
+ "flag"
+ "fmt"
+ "io"
+ "os"
+
+ "android/soong/symbol_inject"
+)
+
+func main() {
+ var inputFile, linkerFile, outputFile string
+
+ flag.StringVar(&inputFile, "i", "", "Input file")
+ flag.StringVar(&linkerFile, "l", "", "Linker file")
+ flag.StringVar(&outputFile, "o", "", "Output file")
+ flag.Parse()
+
+ if inputFile == "" || linkerFile == "" || outputFile == "" || flag.NArg() != 0 {
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ r, err := os.Open(inputFile)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(2)
+ }
+ defer r.Close()
+
+ file, err := symbol_inject.OpenFile(r)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(3)
+ }
+
+ linker, err := elf.Open(linkerFile)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(4)
+ }
+
+ start_addr, err := parseElf(r, linker)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(5)
+ }
+
+ w, err := os.OpenFile(outputFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(6)
+ }
+ defer w.Close()
+
+ err = symbol_inject.InjectUint64Symbol(file, w, "__dlwrap_original_start", start_addr)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(7)
+ }
+}
+
+// Check the ELF file, and return the address to the _start function
+func parseElf(r io.ReaderAt, linker *elf.File) (uint64, error) {
+ file, err := elf.NewFile(r)
+ if err != nil {
+ return 0, err
+ }
+
+ symbols, err := file.Symbols()
+ if err != nil {
+ return 0, err
+ }
+
+ for _, prog := range file.Progs {
+ if prog.Type == elf.PT_INTERP {
+ return 0, fmt.Errorf("File should not have a PT_INTERP header")
+ }
+ }
+
+ if dlwrap_start, err := findSymbol(symbols, "__dlwrap__start"); err != nil {
+ return 0, err
+ } else if dlwrap_start.Value != file.Entry {
+ return 0, fmt.Errorf("Expected file entry(0x%x) to point to __dlwrap_start(0x%x)",
+ file.Entry, dlwrap_start.Value)
+ }
+
+ err = checkLinker(file, linker, symbols)
+ if err != nil {
+ return 0, err
+ }
+
+ start, err := findSymbol(symbols, "_start")
+ if err != nil {
+ return 0, fmt.Errorf("Failed to find _start symbol")
+ }
+ return start.Value, nil
+}
+
+func findSymbol(symbols []elf.Symbol, name string) (elf.Symbol, error) {
+ for _, sym := range symbols {
+ if sym.Name == name {
+ return sym, nil
+ }
+ }
+ return elf.Symbol{}, fmt.Errorf("Failed to find symbol %q", name)
+}
+
+// Check that all of the PT_LOAD segments have been embedded properly
+func checkLinker(file, linker *elf.File, fileSyms []elf.Symbol) error {
+ dlwrap_linker_offset, err := findSymbol(fileSyms, "__dlwrap_linker_offset")
+ if err != nil {
+ return err
+ }
+
+ for i, lprog := range linker.Progs {
+ if lprog.Type != elf.PT_LOAD {
+ continue
+ }
+
+ found := false
+ for j, prog := range file.Progs {
+ if prog.Type != elf.PT_LOAD {
+ continue
+ }
+
+ if lprog.Vaddr+dlwrap_linker_offset.Value != prog.Vaddr {
+ continue
+ }
+ found = true
+
+ if lprog.Memsz != prog.Memsz {
+ return fmt.Errorf("Linker prog %d (0x%x) memsz (0x%x) does not match (0x%x)",
+ i, lprog.Vaddr, lprog.Memsz, prog.Memsz)
+ }
+
+ // The linker shouldn't be using BSS, since only one
+ // BSS section is supported per ELF file.
+ if prog.Memsz != prog.Filesz {
+ return fmt.Errorf("Embedded prog %d (0x%x) memsz (0x%x) does not match filesz (0x%x)",
+ j, prog.Vaddr, prog.Memsz, prog.Filesz)
+ }
+
+ if lprog.Flags != prog.Flags {
+ return fmt.Errorf("Linker prog %d (0x%x) flags (%s) do not match (%s)",
+ i, lprog.Vaddr, lprog.Flags, prog.Flags)
+ }
+ }
+ if !found {
+ return fmt.Errorf("Linker prog %d (0x%x) not found at offset 0x%x",
+ i, lprog.Vaddr, dlwrap_linker_offset.Value)
+ }
+ }
+
+ return nil
+}
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index f383de9..8e71a97 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -173,6 +173,10 @@
return ze.content.FileHeader.CRC32
}
+func (ze zipEntry) Size() uint64 {
+ return ze.content.FileHeader.UncompressedSize64
+}
+
func (ze zipEntry) WriteToZip(dest string, zw *zip.Writer) error {
return zw.CopyFrom(ze.content, dest)
}
@@ -195,6 +199,10 @@
return crc32.ChecksumIEEE(be.content)
}
+func (be bufferEntry) Size() uint64 {
+ return uint64(len(be.content))
+}
+
func (be bufferEntry) WriteToZip(dest string, zw *zip.Writer) error {
w, err := zw.CreateHeader(be.fh)
if err != nil {
@@ -215,6 +223,7 @@
String() string
IsDir() bool
CRC32() uint32
+ Size() uint64
WriteToZip(dest string, zw *zip.Writer) error
}
@@ -369,25 +378,27 @@
return fmt.Errorf("Directory/file mismatch at %v from %v and %v\n",
dest, existingSource, source)
}
+
if ignoreDuplicates {
continue
}
+
if emulateJar &&
file.Name == jar.ManifestFile || file.Name == jar.ModuleInfoClass {
// Skip manifest and module info files that are not from the first input file
continue
}
- if !source.IsDir() {
- if emulateJar {
- if existingSource.CRC32() != source.CRC32() {
- fmt.Fprintf(os.Stdout, "WARNING: Duplicate path %v found in %v and %v\n",
- dest, existingSource, source)
- }
- } else {
- return fmt.Errorf("Duplicate path %v found in %v and %v\n",
- dest, existingSource, source)
- }
+
+ if source.IsDir() {
+ continue
}
+
+ if existingSource.CRC32() == source.CRC32() && existingSource.Size() == source.Size() {
+ continue
+ }
+
+ return fmt.Errorf("Duplicate path %v found in %v and %v\n",
+ dest, existingSource, source)
}
}
}
diff --git a/cmd/merge_zips/merge_zips_test.go b/cmd/merge_zips/merge_zips_test.go
index f91111f..19fa5ed 100644
--- a/cmd/merge_zips/merge_zips_test.go
+++ b/cmd/merge_zips/merge_zips_test.go
@@ -88,6 +88,14 @@
ignoreDuplicates: true,
},
{
+ name: "duplicates identical",
+ in: [][]testZipEntry{
+ {a},
+ {a},
+ },
+ out: []testZipEntry{a},
+ },
+ {
name: "sort",
in: [][]testZipEntry{
{be, bc, bDir, bbDir, bbb, A, metainfDir, manifestFile},
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 2824e49..e6c6efd 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -87,7 +87,7 @@
Export_include_dirs []string
// list of input files
- Srcs []string
+ Srcs []string `android:"arch_variant"`
}
type Module struct {
@@ -504,7 +504,7 @@
type genRuleProperties struct {
// names of the output files that will be generated
- Out []string
+ Out []string `android:"arch_variant"`
}
var Bool = proptools.Bool
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 7e16ce1..a99fa18 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -27,7 +27,7 @@
func setUp() {
var err error
- buildDir, err = ioutil.TempDir("", "soong_java_test")
+ buildDir, err = ioutil.TempDir("", "genrule_test")
if err != nil {
panic(err)
}
diff --git a/java/aapt2.go b/java/aapt2.go
index 70c7507..5553bfd 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -111,7 +111,8 @@
var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
blueprint.RuleParams{
- Command: `${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
+ Command: `rm -rf $genDir && ` +
+ `${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
`--output-text-symbols ${rTxt} $inFlags && ` +
`${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` +
`${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`,
diff --git a/java/aar.go b/java/aar.go
index 35fb96f..a06d191 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -250,6 +250,8 @@
}
switch ctx.OtherModuleDependencyTag(module) {
+ case instrumentationForTag:
+ // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
case libTag, frameworkResTag:
if exportPackage != nil {
sharedLibs = append(sharedLibs, exportPackage)
diff --git a/java/app.go b/java/app.go
index d21b62a..5d25dcf 100644
--- a/java/app.go
+++ b/java/app.go
@@ -318,12 +318,6 @@
}
func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if String(a.appTestProperties.Instrumentation_for) != "" {
- a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
- "--rename-instrumentation-target-package",
- String(a.appTestProperties.Instrumentation_for))
- }
-
a.generateAndroidBuildActions(ctx)
a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath)
@@ -335,6 +329,12 @@
android.ExtractSourceDeps(ctx, a.testProperties.Test_config_template)
android.ExtractSourcesDeps(ctx, a.testProperties.Data)
a.AndroidApp.DepsMutator(ctx)
+ if a.appTestProperties.Instrumentation_for != nil {
+ // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
+ // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
+ // use instrumentationForTag instead of libTag.
+ ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
+ }
}
func AndroidTestFactory() android.Module {
diff --git a/java/builder.go b/java/builder.go
index f55a7c7..cefb916 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -399,6 +399,17 @@
})
}
+func GenerateMainClassManifest(ctx android.ModuleContext, outputFile android.WritablePath, mainClass string) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Description: "manifest",
+ Output: outputFile,
+ Args: map[string]string{
+ "content": "Main-Class: " + mainClass + "\n",
+ },
+ })
+}
+
type classpath []android.Path
func (x *classpath) FormJavaClassPath(optName string) string {
diff --git a/java/config/config.go b/java/config/config.go
index 85cb588..d2a8c46 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -27,8 +27,8 @@
var (
pctx = android.NewPackageContext("android/soong/java/config")
- DefaultBootclasspathLibraries = []string{"core-oj", "core-libart", "core-simple", "bouncycastle", "conscrypt", "okhttp"}
- DefaultSystemModules = "core-system-modules"
+ DefaultBootclasspathLibraries = []string{"core.platform.api.stubs", "core-lambda-stubs"}
+ DefaultSystemModules = "core-platform-api-stubs-system-modules"
DefaultLibraries = []string{"ext", "framework"}
DefaultLambdaStubsLibrary = "core-lambda-stubs"
SdkLambdaStubsPath = "prebuilts/sdk/tools/core-lambda-stubs.jar"
diff --git a/java/dex.go b/java/dex.go
index ce0c18e..625fb83 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -157,6 +157,8 @@
if !Bool(opt.Obfuscate) {
r8Flags = append(r8Flags, "-dontobfuscate")
}
+ // TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
+ // dictionary of the app and move the app from libraryjars to injars.
return r8Flags, r8Deps
}
@@ -171,8 +173,6 @@
outDir := android.PathForModuleOut(ctx, "dex")
if useR8 {
- // TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
- // dictionary of the app and move the app from libraryjars to injars.
proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
j.proguardDictionary = proguardDictionary
r8Flags, r8Deps := j.r8Flags(ctx, flags)
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 063f2c1..fca5fc4 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -388,6 +388,7 @@
metalavaStubsFlags string
metalavaAnnotationsFlags string
+ metalavaInclusionAnnotationsFlags string
metalavaApiLevelsAnnotationsFlags string
metalavaApiToXmlFlags string
@@ -1382,7 +1383,6 @@
} else {
metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
}
-
return metalavaFlags
}
@@ -1419,8 +1419,15 @@
}
})
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
- flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction "
+ flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
}
+
+ return flags
+}
+
+func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
+ implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
+ var flags string
ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
if t, ok := m.(*ExportedDroiddocDir); ok {
*implicits = append(*implicits, t.deps...)
@@ -1599,6 +1606,7 @@
flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
flags.metalavaAnnotationsFlags = d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
+ flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
@@ -1610,7 +1618,7 @@
}
d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
- flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+
+ flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
@@ -1621,8 +1629,9 @@
"check_api.current_removed_api_file")
d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
- opts := d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
- " --check-compatibility:removed:current " + removedApiFile.String() + " "
+ opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
+ " --check-compatibility:removed:current " + removedApiFile.String() +
+ flags.metalavaInclusionAnnotationsFlags
d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
@@ -1651,8 +1660,9 @@
"check_api.last_released.removed_api_file")
d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
- opts := d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
- " --check-compatibility:removed:released " + removedApiFile.String() + " "
+ opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
+ flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
+ removedApiFile.String() + " "
d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
diff --git a/java/gen.go b/java/gen.go
index a993829..993e6d1 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -26,6 +26,7 @@
func init() {
pctx.HostBinToolVariable("aidlCmd", "aidl")
+ pctx.HostBinToolVariable("syspropCmd", "sysprop_java")
pctx.SourcePathVariable("logtagsCmd", "build/tools/java-event-log-tags.py")
pctx.SourcePathVariable("mergeLogtagsCmd", "build/tools/merge-event-log-tags.py")
}
@@ -49,6 +50,17 @@
Command: "$mergeLogtagsCmd -o $out $in",
CommandDeps: []string{"$mergeLogtagsCmd"},
})
+
+ sysprop = pctx.AndroidStaticRule("sysprop",
+ blueprint.RuleParams{
+ Command: `rm -rf $out.tmp && mkdir -p $out.tmp && ` +
+ `$syspropCmd --java-output-dir $out.tmp $in && ` +
+ `${config.SoongZipCmd} -jar -o $out -C $out.tmp -D $out.tmp && rm -rf $out.tmp`,
+ CommandDeps: []string{
+ "$syspropCmd",
+ "${config.SoongZipCmd}",
+ },
+ })
)
func genAidl(ctx android.ModuleContext, aidlFile android.Path, aidlFlags string) android.Path {
@@ -82,6 +94,19 @@
return javaFile
}
+func genSysprop(ctx android.ModuleContext, syspropFile android.Path) android.Path {
+ srcJarFile := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcjar")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: sysprop,
+ Description: "sysprop_java " + syspropFile.Rel(),
+ Output: srcJarFile,
+ Input: syspropFile,
+ })
+
+ return srcJarFile
+}
+
func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
flags javaBuilderFlags) android.Paths {
@@ -99,6 +124,9 @@
case ".proto":
srcJarFile := genProto(ctx, srcFile, flags)
outSrcFiles = append(outSrcFiles, srcJarFile)
+ case ".sysprop":
+ srcJarFile := genSysprop(ctx, srcFile)
+ outSrcFiles = append(outSrcFiles, srcJarFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}
diff --git a/java/java.go b/java/java.go
index e5218bb..f651884 100644
--- a/java/java.go
+++ b/java/java.go
@@ -309,6 +309,9 @@
// list of extra progurad flag files
extraProguardFlagFiles android.Paths
+ // manifest file to use instead of properties.Manifest
+ overrideManifest android.OptionalPath
+
// list of SDK lib names that this java moudule is exporting
exportedSdkLibs []string
@@ -368,16 +371,17 @@
}
var (
- staticLibTag = dependencyTag{name: "staticlib"}
- libTag = dependencyTag{name: "javalib"}
- annoTag = dependencyTag{name: "annotation processor"}
- bootClasspathTag = dependencyTag{name: "bootclasspath"}
- systemModulesTag = dependencyTag{name: "system modules"}
- frameworkResTag = dependencyTag{name: "framework-res"}
- frameworkApkTag = dependencyTag{name: "framework-apk"}
- kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
- proguardRaiseTag = dependencyTag{name: "proguard-raise"}
- certificateTag = dependencyTag{name: "certificate"}
+ staticLibTag = dependencyTag{name: "staticlib"}
+ libTag = dependencyTag{name: "javalib"}
+ annoTag = dependencyTag{name: "annotation processor"}
+ bootClasspathTag = dependencyTag{name: "bootclasspath"}
+ systemModulesTag = dependencyTag{name: "system modules"}
+ frameworkResTag = dependencyTag{name: "framework-res"}
+ frameworkApkTag = dependencyTag{name: "framework-apk"}
+ kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
+ proguardRaiseTag = dependencyTag{name: "proguard-raise"}
+ certificateTag = dependencyTag{name: "certificate"}
+ instrumentationForTag = dependencyTag{name: "instrumentation_for"}
)
type sdkDep struct {
@@ -721,27 +725,34 @@
javaPlatform
)
-func getLinkType(m *Module, name string) linkType {
+func getLinkType(m *Module, name string) (ret linkType, stubs bool) {
ver := m.sdkVersion()
- noStdLibs := Bool(m.properties.No_standard_libs)
switch {
- case name == "core.current.stubs" || ver == "core_current" ||
- name == "core.platform.api.stubs" || ver == "core_platform_current" ||
- noStdLibs || name == "stub-annotations" || name == "private-stub-annotations-jar":
- return javaCore
- case name == "android_system_stubs_current" || strings.HasPrefix(ver, "system_"):
- return javaSystem
- case name == "android_test_stubs_current" || strings.HasPrefix(ver, "test_"):
- return javaPlatform
- case name == "android_stubs_current" || ver == "current":
- return javaSdk
+ case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
+ name == "stub-annotations" || name == "private-stub-annotations-jar" ||
+ name == "core-lambda-stubs":
+ return javaCore, true
+ case ver == "core_current" || ver == "core_platform_current":
+ return javaCore, false
+ case name == "android_system_stubs_current":
+ return javaSystem, true
+ case strings.HasPrefix(ver, "system_"):
+ return javaSystem, false
+ case name == "android_test_stubs_current":
+ return javaSystem, true
+ case strings.HasPrefix(ver, "test_"):
+ return javaPlatform, false
+ case name == "android_stubs_current":
+ return javaSdk, true
+ case ver == "current":
+ return javaSdk, false
case ver == "":
- return javaPlatform
+ return javaPlatform, false
default:
if _, err := strconv.Atoi(ver); err != nil {
panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
}
- return javaSdk
+ return javaSdk, false
}
}
@@ -750,8 +761,11 @@
return
}
- myLinkType := getLinkType(from, ctx.ModuleName())
- otherLinkType := getLinkType(&to.Module, ctx.OtherModuleName(to))
+ myLinkType, stubs := getLinkType(from, ctx.ModuleName())
+ if stubs {
+ return
+ }
+ otherLinkType, _ := getLinkType(&to.Module, ctx.OtherModuleName(to))
commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."
switch myLinkType {
@@ -817,7 +831,7 @@
switch tag {
case bootClasspathTag:
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
- case libTag:
+ case libTag, instrumentationForTag:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
// sdk lib names from dependencies are re-exported
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
@@ -856,7 +870,8 @@
case SdkLibraryDependency:
switch tag {
case libTag:
- deps.classpath = append(deps.classpath, dep.HeaderJars(getLinkType(j, ctx.ModuleName()))...)
+ linkType, _ := getLinkType(j, ctx.ModuleName())
+ deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
// names of sdk libs that are directly depended are exported
j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
default:
@@ -1193,8 +1208,8 @@
jars = append(jars, deps.staticJars...)
jars = append(jars, deps.staticResourceJars...)
- var manifest android.OptionalPath
- if j.properties.Manifest != nil {
+ manifest := j.overrideManifest
+ if !manifest.Valid() && j.properties.Manifest != nil {
manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest"))
}
@@ -1536,6 +1551,9 @@
type binaryProperties struct {
// installable script to execute the resulting jar
Wrapper *string
+
+ // Name of the class containing main to be inserted into the manifest as Main-Class.
+ Main_class *string
}
type Binary struct {
@@ -1556,6 +1574,15 @@
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if ctx.Arch().ArchType == android.Common {
// Compile the jar
+ if j.binaryProperties.Main_class != nil {
+ if j.properties.Manifest != nil {
+ ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
+ }
+ manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
+ GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
+ j.overrideManifest = android.OptionalPathForPath(manifestFile)
+ }
+
j.Library.GenerateAndroidBuildActions(ctx)
} else {
// Handle the binary wrapper
diff --git a/java/java_test.go b/java/java_test.go
index 76244f0..86349fe 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -111,19 +111,14 @@
ctx.Register()
extraModules := []string{
- "core-oj",
- "core-libart",
"core-lambda-stubs",
- "core-simple",
- "bouncycastle",
- "conscrypt",
- "okhttp",
"framework",
"ext",
"android_stubs_current",
"android_system_stubs_current",
"android_test_stubs_current",
"core.current.stubs",
+ "core.platform.api.stubs",
"kotlin-stdlib",
}
@@ -134,7 +129,7 @@
srcs: ["a.java"],
no_standard_libs: true,
sdk_version: "core_current",
- system_modules: "core-system-modules",
+ system_modules: "core-platform-api-stubs-system-modules",
}
`, extra)
}
@@ -148,6 +143,7 @@
systemModules := []string{
"core-system-modules",
+ "core-platform-api-stubs-system-modules",
"android_stubs_current_system_modules",
"android_system_stubs_current_system_modules",
"android_test_stubs_current_system_modules",
@@ -367,15 +363,15 @@
}{
{
name: "default",
- bootclasspath: []string{"core-oj", "core-libart", "core-simple", "bouncycastle", "conscrypt", "okhttp"},
- system: "core-system-modules",
+ bootclasspath: []string{"core.platform.api.stubs", "core-lambda-stubs"},
+ system: "core-platform-api-stubs-system-modules",
classpath: []string{"ext", "framework"},
},
{
name: "blank sdk version",
properties: `sdk_version: "",`,
- bootclasspath: []string{"core-oj", "core-libart", "core-simple", "bouncycastle", "conscrypt", "okhttp"},
- system: "core-system-modules",
+ bootclasspath: []string{"core.platform.api.stubs", "core-lambda-stubs"},
+ system: "core-platform-api-stubs-system-modules",
classpath: []string{"ext", "framework"},
},
{
@@ -433,8 +429,8 @@
{
name: "nostdlib system_modules",
- properties: `no_standard_libs: true, system_modules: "core-system-modules"`,
- system: "core-system-modules",
+ properties: `no_standard_libs: true, system_modules: "core-platform-api-stubs-system-modules"`,
+ system: "core-platform-api-stubs-system-modules",
bootclasspath: []string{`""`},
classpath: []string{},
},
diff --git a/python/scripts/stub_template_host.txt b/python/scripts/stub_template_host.txt
index e686211..213401d 100644
--- a/python/scripts/stub_template_host.txt
+++ b/python/scripts/stub_template_host.txt
@@ -41,6 +41,7 @@
args = sys.argv[1:]
new_env = {}
+ runfiles_path = None
try:
runfiles_path = ExtractRunfiles()
@@ -82,7 +83,8 @@
except:
raise
finally:
- shutil.rmtree(runfiles_path, True)
+ if runfiles_path is not None:
+ shutil.rmtree(runfiles_path, True)
if __name__ == '__main__':
Main()
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 7f6e2c9..0143d1e 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -34,11 +34,6 @@
SOONG_NDK_OUT=${OUT_DIR}/soong/ndk
rm -rf ${SOONG_OUT}
mkdir -p ${SOONG_OUT}
-cat > ${SOONG_OUT}/soong.config << EOF
-{
- "Ndk_abis": true
-}
-EOF
# We only really need to set some of these variables, but soong won't merge this
# with the defaults, so we need to write out all the defaults with our values
@@ -63,7 +58,9 @@
],
"HostArch": "x86_64",
"Malloc_not_svelte": false,
- "Safestack": false
+ "Safestack": false,
+
+ "Ndk_abis": true
}
EOF
m --skip-make ${SOONG_OUT}/ndk.timestamp
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index 80a398b..07925df 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -56,9 +56,14 @@
parser.add_argument('--library', dest='library', action='store_true',
help='manifest is for a static library')
parser.add_argument('--uses-library', dest='uses_libraries', action='append',
- help='specify additional <uses-library> tag to add')
+ help='specify additional <uses-library> tag to add. android:requred is set to true')
+ parser.add_argument('--optional-uses-library', dest='optional_uses_libraries', action='append',
+ help='specify additional <uses-library> tag to add. android:requred is set to false')
parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true',
help='manifest is for a package built against the platform')
+ parser.add_argument('--prefer-integrity', type=bool, dest='prefer_integrity',
+ help=('specify if the app prefers strict integrity. Should not be conflict if ' +
+ 'already declared in the manifest.'))
parser.add_argument('input', help='input AndroidManifest.xml file')
parser.add_argument('output', help='output AndroidManifest.xml file')
return parser.parse_args()
@@ -190,12 +195,13 @@
element.setAttributeNode(target_attr)
-def add_uses_libraries(doc, new_uses_libraries):
- """Add additional <uses-library> tags with android:required=true.
+def add_uses_libraries(doc, new_uses_libraries, required):
+ """Add additional <uses-library> tags
Args:
doc: The XML document. May be modified by this function.
new_uses_libraries: The names of libraries to be added by this function.
+ required: The value of android:required attribute. Can be true or false.
Raises:
RuntimeError: Invalid manifest
"""
@@ -227,7 +233,7 @@
ul = doc.createElement('uses-library')
ul.setAttributeNS(android_ns, 'android:name', name)
- ul.setAttributeNS(android_ns, 'android:required', 'true')
+ ul.setAttributeNS(android_ns, 'android:required', str(required).lower())
application.insertBefore(doc.createTextNode(indent), last)
application.insertBefore(ul, last)
@@ -266,6 +272,28 @@
application.setAttributeNode(attr)
+def add_prefer_integrity(doc):
+ manifest = parse_manifest(doc)
+ elems = get_children_with_tag(manifest, 'application')
+ application = elems[0] if len(elems) == 1 else None
+ if len(elems) > 1:
+ raise RuntimeError('found multiple <application> tags')
+ elif not elems:
+ application = doc.createElement('application')
+ indent = get_indent(manifest.firstChild, 1)
+ first = manifest.firstChild
+ manifest.insertBefore(doc.createTextNode(indent), first)
+ manifest.insertBefore(application, first)
+
+ attr = application.getAttributeNodeNS(android_ns, 'preferIntegrity')
+ if attr is None:
+ attr = doc.createAttributeNS(android_ns, 'android:preferIntegrity')
+ attr.value = 'true'
+ application.setAttributeNode(attr)
+ elif attr.value != 'true':
+ raise RuntimeError('existing attribute mismatches the option of --prefer-integrity')
+
+
def write_xml(f, doc):
f.write('<?xml version="1.0" encoding="utf-8"?>\n')
for node in doc.childNodes:
@@ -285,11 +313,17 @@
raise_min_sdk_version(doc, args.min_sdk_version, args.target_sdk_version, args.library)
if args.uses_libraries:
- add_uses_libraries(doc, args.uses_libraries)
+ add_uses_libraries(doc, args.uses_libraries, True)
+
+ if args.optional_uses_libraries:
+ add_uses_libraries(doc, args.optional_uses_libraries, False)
if args.uses_non_sdk_api:
add_uses_non_sdk_api(doc)
+ if args.prefer_integrity:
+ add_prefer_integrity(doc)
+
with open(args.output, 'wb') as f:
write_xml(f, doc)
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index d1d401a..a621445 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -346,5 +346,40 @@
self.assertEqual(output, expected)
+class PreferIntegrityTest(unittest.TestCase):
+ """Unit tests for add_prefer_integrity function."""
+
+ def run_test(self, input_manifest):
+ doc = minidom.parseString(input_manifest)
+ manifest_fixer.add_prefer_integrity(doc)
+ output = StringIO.StringIO()
+ manifest_fixer.write_xml(output, doc)
+ return output.getvalue()
+
+ manifest_tmpl = (
+ '<?xml version="1.0" encoding="utf-8"?>\n'
+ '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
+ ' <application%s/>\n'
+ '</manifest>\n')
+
+ def prefer_integrity(self, value):
+ return ' android:preferIntegrity="%s"' % value
+
+ def test_manifest_with_undeclared_preference(self):
+ manifest_input = self.manifest_tmpl % ''
+ expected = self.manifest_tmpl % self.prefer_integrity('true')
+ output = self.run_test(manifest_input)
+ self.assertEqual(output, expected)
+
+ def test_manifest_with_prefer_integrity(self):
+ manifest_input = self.manifest_tmpl % self.prefer_integrity('true')
+ expected = manifest_input
+ output = self.run_test(manifest_input)
+ self.assertEqual(output, expected)
+
+ def test_manifest_with_not_prefer_integrity(self):
+ manifest_input = self.manifest_tmpl % self.prefer_integrity('false')
+ self.assertRaises(RuntimeError, self.run_test, manifest_input)
+
if __name__ == '__main__':
unittest.main()
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 29594dc..4634c18 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -98,6 +98,7 @@
else
"${CROSS_COMPILE}objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
fi
+ rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
else
cp -f "${infile}" "${outfile}.tmp"
fi
diff --git a/cmd/symbol_inject/Android.bp b/symbol_inject/Android.bp
similarity index 90%
rename from cmd/symbol_inject/Android.bp
rename to symbol_inject/Android.bp
index a2ea12b..8308043 100644
--- a/cmd/symbol_inject/Android.bp
+++ b/symbol_inject/Android.bp
@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-blueprint_go_binary {
- name: "symbol_inject",
+bootstrap_go_package {
+ name: "soong-symbol_inject",
+ pkgPath: "android/soong/symbol_inject",
srcs: [
"symbol_inject.go",
"elf.go",
diff --git a/cmd/symbol_inject/Android.bp b/symbol_inject/cmd/Android.bp
similarity index 71%
copy from cmd/symbol_inject/Android.bp
copy to symbol_inject/cmd/Android.bp
index a2ea12b..ee2f259 100644
--- a/cmd/symbol_inject/Android.bp
+++ b/symbol_inject/cmd/Android.bp
@@ -14,19 +14,8 @@
blueprint_go_binary {
name: "symbol_inject",
+ deps: ["soong-symbol_inject"],
srcs: [
"symbol_inject.go",
- "elf.go",
- "macho.go",
- "pe.go",
- ],
- testSrcs: [
- "elf_symboldata_test.go",
- "elf_test.go",
- "macho_symboldata_test.go",
- "macho_test.go",
- "pe_symboldata_test.go",
- "pe_test.go",
- "symbol_inject_test.go",
],
}
diff --git a/symbol_inject/cmd/symbol_inject.go b/symbol_inject/cmd/symbol_inject.go
new file mode 100644
index 0000000..1397b37
--- /dev/null
+++ b/symbol_inject/cmd/symbol_inject.go
@@ -0,0 +1,97 @@
+// Copyright 2018 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 main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+
+ "android/soong/symbol_inject"
+)
+
+var (
+ input = flag.String("i", "", "input file")
+ output = flag.String("o", "", "output file")
+ symbol = flag.String("s", "", "symbol to inject into")
+ from = flag.String("from", "", "optional existing value of the symbol for verification")
+ value = flag.String("v", "", "value to inject into symbol")
+
+ dump = flag.Bool("dump", false, "dump the symbol table for copying into a test")
+)
+
+func main() {
+ flag.Parse()
+
+ usageError := func(s string) {
+ fmt.Fprintln(os.Stderr, s)
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ if *input == "" {
+ usageError("-i is required")
+ }
+
+ if !*dump {
+ if *output == "" {
+ usageError("-o is required")
+ }
+
+ if *symbol == "" {
+ usageError("-s is required")
+ }
+
+ if *value == "" {
+ usageError("-v is required")
+ }
+ }
+
+ r, err := os.Open(*input)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(2)
+ }
+ defer r.Close()
+
+ if *dump {
+ err := symbol_inject.DumpSymbols(r)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(6)
+ }
+ return
+ }
+
+ w, err := os.OpenFile(*output, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(3)
+ }
+ defer w.Close()
+
+ file, err := symbol_inject.OpenFile(r)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(4)
+ }
+
+ err = symbol_inject.InjectStringSymbol(file, w, *symbol, *value, *from)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Remove(*output)
+ os.Exit(5)
+ }
+}
diff --git a/cmd/symbol_inject/elf.go b/symbol_inject/elf.go
similarity index 99%
rename from cmd/symbol_inject/elf.go
rename to symbol_inject/elf.go
index d94877d..8742cbd 100644
--- a/cmd/symbol_inject/elf.go
+++ b/symbol_inject/elf.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/elf"
diff --git a/cmd/symbol_inject/elf_symboldata_test.go b/symbol_inject/elf_symboldata_test.go
similarity index 99%
rename from cmd/symbol_inject/elf_symboldata_test.go
rename to symbol_inject/elf_symboldata_test.go
index 9ba7153..b2f1148 100644
--- a/cmd/symbol_inject/elf_symboldata_test.go
+++ b/symbol_inject/elf_symboldata_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import "debug/elf"
diff --git a/cmd/symbol_inject/elf_test.go b/symbol_inject/elf_test.go
similarity index 98%
rename from cmd/symbol_inject/elf_test.go
rename to symbol_inject/elf_test.go
index 30b46a5..aceee44 100644
--- a/cmd/symbol_inject/elf_test.go
+++ b/symbol_inject/elf_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"strconv"
diff --git a/cmd/symbol_inject/macho.go b/symbol_inject/macho.go
similarity index 98%
rename from cmd/symbol_inject/macho.go
rename to symbol_inject/macho.go
index be49f8b..6ee3f4f 100644
--- a/cmd/symbol_inject/macho.go
+++ b/symbol_inject/macho.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/macho"
diff --git a/cmd/symbol_inject/macho_symboldata_test.go b/symbol_inject/macho_symboldata_test.go
similarity index 99%
rename from cmd/symbol_inject/macho_symboldata_test.go
rename to symbol_inject/macho_symboldata_test.go
index 3100a81..7336a27 100644
--- a/cmd/symbol_inject/macho_symboldata_test.go
+++ b/symbol_inject/macho_symboldata_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/macho"
diff --git a/cmd/symbol_inject/macho_test.go b/symbol_inject/macho_test.go
similarity index 98%
rename from cmd/symbol_inject/macho_test.go
rename to symbol_inject/macho_test.go
index 7acab23..50df131 100644
--- a/cmd/symbol_inject/macho_test.go
+++ b/symbol_inject/macho_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/macho"
diff --git a/cmd/symbol_inject/pe.go b/symbol_inject/pe.go
similarity index 98%
rename from cmd/symbol_inject/pe.go
rename to symbol_inject/pe.go
index 12f35ee..58cf91a 100644
--- a/cmd/symbol_inject/pe.go
+++ b/symbol_inject/pe.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/pe"
diff --git a/cmd/symbol_inject/pe_symboldata_test.go b/symbol_inject/pe_symboldata_test.go
similarity index 99%
rename from cmd/symbol_inject/pe_symboldata_test.go
rename to symbol_inject/pe_symboldata_test.go
index edc1c97..5c0fd70 100644
--- a/cmd/symbol_inject/pe_symboldata_test.go
+++ b/symbol_inject/pe_symboldata_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/pe"
diff --git a/cmd/symbol_inject/pe_test.go b/symbol_inject/pe_test.go
similarity index 99%
rename from cmd/symbol_inject/pe_test.go
rename to symbol_inject/pe_test.go
index 21a0bc4..df7bac3 100644
--- a/cmd/symbol_inject/pe_test.go
+++ b/symbol_inject/pe_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/pe"
diff --git a/cmd/symbol_inject/symbol_inject.go b/symbol_inject/symbol_inject.go
similarity index 70%
rename from cmd/symbol_inject/symbol_inject.go
rename to symbol_inject/symbol_inject.go
index d0f01c5..2a3d67e 100644
--- a/cmd/symbol_inject/symbol_inject.go
+++ b/symbol_inject/symbol_inject.go
@@ -12,25 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"bytes"
- "flag"
+ "encoding/binary"
"fmt"
"io"
"math"
- "os"
-)
-
-var (
- input = flag.String("i", "", "input file")
- output = flag.String("o", "", "output file")
- symbol = flag.String("s", "", "symbol to inject into")
- from = flag.String("from", "", "optional existing value of the symbol for verification")
- value = flag.String("v", "", "value to inject into symbol")
-
- dump = flag.Bool("dump", false, "dump the symbol table for copying into a test")
)
var maxUint64 uint64 = math.MaxUint64
@@ -39,71 +28,7 @@
error
}
-func main() {
- flag.Parse()
-
- usageError := func(s string) {
- fmt.Fprintln(os.Stderr, s)
- flag.Usage()
- os.Exit(1)
- }
-
- if *input == "" {
- usageError("-i is required")
- }
-
- if !*dump {
- if *output == "" {
- usageError("-o is required")
- }
-
- if *symbol == "" {
- usageError("-s is required")
- }
-
- if *value == "" {
- usageError("-v is required")
- }
- }
-
- r, err := os.Open(*input)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(2)
- }
- defer r.Close()
-
- if *dump {
- err := dumpSymbols(r)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(6)
- }
- return
- }
-
- w, err := os.OpenFile(*output, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(3)
- }
- defer w.Close()
-
- file, err := openFile(r)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(4)
- }
-
- err = injectSymbol(file, w, *symbol, *value, *from)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Remove(*output)
- os.Exit(5)
- }
-}
-
-func openFile(r io.ReaderAt) (*File, error) {
+func OpenFile(r io.ReaderAt) (*File, error) {
file, err := elfSymbolsFromFile(r)
if elfError, ok := err.(cantParseError); ok {
// Try as a mach-o file
@@ -126,7 +51,7 @@
return file, err
}
-func injectSymbol(file *File, w io.Writer, symbol, value, from string) error {
+func InjectStringSymbol(file *File, w io.Writer, symbol, value, from string) error {
offset, size, err := findSymbol(file, symbol)
if err != nil {
return err
@@ -151,13 +76,29 @@
}
}
- return copyAndInject(file.r, w, offset, size, value)
-}
-
-func copyAndInject(r io.ReaderAt, w io.Writer, offset, size uint64, value string) (err error) {
buf := make([]byte, size)
copy(buf, value)
+ return copyAndInject(file.r, w, offset, buf)
+}
+
+func InjectUint64Symbol(file *File, w io.Writer, symbol string, value uint64) error {
+ offset, size, err := findSymbol(file, symbol)
+ if err != nil {
+ return err
+ }
+
+ if size != 8 {
+ return fmt.Errorf("symbol %q is not a uint64, it is %d bytes long", symbol, size)
+ }
+
+ buf := make([]byte, 8)
+ binary.LittleEndian.PutUint64(buf, value)
+
+ return copyAndInject(file.r, w, offset, buf)
+}
+
+func copyAndInject(r io.ReaderAt, w io.Writer, offset uint64, buf []byte) (err error) {
// Copy the first bytes up to the symbol offset
_, err = io.Copy(w, io.NewSectionReader(r, 0, int64(offset)))
@@ -167,7 +108,7 @@
}
// Write the remainder of the file
- pos := int64(offset + size)
+ pos := int64(offset) + int64(len(buf))
if err == nil {
_, err = io.Copy(w, io.NewSectionReader(r, pos, 1<<63-1-pos))
}
@@ -239,7 +180,7 @@
Size uint64
}
-func dumpSymbols(r io.ReaderAt) error {
+func DumpSymbols(r io.ReaderAt) error {
err := dumpElfSymbols(r)
if elfError, ok := err.(cantParseError); ok {
// Try as a mach-o file
diff --git a/cmd/symbol_inject/symbol_inject_test.go b/symbol_inject/symbol_inject_test.go
similarity index 77%
rename from cmd/symbol_inject/symbol_inject_test.go
rename to symbol_inject/symbol_inject_test.go
index dbee39a..6607e65 100644
--- a/cmd/symbol_inject/symbol_inject_test.go
+++ b/symbol_inject/symbol_inject_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"bytes"
@@ -23,32 +23,23 @@
func TestCopyAndInject(t *testing.T) {
s := "abcdefghijklmnopqrstuvwxyz"
testCases := []struct {
- offset, size uint64
- value string
- expected string
+ offset uint64
+ buf string
+ expected string
}{
{
offset: 0,
- size: 1,
- value: "A",
+ buf: "A",
expected: "Abcdefghijklmnopqrstuvwxyz",
},
{
offset: 1,
- size: 1,
- value: "B",
- expected: "aBcdefghijklmnopqrstuvwxyz",
- },
- {
- offset: 1,
- size: 1,
- value: "BCD",
+ buf: "B",
expected: "aBcdefghijklmnopqrstuvwxyz",
},
{
offset: 25,
- size: 1,
- value: "Z",
+ buf: "Z",
expected: "abcdefghijklmnopqrstuvwxyZ",
},
}
@@ -57,7 +48,7 @@
t.Run(strconv.Itoa(i), func(t *testing.T) {
in := bytes.NewReader([]byte(s))
out := &bytes.Buffer{}
- copyAndInject(in, out, testCase.offset, testCase.size, testCase.value)
+ copyAndInject(in, out, testCase.offset, []byte(testCase.buf))
if out.String() != testCase.expected {
t.Errorf("expected %s, got %s", testCase.expected, out.String())
diff --git a/ui/build/build.go b/ui/build/build.go
index 377481b..c902a0f 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -40,9 +40,10 @@
pool local_pool
depth = {{.Parallel}}
build _kati_always_build_: phony
-{{if .HasKatiSuffix}}include {{.KatiBuildNinjaFile}}
+{{if .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
+subninja {{.KatiPackageNinjaFile}}
{{end -}}
-include {{.SoongNinjaFile}}
+subninja {{.SoongNinjaFile}}
`))
func createCombinedBuildNinjaFile(ctx Context, config Config) {
@@ -180,6 +181,7 @@
genKatiSuffix(ctx, config)
runKatiCleanSpec(ctx, config)
runKatiBuild(ctx, config)
+ runKatiPackage(ctx, config)
ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0777)
} else {
diff --git a/ui/build/config.go b/ui/build/config.go
index d470b96..840f505 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -34,6 +34,7 @@
arguments []string
goma bool
environ *Environment
+ distDir string
// From the arguments
parallel int
@@ -86,6 +87,12 @@
ret.environ.Set("OUT_DIR", outDir)
}
+ if distDir, ok := ret.environ.Get("DIST_DIR"); ok {
+ ret.distDir = filepath.Clean(distDir)
+ } else {
+ ret.distDir = filepath.Join(ret.OutDir(), "dist")
+ }
+
ret.environ.Unset(
// We're already using it
"USE_SOONG_UI",
@@ -107,6 +114,9 @@
// We handle this above
"OUT_DIR_COMMON_BASE",
+ // This is handled above too, and set for individual commands later
+ "DIST_DIR",
+
// Variables that have caused problems in the past
"CDPATH",
"DISPLAY",
@@ -248,10 +258,10 @@
}
} else if k, v, ok := decodeKeyValue(arg); ok && len(k) > 0 {
c.environ.Set(k, v)
+ } else if arg == "dist" {
+ c.dist = true
} else {
- if arg == "dist" {
- c.dist = true
- } else if arg == "checkbuild" {
+ if arg == "checkbuild" {
c.checkbuild = true
}
c.arguments = append(c.arguments, arg)
@@ -375,10 +385,7 @@
}
func (c *configImpl) DistDir() string {
- if distDir, ok := c.environ.Get("DIST_DIR"); ok {
- return filepath.Clean(distDir)
- }
- return filepath.Join(c.OutDir(), "dist")
+ return c.distDir
}
func (c *configImpl) NinjaArgs() []string {
@@ -505,6 +512,10 @@
return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiBuildSuffix+".ninja")
}
+func (c *configImpl) KatiPackageNinjaFile() string {
+ return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiPackageSuffix+".ninja")
+}
+
func (c *configImpl) SoongNinjaFile() string {
return filepath.Join(c.SoongOutDir(), "build.ninja")
}
@@ -532,6 +543,10 @@
return filepath.Join(c.ProductOut(), "previous_build_config.mk")
}
+func (c *configImpl) KatiPackageMkDir() string {
+ return filepath.Join(c.ProductOut(), "obj", "CONFIG", "kati_packaging")
+}
+
func (c *configImpl) hostOutRoot() string {
return filepath.Join(c.OutDir(), "host")
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index ffea841..ad57d02 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -32,8 +32,40 @@
//
// vars is the list of variables to read. The values will be put in the
// returned map.
+//
+// variables controlled by soong_ui directly are now returned without needing
+// to call into make, to retain compatibility.
func DumpMakeVars(ctx Context, config Config, goals, vars []string) (map[string]string, error) {
- return dumpMakeVars(ctx, config, goals, vars, false)
+ soongUiVars := map[string]func() string{
+ "OUT_DIR": func() string { return config.OutDir() },
+ "DIST_DIR": func() string { return config.DistDir() },
+ }
+
+ makeVars := make([]string, 0, len(vars))
+ for _, v := range vars {
+ if _, ok := soongUiVars[v]; !ok {
+ makeVars = append(makeVars, v)
+ }
+ }
+
+ var ret map[string]string
+ if len(makeVars) > 0 {
+ var err error
+ ret, err = dumpMakeVars(ctx, config, goals, makeVars, false)
+ if err != nil {
+ return ret, err
+ }
+ } else {
+ ret = make(map[string]string)
+ }
+
+ for _, v := range vars {
+ if f, ok := soongUiVars[v]; ok {
+ ret[v] = f()
+ }
+ }
+
+ return ret, nil
}
func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
@@ -48,7 +80,6 @@
"dump-many-vars",
"MAKECMDGOALS="+strings.Join(goals, " "))
cmd.Environment.Set("CALLED_FROM_SETUP", "true")
- cmd.Environment.Set("BUILD_SYSTEM", "build/make/core")
if write_soong_vars {
cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
}
diff --git a/ui/build/environment.go b/ui/build/environment.go
index cbeeb4b..d8ff7f2 100644
--- a/ui/build/environment.go
+++ b/ui/build/environment.go
@@ -75,6 +75,17 @@
*e = out
}
+// Allow removes all keys that are not present in the input list
+func (e *Environment) Allow(keys ...string) {
+ out := (*e)[:0]
+ for _, env := range *e {
+ if key, _, ok := decodeKeyValue(env); ok && inList(key, keys) {
+ out = append(out, env)
+ }
+ }
+ *e = out
+}
+
// Environ returns the []string required for exec.Cmd.Env
func (e *Environment) Environ() []string {
return []string(*e)
diff --git a/ui/build/environment_test.go b/ui/build/environment_test.go
index 0294dac..37f500f 100644
--- a/ui/build/environment_test.go
+++ b/ui/build/environment_test.go
@@ -56,6 +56,15 @@
}
}
+func TestEnvAllow(t *testing.T) {
+ initial := &Environment{"TEST=1", "TEST2=0", "TEST3=2"}
+ initial.Allow("TEST3", "TEST")
+ got := initial.Environ()
+ if len(got) != 2 || got[0] != "TEST=1" || got[1] != "TEST3=2" {
+ t.Errorf("Expected [TEST=1 TEST3=2], got: %v", got)
+ }
+}
+
const testKatiEnvFileContents = `#!/bin/sh
# Generated by kati unknown
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 546fd1a..56e9a88 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -28,6 +28,7 @@
const katiBuildSuffix = ""
const katiCleanspecSuffix = "-cleanspec"
+const katiPackageSuffix = "-package"
// genKatiSuffix creates a suffix for kati-generated files so that we can cache
// them based on their inputs. So this should encode all common changes to Kati
@@ -59,7 +60,7 @@
}
}
-func runKati(ctx Context, config Config, extraSuffix string, args []string) {
+func runKati(ctx Context, config Config, extraSuffix string, args []string, envFunc func(*Environment)) {
executable := config.PrebuiltBuildTool("ckati")
args = append([]string{
"--ninja",
@@ -80,10 +81,6 @@
"--kati_stats",
}, args...)
- args = append(args,
- "SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
- "TARGET_DEVICE_DIR="+config.TargetDeviceDir())
-
cmd := Command(ctx, config, "ckati", executable, args...)
cmd.Sandbox = katiSandbox
pipe, err := cmd.StdoutPipe()
@@ -92,6 +89,8 @@
}
cmd.Stderr = cmd.Stdout
+ envFunc(cmd.Environment)
+
cmd.StartOrFatal()
status.KatiReader(ctx.Status.StartTool(), pipe)
cmd.WaitOrFatal()
@@ -103,7 +102,6 @@
args := []string{
"--writable", config.OutDir() + "/",
- "--writable", config.DistDir() + "/",
"-f", "build/make/core/main.mk",
}
@@ -125,9 +123,54 @@
args = append(args, config.KatiArgs()...)
- args = append(args, "SOONG_ANDROID_MK="+config.SoongAndroidMk())
+ args = append(args,
+ "SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
+ "SOONG_ANDROID_MK="+config.SoongAndroidMk(),
+ "TARGET_DEVICE_DIR="+config.TargetDeviceDir(),
+ "KATI_PACKAGE_MK_DIR="+config.KatiPackageMkDir())
- runKati(ctx, config, katiBuildSuffix, args)
+ runKati(ctx, config, katiBuildSuffix, args, func(env *Environment) {})
+}
+
+func runKatiPackage(ctx Context, config Config) {
+ ctx.BeginTrace("kati package")
+ defer ctx.EndTrace()
+
+ args := []string{
+ "--writable", config.DistDir() + "/",
+ "--werror_writable",
+ "--werror_implicit_rules",
+ "--werror_overriding_commands",
+ "--werror_real_to_phony",
+ "--werror_phony_looks_real",
+ "-f", "build/make/packaging/main.mk",
+ "KATI_PACKAGE_MK_DIR=" + config.KatiPackageMkDir(),
+ }
+
+ runKati(ctx, config, katiPackageSuffix, args, func(env *Environment) {
+ env.Allow([]string{
+ // Some generic basics
+ "LANG",
+ "LC_MESSAGES",
+ "PATH",
+ "PWD",
+ "TMPDIR",
+
+ // Tool configs
+ "JAVA_HOME",
+ "PYTHONDONTWRITEBYTECODE",
+
+ // Build configuration
+ "ANDROID_BUILD_SHELL",
+ "DIST_DIR",
+ "OUT_DIR",
+ }...)
+
+ if config.Dist() {
+ env.Set("DIST", "true")
+ env.Set("DIST_DIR", config.DistDir())
+ }
+ })
}
func runKatiCleanSpec(ctx Context, config Config) {
@@ -138,5 +181,7 @@
"--werror_implicit_rules",
"--werror_overriding_commands",
"-f", "build/make/core/cleanbuild.mk",
- })
+ "SOONG_MAKEVARS_MK=" + config.SoongMakeVarsMk(),
+ "TARGET_DEVICE_DIR=" + config.TargetDeviceDir(),
+ }, func(env *Environment) {})
}
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 91cb475..c8f19d1 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -60,6 +60,8 @@
cmd.Environment.AppendFromKati(config.KatiEnvFile())
}
+ cmd.Environment.Set("DIST_DIR", config.DistDir())
+
// Allow both NINJA_ARGS and NINJA_EXTRA_ARGS, since both have been
// used in the past to specify extra ninja arguments.
if extra, ok := cmd.Environment.Get("NINJA_ARGS"); ok {
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 6851e8c..c4fcc20 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -41,8 +41,8 @@
var Log = PathConfig{
Symlink: true,
- Log: true,
- Error: false,
+ Log: true,
+ Error: false,
}
// The configuration used if the tool is not listed in the config below.
@@ -101,7 +101,6 @@
"ls": Allowed,
"lsof": Allowed,
"m4": Allowed,
- "make": Log,
"md5sum": Allowed,
"mkdir": Allowed,
"mktemp": Allowed,
@@ -110,7 +109,6 @@
"openssl": Allowed,
"paste": Allowed,
"patch": Allowed,
- "perl": Log,
"pgrep": Allowed,
"pkill": Allowed,
"ps": Allowed,
@@ -149,7 +147,6 @@
"which": Allowed,
"whoami": Allowed,
"xargs": Allowed,
- "xmllint": Log,
"xxd": Allowed,
"xz": Allowed,
"zip": Allowed,
diff --git a/ui/status/kati.go b/ui/status/kati.go
index 552a9e9..7c26d42 100644
--- a/ui/status/kati.go
+++ b/ui/status/kati.go
@@ -24,7 +24,7 @@
)
var katiError = regexp.MustCompile(`^(\033\[1m)?[^ ]+:[0-9]+: (\033\[31m)?error:`)
-var katiIncludeRe = regexp.MustCompile(`^(\[(\d+)/(\d+)] )?((including [^ ]+|initializing build system|finishing build rules|writing build rules) ...)$`)
+var katiIncludeRe = regexp.MustCompile(`^(\[(\d+)/(\d+)] )?((including [^ ]+|initializing (build|packaging) system|finishing (build|packaging) rules|writing (build|packaging) rules) ...)$`)
var katiLogRe = regexp.MustCompile(`^\*kati\*: `)
var katiNinjaMissing = regexp.MustCompile("^[^ ]+ is missing, regenerating...$")