Merge "Stop using prebuilt NDK CRT objects."

This commit is contained in:
Treehugger Robot 2020-08-12 22:01:27 +00:00 committed by Gerrit Code Review
commit 50a58067e6
10 changed files with 113 additions and 121 deletions

View File

@ -130,34 +130,12 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps = binary.baseLinker.linkerDeps(ctx, deps)
if ctx.toolchain().Bionic() {
if !Bool(binary.baseLinker.Properties.Nocrt) {
if !ctx.useSdk() {
if binary.static() {
deps.CrtBegin = "crtbegin_static"
} else {
deps.CrtBegin = "crtbegin_dynamic"
}
deps.CrtEnd = "crtend_android"
} else {
// TODO(danalbert): Add generation of crt objects.
// For `sdk_version: "current"`, we don't actually have a
// freshly generated set of CRT objects. Use the last stable
// version.
version := ctx.sdkVersion()
if version == "current" {
version = getCurrentNdkPrebuiltVersion(ctx)
}
if binary.static() {
deps.CrtBegin = "ndk_crtbegin_static." + version
} else {
if binary.static() {
deps.CrtBegin = "ndk_crtbegin_static." + version
} else {
deps.CrtBegin = "ndk_crtbegin_dynamic." + version
}
deps.CrtEnd = "ndk_crtend_android." + version
}
}
}
if binary.static() {

View File

@ -681,6 +681,13 @@ func (c *Module) MinSdkVersion() string {
return String(c.Properties.Min_sdk_version)
}
func (c *Module) SplitPerApiLevel() bool {
if linker, ok := c.linker.(*objectLinker); ok {
return linker.isCrt()
}
return false
}
func (c *Module) AlwaysSdk() bool {
return c.Properties.AlwaysSdk || Bool(c.Properties.Sdk_variant_only)
}
@ -952,7 +959,7 @@ func (c *Module) canUseSdk() bool {
func (c *Module) UseSdk() bool {
if c.canUseSdk() {
return String(c.Properties.Sdk_version) != ""
return String(c.Properties.Sdk_version) != "" || c.SplitPerApiLevel()
}
return false
}
@ -1485,8 +1492,11 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
c.Properties.SubName += ramdiskSuffix
} else if c.InRecovery() && !c.OnlyInRecovery() {
c.Properties.SubName += recoverySuffix
} else if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake {
} else if c.IsSdkVariant() && (c.Properties.SdkAndPlatformVariantVisibleToMake || c.SplitPerApiLevel()) {
c.Properties.SubName += sdkSuffix
if c.SplitPerApiLevel() {
c.Properties.SubName += "." + c.SdkVersion()
}
}
ctx := &moduleContext{
@ -1659,7 +1669,7 @@ func (c *Module) begin(ctx BaseModuleContext) {
for _, feature := range c.features {
feature.begin(ctx)
}
if ctx.useSdk() {
if ctx.useSdk() && c.IsSdkVariant() {
version, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch())
if err != nil {
ctx.PropertyErrorf("sdk_version", err.Error())
@ -1762,6 +1772,22 @@ func StubsLibNameAndVersion(name string) (string, string) {
return name, ""
}
func GetCrtVariations(ctx android.BottomUpMutatorContext,
m LinkableInterface) []blueprint.Variation {
if ctx.Os() != android.Android {
return nil
}
if m.UseSdk() {
return []blueprint.Variation{
{Mutator: "sdk", Variation: "sdk"},
{Mutator: "ndk_api", Variation: m.SdkVersion()},
}
}
return []blueprint.Variation{
{Mutator: "sdk", Variation: ""},
}
}
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
if !c.Enabled() {
return
@ -2024,11 +2050,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
vendorSnapshotObjects := vendorSnapshotObjects(actx.Config())
crtVariations := GetCrtVariations(ctx, c)
if deps.CrtBegin != "" {
actx.AddVariationDependencies(nil, CrtBeginDepTag, rewriteSnapshotLibs(deps.CrtBegin, vendorSnapshotObjects))
actx.AddVariationDependencies(crtVariations, CrtBeginDepTag,
rewriteSnapshotLibs(deps.CrtBegin, vendorSnapshotObjects))
}
if deps.CrtEnd != "" {
actx.AddVariationDependencies(nil, CrtEndDepTag, rewriteSnapshotLibs(deps.CrtEnd, vendorSnapshotObjects))
actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
rewriteSnapshotLibs(deps.CrtEnd, vendorSnapshotObjects))
}
if deps.LinkerFlagsFile != "" {
actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
@ -3076,7 +3105,7 @@ func squashRecoverySrcs(m *Module) {
}
func (c *Module) IsSdkVariant() bool {
return c.Properties.IsSdkVariant
return c.Properties.IsSdkVariant || c.AlwaysSdk()
}
func getCurrentNdkPrebuiltVersion(ctx DepsContext) string {

View File

@ -565,7 +565,7 @@ func makeDefineString(name string) string {
var gnuToCReplacer = strings.NewReplacer("gnu", "c")
func ndkPathDeps(ctx ModuleContext) android.Paths {
if ctx.useSdk() {
if ctx.Module().(*Module).IsSdkVariant() {
// The NDK sysroot timestamp file depends on all the NDK sysroot files
// (headers and libraries).
return android.Paths{getNdkBaseTimestampFile(ctx)}

View File

@ -800,21 +800,8 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...)
} else if library.shared() {
if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
if !ctx.useSdk() {
deps.CrtBegin = "crtbegin_so"
deps.CrtEnd = "crtend_so"
} else {
// TODO(danalbert): Add generation of crt objects.
// For `sdk_version: "current"`, we don't actually have a
// freshly generated set of CRT objects. Use the last stable
// version.
version := ctx.sdkVersion()
if version == "current" {
version = getCurrentNdkPrebuiltVersion(ctx)
}
deps.CrtBegin = "ndk_crtbegin_so." + version
deps.CrtEnd = "ndk_crtend_so." + version
}
}
deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...)
deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...)

View File

@ -110,6 +110,10 @@ func intMax(a int, b int) int {
func normalizeNdkApiLevel(ctx android.BaseModuleContext, apiLevel string,
arch android.Arch) (string, error) {
if apiLevel == "" {
panic("empty apiLevel not allowed")
}
if apiLevel == "current" {
return apiLevel, nil
}
@ -136,7 +140,8 @@ func normalizeNdkApiLevel(ctx android.BaseModuleContext, apiLevel string,
// supported version here instead.
version, err := strconv.Atoi(apiLevel)
if err != nil {
return "", fmt.Errorf("API level must be an integer (is %q)", apiLevel)
// Non-integer API levels are codenames.
return apiLevel, nil
}
version = intMax(version, minVersion)
@ -182,40 +187,61 @@ func shouldUseVersionScript(ctx android.BaseModuleContext, stub *stubDecorator)
return version >= unversionedUntil, nil
}
func generateStubApiVariants(mctx android.BottomUpMutatorContext, c *stubDecorator) {
platformVersion := mctx.Config().PlatformSdkVersionInt()
func generatePerApiVariants(ctx android.BottomUpMutatorContext, m *Module,
propName string, propValue string, perSplit func(*Module, string)) {
platformVersion := ctx.Config().PlatformSdkVersionInt()
firstSupportedVersion, err := normalizeNdkApiLevel(mctx, String(c.properties.First_version),
mctx.Arch())
firstSupportedVersion, err := normalizeNdkApiLevel(ctx, propValue,
ctx.Arch())
if err != nil {
mctx.PropertyErrorf("first_version", err.Error())
ctx.PropertyErrorf(propName, err.Error())
}
firstGenVersion, err := getFirstGeneratedVersion(firstSupportedVersion, platformVersion)
firstGenVersion, err := getFirstGeneratedVersion(firstSupportedVersion,
platformVersion)
if err != nil {
// In theory this is impossible because we've already run this through
// normalizeNdkApiLevel above.
mctx.PropertyErrorf("first_version", err.Error())
ctx.PropertyErrorf(propName, err.Error())
}
var versionStrs []string
for version := firstGenVersion; version <= platformVersion; version++ {
versionStrs = append(versionStrs, strconv.Itoa(version))
}
versionStrs = append(versionStrs, mctx.Config().PlatformVersionActiveCodenames()...)
versionStrs = append(versionStrs, ctx.Config().PlatformVersionActiveCodenames()...)
versionStrs = append(versionStrs, "current")
modules := mctx.CreateVariations(versionStrs...)
modules := ctx.CreateVariations(versionStrs...)
for i, module := range modules {
module.(*Module).compiler.(*stubDecorator).properties.ApiLevel = versionStrs[i]
perSplit(module.(*Module), versionStrs[i])
}
}
func NdkApiMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok {
func NdkApiMutator(ctx android.BottomUpMutatorContext) {
if m, ok := ctx.Module().(*Module); ok {
if m.Enabled() {
if compiler, ok := m.compiler.(*stubDecorator); ok {
generateStubApiVariants(mctx, compiler)
if ctx.Os() != android.Android {
// These modules are always android.DeviceEnabled only, but
// those include Fuchsia devices, which we don't support.
ctx.Module().Disable()
return
}
generatePerApiVariants(ctx, m, "first_version",
String(compiler.properties.First_version),
func(m *Module, version string) {
m.compiler.(*stubDecorator).properties.ApiLevel =
version
})
} else if m.SplitPerApiLevel() && m.IsSdkVariant() {
if ctx.Os() != android.Android {
return
}
generatePerApiVariants(ctx, m, "min_sdk_version",
m.MinSdkVersion(), func(m *Module, version string) {
m.Properties.Sdk_version = &version
})
}
}
}

View File

@ -55,6 +55,10 @@ type ObjectLinkerProperties struct {
// if set, the path to a linker script to pass to ld -r when combining multiple object files.
Linker_script *string `android:"path,arch_variant"`
// Indicates that this module is a CRT object. CRT objects will be split
// into a variant per-API level between min_sdk_version and current.
Crt *bool
}
func newObject() *Module {
@ -162,3 +166,7 @@ func (object *objectLinker) coverageOutputFilePath() android.OptionalPath {
func (object *objectLinker) object() bool {
return true
}
func (object *objectLinker) isCrt() bool {
return Bool(object.Properties.Crt)
}

View File

@ -338,6 +338,8 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
vendor_available: true,
native_bridge_supported: true,
stl: "none",
min_sdk_version: "16",
crt: true,
apex_available: [
"//apex_available:platform",
"//apex_available:anyapex",
@ -347,48 +349,26 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
cc_object {
name: "crtbegin_so",
defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
min_sdk_version: "29",
stl: "none",
}
cc_object {
name: "crtbegin_dynamic",
defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
stl: "none",
}
cc_object {
name: "crtbegin_static",
defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
stl: "none",
}
cc_object {
name: "crtend_so",
defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
min_sdk_version: "29",
stl: "none",
}
cc_object {
name: "crtend_android",
defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
stl: "none",
}
cc_library {
@ -420,26 +400,6 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
symbol_file: "libdl.map.txt",
}
ndk_prebuilt_object {
name: "ndk_crtbegin_so.27",
sdk_version: "27",
}
ndk_prebuilt_object {
name: "ndk_crtend_so.27",
sdk_version: "27",
}
ndk_prebuilt_object {
name: "ndk_crtbegin_dynamic.27",
sdk_version: "27",
}
ndk_prebuilt_object {
name: "ndk_crtend_android.27",
sdk_version: "27",
}
ndk_prebuilt_shared_stl {
name: "ndk_libc++_shared",
}

View File

@ -531,16 +531,6 @@ func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
system_shared_libs: [],
sdk_version: "29",
}
ndk_prebuilt_object {
name: "ndk_crtbegin_so.29",
sdk_version: "29",
}
ndk_prebuilt_object {
name: "ndk_crtend_so.29",
sdk_version: "29",
}
`
fs := map[string][]byte{
"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
@ -553,16 +543,28 @@ func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
var crtbeginFound, crtendFound bool
expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
"android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
expectedCrtEnd := ctx.ModuleForTests("crtend_so",
"android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
implicits := []string{}
for _, input := range inputs {
switch input.String() {
case "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o":
implicits = append(implicits, input.String())
if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
crtbeginFound = true
case "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o":
} else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
crtendFound = true
}
}
if !crtbeginFound || !crtendFound {
t.Error("should link with ndk_crtbegin_so.29 and ndk_crtend_so.29")
if !crtbeginFound {
t.Error(fmt.Sprintf(
"expected implicit with suffix %q, have the following implicits:\n%s",
expectedCrtBegin, strings.Join(implicits, "\n")))
}
if !crtendFound {
t.Error(fmt.Sprintf(
"expected implicit with suffix %q, have the following implicits:\n%s",
expectedCrtEnd, strings.Join(implicits, "\n")))
}
}

View File

@ -1003,11 +1003,12 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
blueprint.Variation{Mutator: "link", Variation: "static"}),
cc.StaticDepTag(), deps.StaticLibs...)
crtVariations := append(cc.GetCrtVariations(ctx, mod), commonDepVariations...)
if deps.CrtBegin != "" {
actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin)
actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, deps.CrtBegin)
}
if deps.CrtEnd != "" {
actx.AddVariationDependencies(commonDepVariations, cc.CrtEndDepTag, deps.CrtEnd)
actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, deps.CrtEnd)
}
if mod.sourceProvider != nil {

View File

@ -99,6 +99,7 @@ func GatherRequiredDepsForTest() string {
func CreateTestContext() *android.TestContext {
ctx := android.NewTestArchContext()
android.RegisterPrebuiltMutators(ctx)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
cc.RegisterRequiredBuildComponentsForTest(ctx)
ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
ctx.RegisterModuleType("rust_binary", RustBinaryFactory)