summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md59
-rw-r--r--android/androidmk.go15
-rw-r--r--android/arch.go7
-rw-r--r--android/bazel.go4
-rw-r--r--android/makevars.go94
-rw-r--r--android/module.go147
-rw-r--r--bazel/configurability.go2
-rw-r--r--cc/config/Android.bp2
-rw-r--r--cc/config/darwin_host.go (renamed from cc/config/x86_darwin_host.go)55
-rw-r--r--java/bootclasspath_fragment.go2
-rw-r--r--java/robolectric.go12
-rw-r--r--java/systemserver_classpath_fragment.go11
-rw-r--r--rust/binary.go13
-rw-r--r--rust/config/Android.bp2
-rw-r--r--rust/config/darwin_host.go (renamed from rust/config/x86_darwin_host.go)41
-rw-r--r--rust/rust.go15
-rw-r--r--rust/sanitize.go4
-rw-r--r--scripts/check_boot_jars/package_allowed_list.txt1
-rwxr-xr-xscripts/manifest_check.py32
-rw-r--r--ui/build/soong.go67
20 files changed, 478 insertions, 107 deletions
diff --git a/README.md b/README.md
index a67c393aa..b820fd169 100644
--- a/README.md
+++ b/README.md
@@ -561,27 +561,41 @@ written to a [ninja](http://ninja-build.org) build file.
## Developing for Soong
-To load Soong code in a Go-aware IDE, create a directory outside your android tree and then:
-```bash
-apt install bindfs
-export GOPATH=<path to the directory you created>
-build/soong/scripts/setup_go_workspace_for_soong.sh
-```
-
-This will bind mount the Soong source directories into the directory in the layout expected by
-the IDE.
-
+To load the code of Soong in IntelliJ:
+
+* File -> Open, open the `build/soong` directory. It will be opened as a new
+ project.
+* File -> Settings, then Languages & Frameworks -> Go -> GOROOT, then set it to
+ `prebuilts/go/linux-x86`
+* File -> Project Structure, then, Project Settings -> Modules, then Add
+ Content Root, then add the `build/blueprint` directory.
+* Optional: also add the `external/golang-protobuf` directory. In practice,
+ IntelliJ seems to work well enough without this, too.
### Running Soong in a debugger
-To run the soong_build process in a debugger, install `dlv` and then start the build with
-`SOONG_DELVE=<listen addr>` in the environment.
+To make `soong_build` wait for a debugger connection, install `dlv` and then
+start the build with `SOONG_DELVE=<listen addr>` in the environment.
For example:
```bash
-SOONG_DELVE=:1234 m nothing
+SOONG_DELVE=:5006 m nothing
+```
+
+To make `soong_ui` wait for a debugger connection, use the `SOONG_UI_DELVE`
+variable:
+
+```
+SOONG_UI_DELVE=:5006 m nothing
```
-and then in another terminal:
+
+
+setting or unsetting `SOONG_DELVE` causes a recompilation of `soong_build`. This
+is because in order to debug the binary, it needs to be built with debug
+symbols.
+
+To test the debugger connection, run this command:
+
```
-dlv connect :1234
+dlv connect :5006
```
If you see an error:
@@ -596,6 +610,21 @@ using:
sudo sysctl -w kernel.yama.ptrace_scope=0
```
+To connect to the process using IntelliJ:
+
+* Run -> Edit Configurations...
+* Choose "Go Remote" on the left
+* Click on the "+" buttion on the top-left
+* Give it a nice name and set "Host" to localhost and "Port" to the port in the
+ environment variable
+
+Debugging works far worse than debugging Java, but is sometimes useful.
+
+Sometimes the `dlv` process hangs on connection. A symptom of this is `dlv`
+spinning a core or two. In that case, `kill -9` `dlv` and try again.
+Anecdotally, it _feels_ like waiting a minute after the start of `soong_build`
+helps.
+
## Contact
Email android-building@googlegroups.com (external) for any questions, or see
diff --git a/android/androidmk.go b/android/androidmk.go
index f5a9f874b..b6b04a6bc 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -516,6 +516,16 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+ // If the install rule was generated by Soong tell Make about it.
+ if amod.InstallBypassMake() && len(base.katiInstalls) > 0 {
+ // Assume the primary install file is last since it probably needs to depend on any other
+ // installed files. If that is not the case we can add a method to specify the primary
+ // installed file.
+ a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to)
+ a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled())
+ a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths())
+ }
+
if am, ok := mod.(ApexModule); ok {
a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
}
@@ -911,6 +921,11 @@ func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
return true
}
+ // Only expose the primary Darwin target, as Make does not understand Darwin+Arm64
+ if module.Os() == Darwin && module.Target().HostCross {
+ return true
+ }
+
return !module.Enabled() ||
module.commonProperties.HideFromMake ||
// Make does not understand LinuxBionic
diff --git a/android/arch.go b/android/arch.go
index 5e3e9204a..3bf54b711 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -308,7 +308,7 @@ var (
// LinuxMusl is the OS for the Linux kernel plus the musl runtime.
LinuxMusl = newOsType("linux_musl", Host, false, X86, X86_64)
// Darwin is the OS for MacOS/Darwin host machines.
- Darwin = newOsType("darwin", Host, false, X86_64)
+ Darwin = newOsType("darwin", Host, false, Arm64, X86_64)
// LinuxBionic is the OS for the Linux kernel plus the Bionic libc runtime, but without the
// rest of Android.
LinuxBionic = newOsType("linux_bionic", Host, false, Arm64, X86_64)
@@ -696,6 +696,11 @@ func archMutator(bpctx blueprint.BottomUpMutatorContext) {
for i, m := range modules {
addTargetProperties(m, targets[i], multiTargets, i == 0)
m.base().setArchProperties(mctx)
+
+ // Install support doesn't understand Darwin+Arm64
+ if os == Darwin && targets[i].HostCross {
+ m.base().commonProperties.SkipInstall = true
+ }
}
}
diff --git a/android/bazel.go b/android/bazel.go
index 5dda65537..87a9d507d 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -249,8 +249,8 @@ var (
"build_tools_source_properties",
// //external/libcap/...
- "libcap", // http://b/198595332, depends on _makenames, a cc_binary
- "cap_names.h", // http://b/198596102, depends on _makenames, a cc_binary
+ "cap_names.h", // http://b/196105070 host toolchain misconfigurations for mixed builds
+ "libcap", // http://b/196105070 host toolchain misconfigurations for mixed builds
"libminijail", // depends on unconverted modules: libcap
"getcap", // depends on unconverted modules: libcap
diff --git a/android/makevars.go b/android/makevars.go
index 40c0ccded..20db65a50 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -17,6 +17,8 @@ package android
import (
"bytes"
"fmt"
+ "path/filepath"
+ "runtime"
"sort"
"strings"
@@ -222,6 +224,9 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
lateOutFile := absolutePath(PathForOutput(ctx,
"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
+ installsFile := absolutePath(PathForOutput(ctx,
+ "installs"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
+
if ctx.Failed() {
return
}
@@ -229,6 +234,8 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
var vars []makeVarsVariable
var dists []dist
var phonies []phony
+ var katiInstalls []katiInstall
+ var katiSymlinks []katiInstall
providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...)
@@ -258,6 +265,11 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
phonies = append(phonies, mctx.phonies...)
dists = append(dists, mctx.dists...)
}
+
+ if m.ExportedToMake() {
+ katiInstalls = append(katiInstalls, m.base().katiInstalls...)
+ katiSymlinks = append(katiSymlinks, m.base().katiSymlinks...)
+ }
})
if ctx.Failed() {
@@ -297,6 +309,10 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
ctx.Errorf(err.Error())
}
+ installsBytes := s.writeInstalls(katiInstalls, katiSymlinks)
+ if err := pathtools.WriteFileIfChanged(installsFile, installsBytes, 0666); err != nil {
+ ctx.Errorf(err.Error())
+ }
}
func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
@@ -405,6 +421,84 @@ func (s *makeVarsSingleton) writeLate(phonies []phony, dists []dist) []byte {
return buf.Bytes()
}
+// writeInstalls writes the list of install rules generated by Soong to a makefile. The rules
+// are exported to Make instead of written directly to the ninja file so that main.mk can add
+// the dependencies from the `required` property that are hard to resolve in Soong.
+func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []byte {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprint(buf, `# Autogenerated file
+
+# Values written by Soong to generate install rules that can be amended by Kati.
+
+
+`)
+
+ preserveSymlinksFlag := "-d"
+ if runtime.GOOS == "darwin" {
+ preserveSymlinksFlag = "-R"
+ }
+
+ for _, install := range installs {
+ // Write a rule for each install request in the form:
+ // to: from [ deps ] [ | order only deps ]
+ // cp -f -d $< $@ [ && chmod +x $@ ]
+ fmt.Fprintf(buf, "%s: %s", install.to.String(), install.from.String())
+ for _, dep := range install.implicitDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ if len(install.orderOnlyDeps) > 0 {
+ fmt.Fprintf(buf, " |")
+ }
+ for _, dep := range install.orderOnlyDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ fmt.Fprintln(buf)
+
+ fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@", preserveSymlinksFlag)
+ if install.executable {
+ fmt.Fprintf(buf, " && chmod +x $@")
+ }
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf)
+ }
+
+ for _, symlink := range symlinks {
+ fmt.Fprintf(buf, "%s:", symlink.to.String())
+ for _, dep := range symlink.implicitDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ if symlink.from != nil || len(symlink.orderOnlyDeps) > 0 {
+ fmt.Fprintf(buf, " |")
+ }
+ if symlink.from != nil {
+ fmt.Fprintf(buf, " %s", symlink.from.String())
+ }
+ for _, dep := range symlink.orderOnlyDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ fmt.Fprintln(buf)
+
+ fromStr := ""
+ if symlink.from != nil {
+ rel, err := filepath.Rel(filepath.Dir(symlink.to.String()), symlink.from.String())
+ if err != nil {
+ panic(fmt.Errorf("failed to find relative path for symlink from %q to %q: %w",
+ symlink.from.String(), symlink.to.String(), err))
+ }
+ fromStr = rel
+ } else {
+ fromStr = symlink.absFrom
+ }
+
+ fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf)
+ }
+
+ return buf.Bytes()
+}
+
func (c *makeVarsContext) DeviceConfig() DeviceConfig {
return DeviceConfig{c.Config().deviceConfig}
}
diff --git a/android/module.go b/android/module.go
index 503fff3da..3447f2b51 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1194,7 +1194,10 @@ type ModuleBase struct {
packagingSpecs []PackagingSpec
packagingSpecsDepSet *packagingSpecsDepSet
noticeFiles Paths
- phonies map[string]Paths
+ // katiInstalls tracks the install rules that were created by Soong but are being exported
+ // to Make to convert to ninja rules so that Make can add additional dependencies.
+ katiInstalls katiInstalls
+ katiSymlinks katiInstalls
// The files to copy to the dist as explicitly specified in the .bp file.
distFiles TaggedDistFiles
@@ -2016,9 +2019,8 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
m.tidyFiles = append(m.tidyFiles, ctx.tidyFiles...)
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
- for k, v := range ctx.phonies {
- m.phonies[k] = append(m.phonies[k], v...)
- }
+ m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
+ m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
} else if ctx.Config().AllowMissingDependencies() {
// If the module is not enabled it will not create any build rules, nothing will call
// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
@@ -2217,12 +2219,52 @@ type moduleContext struct {
module Module
phonies map[string]Paths
+ katiInstalls []katiInstall
+ katiSymlinks []katiInstall
+
// For tests
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
variables map[string]string
}
+// katiInstall stores a request from Soong to Make to create an install rule.
+type katiInstall struct {
+ from Path
+ to InstallPath
+ implicitDeps Paths
+ orderOnlyDeps Paths
+ executable bool
+
+ absFrom string
+}
+
+type katiInstalls []katiInstall
+
+// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
+// space separated list of from:to tuples.
+func (installs katiInstalls) BuiltInstalled() string {
+ sb := strings.Builder{}
+ for i, install := range installs {
+ if i != 0 {
+ sb.WriteRune(' ')
+ }
+ sb.WriteString(install.from.String())
+ sb.WriteRune(':')
+ sb.WriteString(install.to.String())
+ }
+ return sb.String()
+}
+
+// InstallPaths returns the install path of each entry.
+func (installs katiInstalls) InstallPaths() InstallPaths {
+ paths := make(InstallPaths, 0, len(installs))
+ for _, install := range installs {
+ paths = append(paths, install.to)
+ }
+ return paths
+}
+
func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
return pctx, BuildParams{
Rule: ErrorRule,
@@ -2854,20 +2896,33 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
orderOnlyDeps = deps
}
- rule := Cp
- if executable {
- rule = CpExecutable
- }
+ if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ // When creating the install rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ m.katiInstalls = append(m.katiInstalls, katiInstall{
+ from: srcPath,
+ to: fullInstallPath,
+ implicitDeps: implicitDeps,
+ orderOnlyDeps: orderOnlyDeps,
+ executable: executable,
+ })
+ } else {
+ rule := Cp
+ if executable {
+ rule = CpExecutable
+ }
- m.Build(pctx, BuildParams{
- Rule: rule,
- Description: "install " + fullInstallPath.Base(),
- Output: fullInstallPath,
- Input: srcPath,
- Implicits: implicitDeps,
- OrderOnly: orderOnlyDeps,
- Default: !m.Config().KatiEnabled(),
- })
+ m.Build(pctx, BuildParams{
+ Rule: rule,
+ Description: "install " + fullInstallPath.Base(),
+ Output: fullInstallPath,
+ Input: srcPath,
+ Implicits: implicitDeps,
+ OrderOnly: orderOnlyDeps,
+ Default: !m.Config().KatiEnabled(),
+ })
+ }
m.installFiles = append(m.installFiles, fullInstallPath)
}
@@ -2889,16 +2944,26 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src
}
if !m.skipInstall() {
- m.Build(pctx, BuildParams{
- Rule: Symlink,
- Description: "install symlink " + fullInstallPath.Base(),
- Output: fullInstallPath,
- Input: srcPath,
- Default: !m.Config().KatiEnabled(),
- Args: map[string]string{
- "fromPath": relPath,
- },
- })
+ if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ // When creating the symlink rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+ from: srcPath,
+ to: fullInstallPath,
+ })
+ } else {
+ m.Build(pctx, BuildParams{
+ Rule: Symlink,
+ Description: "install symlink " + fullInstallPath.Base(),
+ Output: fullInstallPath,
+ Input: srcPath,
+ Default: !m.Config().KatiEnabled(),
+ Args: map[string]string{
+ "fromPath": relPath,
+ },
+ })
+ }
m.installFiles = append(m.installFiles, fullInstallPath)
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
@@ -2921,15 +2986,25 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
if !m.skipInstall() {
- m.Build(pctx, BuildParams{
- Rule: Symlink,
- Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
- Output: fullInstallPath,
- Default: !m.Config().KatiEnabled(),
- Args: map[string]string{
- "fromPath": absPath,
- },
- })
+ if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ // When creating the symlink rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+ absFrom: absPath,
+ to: fullInstallPath,
+ })
+ } else {
+ m.Build(pctx, BuildParams{
+ Rule: Symlink,
+ Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
+ Output: fullInstallPath,
+ Default: !m.Config().KatiEnabled(),
+ Args: map[string]string{
+ "fromPath": absPath,
+ },
+ })
+ }
m.installFiles = append(m.installFiles, fullInstallPath)
}
diff --git a/bazel/configurability.go b/bazel/configurability.go
index e9641e7ff..f05c8e55c 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -39,6 +39,7 @@ const (
osArchAndroidArm64 = "android_arm64"
osArchAndroidX86 = "android_x86"
osArchAndroidX86_64 = "android_x86_64"
+ osArchDarwinArm64 = "darwin_arm64"
osArchDarwinX86_64 = "darwin_x86_64"
osArchLinuxX86 = "linux_glibc_x86"
osArchLinuxX86_64 = "linux_glibc_x86_64"
@@ -96,6 +97,7 @@ var (
osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
+ osArchDarwinArm64: "//build/bazel/platforms/os_arch:darwin_arm64",
osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index 3e8ee48ca..7b7ee2849 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -24,7 +24,7 @@ bootstrap_go_package {
"x86_device.go",
"x86_64_device.go",
- "x86_darwin_host.go",
+ "darwin_host.go",
"x86_linux_host.go",
"x86_linux_bionic_host.go",
"x86_windows_host.go",
diff --git a/cc/config/x86_darwin_host.go b/cc/config/darwin_host.go
index ad82b9476..318acb4e7 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/darwin_host.go
@@ -53,9 +53,6 @@ var (
}
darwinSupportedSdkVersions = []string{
- "10.13",
- "10.14",
- "10.15",
"11",
}
@@ -174,19 +171,43 @@ type toolchainDarwin struct {
toolchain64Bit
}
-func (t *toolchainDarwin) Name() string {
+type toolchainDarwinX86 struct {
+ toolchainDarwin
+}
+
+type toolchainDarwinArm struct {
+ toolchainDarwin
+}
+
+func (t *toolchainDarwinArm) Name() string {
+ return "arm64"
+}
+
+func (t *toolchainDarwinX86) Name() string {
return "x86_64"
}
-func (t *toolchainDarwin) GccRoot() string {
+func (t *toolchainDarwinArm) GccRoot() string {
+ panic("unimplemented")
+}
+
+func (t *toolchainDarwinArm) GccTriple() string {
+ panic("unimplemented")
+}
+
+func (t *toolchainDarwinArm) GccVersion() string {
+ panic("unimplemented")
+}
+
+func (t *toolchainDarwinX86) GccRoot() string {
return "${config.DarwinGccRoot}"
}
-func (t *toolchainDarwin) GccTriple() string {
+func (t *toolchainDarwinX86) GccTriple() string {
return "${config.DarwinGccTriple}"
}
-func (t *toolchainDarwin) GccVersion() string {
+func (t *toolchainDarwinX86) GccVersion() string {
return darwinGccVersion
}
@@ -194,7 +215,11 @@ func (t *toolchainDarwin) IncludeFlags() string {
return ""
}
-func (t *toolchainDarwin) ClangTriple() string {
+func (t *toolchainDarwinArm) ClangTriple() string {
+ return "aarch64-apple-darwin"
+}
+
+func (t *toolchainDarwinX86) ClangTriple() string {
return "x86_64-apple-darwin"
}
@@ -230,12 +255,18 @@ func (t *toolchainDarwin) ToolPath() string {
return "${config.MacToolPath}"
}
-var toolchainDarwinSingleton Toolchain = &toolchainDarwin{}
+var toolchainDarwinArmSingleton Toolchain = &toolchainDarwinArm{}
+var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{}
+
+func darwinArmToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainDarwinArmSingleton
+}
-func darwinToolchainFactory(arch android.Arch) Toolchain {
- return toolchainDarwinSingleton
+func darwinX86ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainDarwinX86Singleton
}
func init() {
- registerToolchainFactory(android.Darwin, android.X86_64, darwinToolchainFactory)
+ registerToolchainFactory(android.Darwin, android.Arm64, darwinArmToolchainFactory)
+ registerToolchainFactory(android.Darwin, android.X86_64, darwinX86ToolchainFactory)
}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 8f18790ea..bfa683824 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -616,6 +616,8 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext)
// This is an exception to support end-to-end test for SdkExtensions, until such support exists.
if android.InList("test_framework-sdkextensions", possibleUpdatableModules) {
jars = jars.Append("com.android.sdkext", "test_framework-sdkextensions")
+ } else if android.InList("test_framework-apexd", possibleUpdatableModules) {
+ jars = jars.Append("com.android.apex.test_package", "test_framework-apexd")
} else if global.ApexBootJars.Len() != 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
unknown = android.RemoveListFromList(unknown, b.properties.Coverage.Contents)
_, unknown = android.RemoveFromList("core-icu4j", unknown)
diff --git a/java/robolectric.go b/java/robolectric.go
index a3603adf8..16af546ba 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -212,13 +212,7 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
installDeps = append(installDeps, installedData)
}
- installed := ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
-
- if r.ExportedToMake() {
- // Soong handles installation here, but Make is usually what creates the phony rule that atest
- // uses to build the module. Create it here for now.
- ctx.Phony(ctx.ModuleName(), installed)
- }
+ r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
}
func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath,
@@ -282,6 +276,10 @@ func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFi
func (r *robolectricTest) AndroidMkEntries() []android.AndroidMkEntries {
entriesList := r.Library.AndroidMkEntries()
entries := &entriesList[0]
+ entries.ExtraEntries = append(entries.ExtraEntries,
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ })
entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string) {
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index b5f52fd10..d75635c43 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -124,8 +124,15 @@ func (s *SystemServerClasspathModule) configuredJars(ctx android.ModuleContext)
// So ignore it even if it is not in PRODUCT_APEX_SYSTEM_SERVER_JARS.
// TODO(b/203233647): Add better mechanism to make it optional.
_, unknown = android.RemoveFromList("car-frameworks-service-module", unknown)
- // For non test apexes, make sure that all contents are actually declared in make.
- if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
+
+ // TODO(satayev): for apex_test we want to include all contents unconditionally to classpaths
+ // config. However, any test specific jars would not be present in ApexSystemServerJars. Instead,
+ // we should check if we are creating a config for apex_test via ApexInfo and amend the values.
+ // This is an exception to support end-to-end test for ApexdUnitTests, until such support exists.
+ if android.InList("test_service-apexd", possibleUpdatableModules) {
+ jars = jars.Append("com.android.apex.test_package", "test_service-apexd")
+ } else if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
+ // For non test apexes, make sure that all contents are actually declared in make.
ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_SYSTEM_SERVER_JARS", unknown)
}
diff --git a/rust/binary.go b/rust/binary.go
index 2c3f54835..7c18730c6 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -31,6 +31,11 @@ type BinaryCompilerProperties struct {
Static_executable *bool `android:"arch_variant"`
}
+type binaryInterface interface {
+ binary() bool
+ staticallyLinked() bool
+}
+
type binaryDecorator struct {
*baseCompiler
stripper Stripper
@@ -155,3 +160,11 @@ func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
}
return binary.baseCompiler.stdLinkage(ctx)
}
+
+func (binary *binaryDecorator) binary() bool {
+ return true
+}
+
+func (binary *binaryDecorator) staticallyLinked() bool {
+ return Bool(binary.Properties.Static_executable)
+}
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index 5b121c3aa..7757c79fc 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -16,7 +16,7 @@ bootstrap_go_package {
"lints.go",
"toolchain.go",
"allowed_list.go",
- "x86_darwin_host.go",
+ "darwin_host.go",
"x86_linux_bionic_host.go",
"x86_linux_host.go",
"x86_device.go",
diff --git a/rust/config/x86_darwin_host.go b/rust/config/darwin_host.go
index 8ff0dd4be..03bea8274 100644
--- a/rust/config/x86_darwin_host.go
+++ b/rust/config/darwin_host.go
@@ -25,41 +25,64 @@ var (
DarwinRustLinkFlags = []string{
"-B${cc_config.MacToolPath}",
}
+ darwinArm64Rustflags = []string{}
+ darwinArm64Linkflags = []string{}
darwinX8664Rustflags = []string{}
darwinX8664Linkflags = []string{}
)
func init() {
+ registerToolchainFactory(android.Darwin, android.Arm64, darwinArm64ToolchainFactory)
registerToolchainFactory(android.Darwin, android.X86_64, darwinX8664ToolchainFactory)
+
pctx.StaticVariable("DarwinToolchainRustFlags", strings.Join(DarwinRustFlags, " "))
pctx.StaticVariable("DarwinToolchainLinkFlags", strings.Join(DarwinRustLinkFlags, " "))
+
+ pctx.StaticVariable("DarwinToolchainArm64RustFlags", strings.Join(darwinArm64Rustflags, " "))
+ pctx.StaticVariable("DarwinToolchainArm64LinkFlags", strings.Join(darwinArm64Linkflags, " "))
pctx.StaticVariable("DarwinToolchainX8664RustFlags", strings.Join(darwinX8664Rustflags, " "))
pctx.StaticVariable("DarwinToolchainX8664LinkFlags", strings.Join(darwinX8664Linkflags, " "))
}
type toolchainDarwin struct {
+ toolchain64Bit
toolchainRustFlags string
toolchainLinkFlags string
}
+type toolchainDarwinArm64 struct {
+ toolchainDarwin
+}
+
type toolchainDarwinX8664 struct {
- toolchain64Bit
toolchainDarwin
}
+func (toolchainDarwinArm64) Supported() bool {
+ return true
+}
+
func (toolchainDarwinX8664) Supported() bool {
return true
}
-func (toolchainDarwinX8664) Bionic() bool {
+func (toolchainDarwin) Bionic() bool {
return false
}
+func (t *toolchainDarwinArm64) Name() string {
+ return "arm64"
+}
+
func (t *toolchainDarwinX8664) Name() string {
return "x86_64"
}
+func (t *toolchainDarwinArm64) RustTriple() string {
+ return "aarch64-apple-darwin"
+}
+
func (t *toolchainDarwinX8664) RustTriple() string {
return "x86_64-apple-darwin"
}
@@ -76,6 +99,15 @@ func (t *toolchainDarwin) ProcMacroSuffix() string {
return ".dylib"
}
+func (t *toolchainDarwinArm64) ToolchainLinkFlags() string {
+ // Prepend the lld flags from cc_config so we stay in sync with cc
+ return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainArm64LinkFlags}"
+}
+
+func (t *toolchainDarwinArm64) ToolchainRustFlags() string {
+ return "${config.DarwinToolchainRustFlags} ${config.DarwinToolchainArm64RustFlags}"
+}
+
func (t *toolchainDarwinX8664) ToolchainLinkFlags() string {
// Prepend the lld flags from cc_config so we stay in sync with cc
return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
@@ -85,8 +117,13 @@ func (t *toolchainDarwinX8664) ToolchainRustFlags() string {
return "${config.DarwinToolchainRustFlags} ${config.DarwinToolchainX8664RustFlags}"
}
+func darwinArm64ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainDarwinArm64Singleton
+}
+
func darwinX8664ToolchainFactory(arch android.Arch) Toolchain {
return toolchainDarwinX8664Singleton
}
+var toolchainDarwinArm64Singleton Toolchain = &toolchainDarwinArm64{}
var toolchainDarwinX8664Singleton Toolchain = &toolchainDarwinX8664{}
diff --git a/rust/rust.go b/rust/rust.go
index 13169f17e..c465cb609 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -261,10 +261,8 @@ func (mod *Module) Rlib() bool {
}
func (mod *Module) Binary() bool {
- if mod.compiler != nil {
- if _, ok := mod.compiler.(*binaryDecorator); ok {
- return true
- }
+ if binary, ok := mod.compiler.(binaryInterface); ok {
+ return binary.binary()
}
return false
}
@@ -273,7 +271,7 @@ func (mod *Module) StaticExecutable() bool {
if !mod.Binary() {
return false
}
- return Bool(mod.compiler.(*binaryDecorator).Properties.Static_executable)
+ return mod.StaticallyLinked()
}
func (mod *Module) Object() bool {
@@ -1123,7 +1121,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if cc.IsWholeStaticLib(depTag) {
// rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail
// if the library is not prefixed by "lib".
- if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
+ if mod.Binary() {
+ // Binaries may sometimes need to link whole static libraries that don't start with 'lib'.
+ // Since binaries don't need to 'rebundle' these like libraries and only use these for the
+ // final linkage, pass the args directly to the linker to handle these cases.
+ depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...)
+ } else if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
} else {
ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
diff --git a/rust/sanitize.go b/rust/sanitize.go
index a4ba4bd33..baa383da6 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -311,8 +311,8 @@ func (mod *Module) SetSanitizeDep(b bool) {
func (mod *Module) StaticallyLinked() bool {
if lib, ok := mod.compiler.(libraryInterface); ok {
return lib.rlib() || lib.static()
- } else if binary, ok := mod.compiler.(*binaryDecorator); ok {
- return Bool(binary.Properties.Static_executable)
+ } else if binary, ok := mod.compiler.(binaryInterface); ok {
+ return binary.staticallyLinked()
}
return false
}
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index b1b1e7e60..ed63651ef 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -69,6 +69,7 @@ javax\.xml\.transform\.sax
javax\.xml\.transform\.stream
javax\.xml\.validation
javax\.xml\.xpath
+jdk\.internal
jdk\.internal\.math
jdk\.internal\.misc
jdk\.internal\.reflect
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index b4936b865..8bed52a9f 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -84,6 +84,13 @@ def parse_args():
return parser.parse_args()
+C_RED = "\033[1;31m"
+C_GREEN = "\033[1;32m"
+C_BLUE = "\033[1;34m"
+C_OFF = "\033[0m"
+C_BOLD = "\033[1m"
+
+
def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
"""Verify that the <uses-library> tags in the manifest match those provided
@@ -119,22 +126,21 @@ def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
errmsg = ''.join([
'mismatch in the <uses-library> tags between the build system and the '
'manifest:\n',
- '\t- required libraries in build system: [%s]\n' % ', '.join(required),
- '\t vs. in the manifest: [%s]\n' %
- ', '.join(manifest_required),
- '\t- optional libraries in build system: [%s]\n' % ', '.join(optional),
- '\t vs. in the manifest: [%s]\n' %
- ', '.join(manifest_optional),
+ '\t- required libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(required), C_OFF),
+ '\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_required), C_OFF),
+ '\t- optional libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(optional), C_OFF),
+ '\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_optional), C_OFF),
'\t- tags in the manifest (%s):\n' % path,
'\t\t%s\n' % '\t\t'.join(tags),
- 'note: the following options are available:\n',
+ '%snote:%s the following options are available:\n' % (C_BLUE, C_OFF),
'\t- to temporarily disable the check on command line, rebuild with ',
- 'RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" ',
- 'and disable AOT-compilation in dexpreopt)\n',
+ '%sRELAX_USES_LIBRARY_CHECK=true%s' % (C_BOLD, C_OFF),
+ ' (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)\n',
'\t- to temporarily disable the check for the whole product, set ',
- 'PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles\n',
- '\t- to fix the check, make build system properties coherent with the '
- 'manifest\n', '\t- see build/make/Changes.md for details\n'
+ '%sPRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true%s in the product makefiles\n' % (C_BOLD, C_OFF),
+ '\t- to fix the check, make build system properties coherent with the manifest\n',
+ '\t- for details, see %sbuild/make/Changes.md%s' % (C_GREEN, C_OFF),
+ ' and %shttps://source.android.com/devices/tech/dalvik/art-class-loader-context%s\n' % (C_GREEN, C_OFF)
])
#pylint: enable=line-too-long
@@ -380,7 +386,7 @@ def main():
# pylint: disable=broad-except
except Exception as err:
- print('error: ' + str(err), file=sys.stderr)
+ print('%serror:%s ' % (C_RED, C_OFF) + str(err), file=sys.stderr)
sys.exit(-1)
diff --git a/ui/build/soong.go b/ui/build/soong.go
index a0f223b2c..1c7fbac7e 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -15,6 +15,7 @@
package build
import (
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -43,6 +44,12 @@ const (
jsonModuleGraphTag = "modulegraph"
queryviewTag = "queryview"
soongDocsTag = "soong_docs"
+
+ // bootstrapEpoch is used to determine if an incremental build is incompatible with the current
+ // version of bootstrap and needs cleaning before continuing the build. Increment this for
+ // incompatible changes, for example when moving the location of the bpglob binary that is
+ // executed during bootstrap before the primary builder has had a chance to update the path.
+ bootstrapEpoch = 0
)
func writeEnvironmentFile(ctx Context, envFile string, envDeps map[string]string) error {
@@ -121,20 +128,31 @@ func environmentArgs(config Config, tag string) []string {
}
}
-func writeEmptyGlobFile(ctx Context, path string) {
+func writeEmptyFile(ctx Context, path string) {
err := os.MkdirAll(filepath.Dir(path), 0777)
if err != nil {
- ctx.Fatalf("Failed to create parent directories of empty ninja glob file '%s': %s", path, err)
+ ctx.Fatalf("Failed to create parent directories of empty file '%s': %s", path, err)
}
- if _, err := os.Stat(path); os.IsNotExist(err) {
+ if exists, err := fileExists(path); err != nil {
+ ctx.Fatalf("Failed to check if file '%s' exists: %s", path, err)
+ } else if !exists {
err = ioutil.WriteFile(path, nil, 0666)
if err != nil {
- ctx.Fatalf("Failed to create empty ninja glob file '%s': %s", path, err)
+ ctx.Fatalf("Failed to create empty file '%s': %s", path, err)
}
}
}
+func fileExists(path string) (bool, error) {
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ return false, nil
+ } else if err != nil {
+ return false, err
+ }
+ return true, nil
+}
+
func primaryBuilderInvocation(config Config, name string, output string, specificArgs []string) bootstrap.PrimaryBuilderInvocation {
commonArgs := make([]string, 0, 0)
@@ -166,10 +184,45 @@ func primaryBuilderInvocation(config Config, name string, output string, specifi
}
}
+// bootstrapEpochCleanup deletes files used by bootstrap during incremental builds across
+// incompatible changes. Incompatible changes are marked by incrementing the bootstrapEpoch
+// constant. A tree is considered out of date for the current epoch of the
+// .soong.bootstrap.epoch.<epoch> file doesn't exist.
+func bootstrapEpochCleanup(ctx Context, config Config) {
+ epochFile := fmt.Sprintf(".soong.bootstrap.epoch.%d", bootstrapEpoch)
+ epochPath := filepath.Join(config.SoongOutDir(), epochFile)
+ if exists, err := fileExists(epochPath); err != nil {
+ ctx.Fatalf("failed to check if bootstrap epoch file %q exists: %q", epochPath, err)
+ } else if !exists {
+ // The tree is out of date for the current epoch, delete files used by bootstrap
+ // and force the primary builder to rerun.
+ os.Remove(filepath.Join(config.SoongOutDir(), "build.ninja"))
+ for _, globFile := range bootstrapGlobFileList(config) {
+ os.Remove(globFile)
+ }
+
+ // Mark the tree as up to date with the current epoch by writing the epoch marker file.
+ writeEmptyFile(ctx, epochPath)
+ }
+}
+
+func bootstrapGlobFileList(config Config) []string {
+ return []string{
+ config.NamedGlobFile(soongBuildTag),
+ config.NamedGlobFile(bp2buildTag),
+ config.NamedGlobFile(jsonModuleGraphTag),
+ config.NamedGlobFile(queryviewTag),
+ config.NamedGlobFile(soongDocsTag),
+ }
+}
+
func bootstrapBlueprint(ctx Context, config Config) {
ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
defer ctx.EndTrace()
+ // Clean up some files for incremental builds across incompatible changes.
+ bootstrapEpochCleanup(ctx, config)
+
mainSoongBuildExtraArgs := []string{"-o", config.SoongNinjaFile()}
if config.EmptyNinjaFile() {
mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--empty-ninja-file")
@@ -232,8 +285,8 @@ func bootstrapBlueprint(ctx Context, config Config) {
// The glob .ninja files are subninja'd. However, they are generated during
// the build itself so we write an empty file if the file does not exist yet
// so that the subninja doesn't fail on clean builds
- for _, globFile := range globFiles {
- writeEmptyGlobFile(ctx, globFile)
+ for _, globFile := range bootstrapGlobFileList(config) {
+ writeEmptyFile(ctx, globFile)
}
var blueprintArgs bootstrap.Args
@@ -342,7 +395,7 @@ func runSoong(ctx Context, config Config) {
}
}()
- runMicrofactory(ctx, config, filepath.Join(config.HostToolDir(), "bpglob"), "github.com/google/blueprint/bootstrap/bpglob",
+ runMicrofactory(ctx, config, "bpglob", "github.com/google/blueprint/bootstrap/bpglob",
map[string]string{"github.com/google/blueprint": "build/blueprint"})
ninja := func(name, ninjaFile string, targets ...string) {