Merge "Replace stringly-typed API levels."

This commit is contained in:
Dan Albert
2020-09-21 20:20:30 +00:00
committed by Gerrit Code Review
10 changed files with 394 additions and 166 deletions

View File

@@ -24,6 +24,192 @@ func init() {
RegisterSingletonType("api_levels", ApiLevelsSingleton) RegisterSingletonType("api_levels", ApiLevelsSingleton)
} }
// An API level, which may be a finalized (numbered) API, a preview (codenamed)
// API, or the future API level (10000). Can be parsed from a string with
// ApiLevelFromUser or ApiLevelOrPanic.
//
// The different *types* of API levels are handled separately. Currently only
// Java has these, and they're managed with the sdkKind enum of the sdkSpec. A
// future cleanup should be to migrate sdkSpec to using ApiLevel instead of its
// sdkVersion int, and to move sdkSpec into this package.
type ApiLevel struct {
// The string representation of the API level.
value string
// A number associated with the API level. The exact value depends on
// whether this API level is a preview or final API.
//
// For final API levels, this is the assigned version number.
//
// For preview API levels, this value has no meaning except to index known
// previews to determine ordering.
number int
// Identifies this API level as either a preview or final API level.
isPreview bool
}
// Returns the canonical name for this API level. For a finalized API level
// this will be the API number as a string. For a preview API level this
// will be the codename, or "current".
func (this ApiLevel) String() string {
return this.value
}
// Returns true if this is a non-final API level.
func (this ApiLevel) IsPreview() bool {
return this.isPreview
}
// Returns true if this is the unfinalized "current" API level. This means
// different things across Java and native. Java APIs do not use explicit
// codenames, so all non-final codenames are grouped into "current". For native
// explicit codenames are typically used, and current is the union of all
// non-final APIs, including those that may not yet be in any codename.
//
// Note that in a build where the platform is final, "current" will not be a
// preview API level but will instead be canonicalized to the final API level.
func (this ApiLevel) IsCurrent() bool {
return this.value == "current"
}
// Returns -1 if the current API level is less than the argument, 0 if they
// are equal, and 1 if it is greater than the argument.
func (this ApiLevel) CompareTo(other ApiLevel) int {
if this.IsPreview() && !other.IsPreview() {
return 1
} else if !this.IsPreview() && other.IsPreview() {
return -1
}
if this.number < other.number {
return -1
} else if this.number == other.number {
return 0
} else {
return 1
}
}
func (this ApiLevel) EqualTo(other ApiLevel) bool {
return this.CompareTo(other) == 0
}
func (this ApiLevel) GreaterThan(other ApiLevel) bool {
return this.CompareTo(other) > 0
}
func (this ApiLevel) GreaterThanOrEqualTo(other ApiLevel) bool {
return this.CompareTo(other) >= 0
}
func (this ApiLevel) LessThan(other ApiLevel) bool {
return this.CompareTo(other) < 0
}
func (this ApiLevel) LessThanOrEqualTo(other ApiLevel) bool {
return this.CompareTo(other) <= 0
}
func uncheckedFinalApiLevel(num int) ApiLevel {
return ApiLevel{
value: strconv.Itoa(num),
number: num,
isPreview: false,
}
}
// TODO: Merge with FutureApiLevel
var CurrentApiLevel = ApiLevel{
value: "current",
number: 10000,
isPreview: true,
}
var NoneApiLevel = ApiLevel{
value: "(no version)",
// Not 0 because we don't want this to compare equal with the first preview.
number: -1,
isPreview: true,
}
// The first version that introduced 64-bit ABIs.
var FirstLp64Version = uncheckedFinalApiLevel(21)
// The first API level that does not require NDK code to link
// libandroid_support.
var FirstNonLibAndroidSupportVersion = uncheckedFinalApiLevel(21)
// If the `raw` input is the codename of an API level has been finalized, this
// function returns the API level number associated with that API level. If the
// input is *not* a finalized codename, the input is returned unmodified.
//
// For example, at the time of writing, R has been finalized as API level 30,
// but S is in development so it has no number assigned. For the following
// inputs:
//
// * "30" -> "30"
// * "R" -> "30"
// * "S" -> "S"
func ReplaceFinalizedCodenames(ctx EarlyModuleContext, raw string) string {
num, ok := getFinalCodenamesMap(ctx.Config())[raw]
if !ok {
return raw
}
return strconv.Itoa(num)
}
// Converts the given string `raw` to an ApiLevel, possibly returning an error.
//
// `raw` must be non-empty. Passing an empty string results in a panic.
//
// "current" will return CurrentApiLevel, which is the ApiLevel associated with
// an arbitrary future release (often referred to as API level 10000).
//
// Finalized codenames will be interpreted as their final API levels, not the
// preview of the associated releases. R is now API 30, not the R preview.
//
// Future codenames return a preview API level that has no associated integer.
//
// Inputs that are not "current", known previews, or convertible to an integer
// will return an error.
func ApiLevelFromUser(ctx EarlyModuleContext, raw string) (ApiLevel, error) {
if raw == "" {
panic("API level string must be non-empty")
}
if raw == "current" {
return CurrentApiLevel, nil
}
for _, preview := range ctx.Config().PreviewApiLevels() {
if raw == preview.String() {
return preview, nil
}
}
canonical := ReplaceFinalizedCodenames(ctx, raw)
asInt, err := strconv.Atoi(canonical)
if err != nil {
return NoneApiLevel, fmt.Errorf("%q could not be parsed as an integer and is not a recognized codename", canonical)
}
apiLevel := uncheckedFinalApiLevel(asInt)
return apiLevel, nil
}
// Converts an API level string `raw` into an ApiLevel in the same method as
// `ApiLevelFromUser`, but the input is assumed to have no errors and any errors
// will panic instead of returning an error.
func ApiLevelOrPanic(ctx EarlyModuleContext, raw string) ApiLevel {
value, err := ApiLevelFromUser(ctx, raw)
if err != nil {
panic(err.Error())
}
return value
}
func ApiLevelsSingleton() Singleton { func ApiLevelsSingleton() Singleton {
return &apiLevelsSingleton{} return &apiLevelsSingleton{}
} }
@@ -52,6 +238,36 @@ func GetApiLevelsJson(ctx PathContext) WritablePath {
return PathForOutput(ctx, "api_levels.json") return PathForOutput(ctx, "api_levels.json")
} }
var finalCodenamesMapKey = NewOnceKey("FinalCodenamesMap")
func getFinalCodenamesMap(config Config) map[string]int {
return config.Once(finalCodenamesMapKey, func() interface{} {
apiLevelsMap := map[string]int{
"G": 9,
"I": 14,
"J": 16,
"J-MR1": 17,
"J-MR2": 18,
"K": 19,
"L": 21,
"L-MR1": 22,
"M": 23,
"N": 24,
"N-MR1": 25,
"O": 26,
"O-MR1": 27,
"P": 28,
"Q": 29,
}
if Bool(config.productVariables.Platform_sdk_final) {
apiLevelsMap["current"] = config.PlatformSdkVersionInt()
}
return apiLevelsMap
}).(map[string]int)
}
var apiLevelsMapKey = NewOnceKey("ApiLevelsMap") var apiLevelsMapKey = NewOnceKey("ApiLevelsMap")
func getApiLevelsMap(config Config) map[string]int { func getApiLevelsMap(config Config) map[string]int {

View File

@@ -642,8 +642,34 @@ func (c *config) PlatformBaseOS() string {
return String(c.productVariables.Platform_base_os) return String(c.productVariables.Platform_base_os)
} }
func (c *config) MinSupportedSdkVersion() int { func (c *config) MinSupportedSdkVersion() ApiLevel {
return 16 return uncheckedFinalApiLevel(16)
}
func (c *config) FinalApiLevels() []ApiLevel {
var levels []ApiLevel
for i := 1; i <= c.PlatformSdkVersionInt(); i++ {
levels = append(levels, uncheckedFinalApiLevel(i))
}
return levels
}
func (c *config) PreviewApiLevels() []ApiLevel {
var levels []ApiLevel
for i, codename := range c.PlatformVersionActiveCodenames() {
levels = append(levels, ApiLevel{
value: codename,
number: i,
isPreview: true,
})
}
return levels
}
func (c *config) AllSupportedApiLevels() []ApiLevel {
var levels []ApiLevel
levels = append(levels, c.FinalApiLevels()...)
return append(levels, c.PreviewApiLevels()...)
} }
func (c *config) DefaultAppTargetSdkInt() int { func (c *config) DefaultAppTargetSdkInt() int {

View File

@@ -18,7 +18,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"sort" "sort"
"strconv"
"strings" "strings"
"github.com/google/blueprint" "github.com/google/blueprint"
@@ -31,7 +30,7 @@ func init() {
} }
func androidMakeVarsProvider(ctx MakeVarsContext) { func androidMakeVarsProvider(ctx MakeVarsContext) {
ctx.Strict("MIN_SUPPORTED_SDK_VERSION", strconv.Itoa(ctx.Config().MinSupportedSdkVersion())) ctx.Strict("MIN_SUPPORTED_SDK_VERSION", ctx.Config().MinSupportedSdkVersion().String())
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@@ -13,6 +13,7 @@ bootstrap_go_package {
], ],
srcs: [ srcs: [
"androidmk.go", "androidmk.go",
"api_level.go",
"builder.go", "builder.go",
"cc.go", "cc.go",
"ccdeps.go", "ccdeps.go",

View File

@@ -451,7 +451,7 @@ func (installer *baseInstaller) AndroidMkEntries(ctx AndroidMkContext, entries *
} }
func (c *stubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { func (c *stubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
entries.SubName = ndkLibrarySuffix + "." + c.properties.ApiLevel entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String()
entries.Class = "SHARED_LIBRARIES" entries.Class = "SHARED_LIBRARIES"
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) { entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {

71
cc/api_level.go Normal file
View File

@@ -0,0 +1,71 @@
// Copyright 2020 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 (
"fmt"
"android/soong/android"
)
func minApiForArch(ctx android.BaseModuleContext,
arch android.ArchType) android.ApiLevel {
switch arch {
case android.Arm, android.X86:
return ctx.Config().MinSupportedSdkVersion()
case android.Arm64, android.X86_64:
return android.FirstLp64Version
default:
panic(fmt.Errorf("Unknown arch %q", arch))
}
}
func nativeApiLevelFromUser(ctx android.BaseModuleContext,
raw string) (android.ApiLevel, error) {
min := minApiForArch(ctx, ctx.Arch().ArchType)
if raw == "minimum" {
return min, nil
}
value, err := android.ApiLevelFromUser(ctx, raw)
if err != nil {
return android.NoneApiLevel, err
}
if value.LessThan(min) {
return min, nil
}
return value, nil
}
func nativeApiLevelFromUserWithDefault(ctx android.BaseModuleContext,
raw string, defaultValue string) (android.ApiLevel, error) {
if raw == "" {
raw = defaultValue
}
return nativeApiLevelFromUser(ctx, raw)
}
func nativeApiLevelOrPanic(ctx android.BaseModuleContext,
raw string) android.ApiLevel {
value, err := nativeApiLevelFromUser(ctx, raw)
if err != nil {
panic(err.Error())
}
return value
}

View File

@@ -629,7 +629,7 @@ func (c *Module) Toc() android.OptionalPath {
func (c *Module) ApiLevel() string { func (c *Module) ApiLevel() string {
if c.linker != nil { if c.linker != nil {
if stub, ok := c.linker.(*stubDecorator); ok { if stub, ok := c.linker.(*stubDecorator); ok {
return stub.properties.ApiLevel return stub.apiLevel.String()
} }
} }
panic(fmt.Errorf("ApiLevel() called on non-stub library module: %q", c.BaseModuleName())) panic(fmt.Errorf("ApiLevel() called on non-stub library module: %q", c.BaseModuleName()))
@@ -1682,11 +1682,13 @@ func (c *Module) begin(ctx BaseModuleContext) {
feature.begin(ctx) feature.begin(ctx)
} }
if ctx.useSdk() && c.IsSdkVariant() { if ctx.useSdk() && c.IsSdkVariant() {
version, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch()) version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion())
if err != nil { if err != nil {
ctx.PropertyErrorf("sdk_version", err.Error()) ctx.PropertyErrorf("sdk_version", err.Error())
c.Properties.Sdk_version = nil
} else {
c.Properties.Sdk_version = StringPtr(version.String())
} }
c.Properties.Sdk_version = StringPtr(version)
} }
} }
@@ -3119,13 +3121,6 @@ func (c *Module) IsSdkVariant() bool {
return c.Properties.IsSdkVariant || c.AlwaysSdk() return c.Properties.IsSdkVariant || c.AlwaysSdk()
} }
func getCurrentNdkPrebuiltVersion(ctx DepsContext) string {
if ctx.Config().PlatformSdkVersionInt() > config.NdkMaxPrebuiltVersionInt {
return strconv.Itoa(config.NdkMaxPrebuiltVersionInt)
}
return ctx.Config().PlatformSdkVersion()
}
func kytheExtractAllFactory() android.Singleton { func kytheExtractAllFactory() android.Singleton {
return &kytheExtractAllSingleton{} return &kytheExtractAllSingleton{}
} }

View File

@@ -126,8 +126,6 @@ var (
ExperimentalCStdVersion = "gnu11" ExperimentalCStdVersion = "gnu11"
ExperimentalCppStdVersion = "gnu++2a" ExperimentalCppStdVersion = "gnu++2a"
NdkMaxPrebuiltVersionInt = 27
// prebuilts/clang default settings. // prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host" ClangDefaultBase = "prebuilts/clang/host"
ClangDefaultVersion = "clang-r383902b" ClangDefaultVersion = "clang-r383902b"

View File

@@ -16,7 +16,6 @@ package cc
import ( import (
"fmt" "fmt"
"strconv"
"strings" "strings"
"sync" "sync"
@@ -52,6 +51,10 @@ var (
ndkKnownLibsLock sync.Mutex ndkKnownLibsLock sync.Mutex
) )
// The First_version and Unversioned_until properties of this struct should not
// be used directly, but rather through the ApiLevel returning methods
// firstVersion() and unversionedUntil().
// Creates a stub shared library based on the provided version file. // Creates a stub shared library based on the provided version file.
// //
// Example: // Example:
@@ -77,9 +80,7 @@ type libraryProperties struct {
// https://github.com/android-ndk/ndk/issues/265. // https://github.com/android-ndk/ndk/issues/265.
Unversioned_until *string Unversioned_until *string
// Private property for use by the mutator that splits per-API level. Can be // Use via apiLevel on the stubDecorator.
// one of <number:sdk_version> or <codename> or "current" passed to
// "ndkstubgen.py" as it is
ApiLevel string `blueprint:"mutated"` ApiLevel string `blueprint:"mutated"`
// True if this API is not yet ready to be shipped in the NDK. It will be // True if this API is not yet ready to be shipped in the NDK. It will be
@@ -96,125 +97,33 @@ type stubDecorator struct {
versionScriptPath android.ModuleGenPath versionScriptPath android.ModuleGenPath
parsedCoverageXmlPath android.ModuleOutPath parsedCoverageXmlPath android.ModuleOutPath
installPath android.Path installPath android.Path
apiLevel android.ApiLevel
firstVersion android.ApiLevel
unversionedUntil android.ApiLevel
} }
// OMG GO func shouldUseVersionScript(ctx BaseModuleContext, stub *stubDecorator) bool {
func intMax(a int, b int) int { return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil)
if a > b {
return a
} else {
return b
}
}
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
}
minVersion := ctx.Config().MinSupportedSdkVersion()
firstArchVersions := map[android.ArchType]int{
android.Arm: minVersion,
android.Arm64: 21,
android.X86: minVersion,
android.X86_64: 21,
}
firstArchVersion, ok := firstArchVersions[arch.ArchType]
if !ok {
panic(fmt.Errorf("Arch %q not found in firstArchVersions", arch.ArchType))
}
if apiLevel == "minimum" {
return strconv.Itoa(firstArchVersion), nil
}
// If the NDK drops support for a platform version, we don't want to have to
// fix up every module that was using it as its SDK version. Clip to the
// supported version here instead.
version, err := strconv.Atoi(apiLevel)
if err != nil {
// Non-integer API levels are codenames.
return apiLevel, nil
}
version = intMax(version, minVersion)
return strconv.Itoa(intMax(version, firstArchVersion)), nil
}
func getFirstGeneratedVersion(firstSupportedVersion string, platformVersion int) (int, error) {
if firstSupportedVersion == "current" {
return platformVersion + 1, nil
}
return strconv.Atoi(firstSupportedVersion)
}
func shouldUseVersionScript(ctx android.BaseModuleContext, stub *stubDecorator) (bool, error) {
// unversioned_until is normally empty, in which case we should use the version script.
if String(stub.properties.Unversioned_until) == "" {
return true, nil
}
if String(stub.properties.Unversioned_until) == "current" {
if stub.properties.ApiLevel == "current" {
return true, nil
} else {
return false, nil
}
}
if stub.properties.ApiLevel == "current" {
return true, nil
}
unversionedUntil, err := android.ApiStrToNum(ctx, String(stub.properties.Unversioned_until))
if err != nil {
return true, err
}
version, err := android.ApiStrToNum(ctx, stub.properties.ApiLevel)
if err != nil {
return true, err
}
return version >= unversionedUntil, nil
} }
func generatePerApiVariants(ctx android.BottomUpMutatorContext, m *Module, func generatePerApiVariants(ctx android.BottomUpMutatorContext, m *Module,
propName string, propValue string, perSplit func(*Module, string)) { from android.ApiLevel, perSplit func(*Module, android.ApiLevel)) {
platformVersion := ctx.Config().PlatformSdkVersionInt()
firstSupportedVersion, err := normalizeNdkApiLevel(ctx, propValue, var versions []android.ApiLevel
ctx.Arch()) versionStrs := []string{}
if err != nil { for _, version := range ctx.Config().AllSupportedApiLevels() {
ctx.PropertyErrorf(propName, err.Error()) if version.GreaterThanOrEqualTo(from) {
versions = append(versions, version)
versionStrs = append(versionStrs, version.String())
}
} }
versions = append(versions, android.CurrentApiLevel)
firstGenVersion, err := getFirstGeneratedVersion(firstSupportedVersion, versionStrs = append(versionStrs, android.CurrentApiLevel.String())
platformVersion)
if err != nil {
// In theory this is impossible because we've already run this through
// normalizeNdkApiLevel above.
ctx.PropertyErrorf(propName, err.Error())
}
var versionStrs []string
for version := firstGenVersion; version <= platformVersion; version++ {
versionStrs = append(versionStrs, strconv.Itoa(version))
}
versionStrs = append(versionStrs, ctx.Config().PlatformVersionActiveCodenames()...)
versionStrs = append(versionStrs, "current")
modules := ctx.CreateVariations(versionStrs...) modules := ctx.CreateVariations(versionStrs...)
for i, module := range modules { for i, module := range modules {
perSplit(module.(*Module), versionStrs[i]) perSplit(module.(*Module), versions[i])
} }
} }
@@ -228,25 +137,56 @@ func NdkApiMutator(ctx android.BottomUpMutatorContext) {
ctx.Module().Disable() ctx.Module().Disable()
return return
} }
generatePerApiVariants(ctx, m, "first_version", firstVersion, err := nativeApiLevelFromUser(ctx,
String(compiler.properties.First_version), String(compiler.properties.First_version))
func(m *Module, version string) { if err != nil {
ctx.PropertyErrorf("first_version", err.Error())
return
}
generatePerApiVariants(ctx, m, firstVersion,
func(m *Module, version android.ApiLevel) {
m.compiler.(*stubDecorator).properties.ApiLevel = m.compiler.(*stubDecorator).properties.ApiLevel =
version version.String()
}) })
} else if m.SplitPerApiLevel() && m.IsSdkVariant() { } else if m.SplitPerApiLevel() && m.IsSdkVariant() {
if ctx.Os() != android.Android { if ctx.Os() != android.Android {
return return
} }
generatePerApiVariants(ctx, m, "min_sdk_version", from, err := nativeApiLevelFromUser(ctx, m.MinSdkVersion())
m.MinSdkVersion(), func(m *Module, version string) { if err != nil {
m.Properties.Sdk_version = &version ctx.PropertyErrorf("min_sdk_version", err.Error())
return
}
generatePerApiVariants(ctx, m, from,
func(m *Module, version android.ApiLevel) {
m.Properties.Sdk_version = StringPtr(version.String())
}) })
} }
} }
} }
} }
func (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool {
this.apiLevel = nativeApiLevelOrPanic(ctx, this.properties.ApiLevel)
var err error
this.firstVersion, err = nativeApiLevelFromUser(ctx,
String(this.properties.First_version))
if err != nil {
ctx.PropertyErrorf("first_version", err.Error())
return false
}
this.unversionedUntil, err = nativeApiLevelFromUserWithDefault(ctx,
String(this.properties.Unversioned_until), "minimum")
if err != nil {
ctx.PropertyErrorf("unversioned_until", err.Error())
return false
}
return true
}
func (c *stubDecorator) compilerInit(ctx BaseModuleContext) { func (c *stubDecorator) compilerInit(ctx BaseModuleContext) {
c.baseCompiler.compilerInit(ctx) c.baseCompiler.compilerInit(ctx)
@@ -340,11 +280,16 @@ func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) O
ctx.PropertyErrorf("symbol_file", "must end with .map.txt") ctx.PropertyErrorf("symbol_file", "must end with .map.txt")
} }
if !c.initializeProperties(ctx) {
// Emits its own errors, so we don't need to.
return Objects{}
}
symbolFile := String(c.properties.Symbol_file) symbolFile := String(c.properties.Symbol_file)
objs, versionScript := compileStubLibrary(ctx, flags, symbolFile, objs, versionScript := compileStubLibrary(ctx, flags, symbolFile,
c.properties.ApiLevel, "") c.apiLevel.String(), "")
c.versionScriptPath = versionScript c.versionScriptPath = versionScript
if c.properties.ApiLevel == "current" && ctx.PrimaryArch() { if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
c.parsedCoverageXmlPath = parseSymbolFileForCoverage(ctx, symbolFile) c.parsedCoverageXmlPath = parseSymbolFileForCoverage(ctx, symbolFile)
} }
return objs return objs
@@ -366,12 +311,7 @@ func (stub *stubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
objs Objects) android.Path { objs Objects) android.Path {
useVersionScript, err := shouldUseVersionScript(ctx, stub) if shouldUseVersionScript(ctx, stub) {
if err != nil {
ctx.ModuleErrorf(err.Error())
}
if useVersionScript {
linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag)
flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath) flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath)
@@ -386,8 +326,6 @@ func (stub *stubDecorator) nativeCoverage() bool {
func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) { func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
arch := ctx.Target().Arch.ArchType.Name arch := ctx.Target().Arch.ArchType.Name
apiLevel := stub.properties.ApiLevel
// arm64 isn't actually a multilib toolchain, so unlike the other LP64 // arm64 isn't actually a multilib toolchain, so unlike the other LP64
// architectures it's just installed to lib. // architectures it's just installed to lib.
libDir := "lib" libDir := "lib"
@@ -396,7 +334,7 @@ func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
} }
installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf( installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf(
"platforms/android-%s/arch-%s/usr/%s", apiLevel, arch, libDir)) "platforms/android-%s/arch-%s/usr/%s", stub.apiLevel, arch, libDir))
stub.installPath = ctx.InstallFile(installDir, path.Base(), path) stub.installPath = ctx.InstallFile(installDir, path.Base(), path)
} }

View File

@@ -17,7 +17,6 @@ package cc
import ( import (
"android/soong/android" "android/soong/android"
"fmt" "fmt"
"strconv"
) )
func getNdkStlFamily(m LinkableInterface) string { func getNdkStlFamily(m LinkableInterface) string {
@@ -136,23 +135,8 @@ func (stl *stl) begin(ctx BaseModuleContext) {
} }
func needsLibAndroidSupport(ctx BaseModuleContext) bool { func needsLibAndroidSupport(ctx BaseModuleContext) bool {
versionStr, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch()) version := nativeApiLevelOrPanic(ctx, ctx.sdkVersion())
if err != nil { return version.LessThan(android.FirstNonLibAndroidSupportVersion)
ctx.PropertyErrorf("sdk_version", err.Error())
}
if versionStr == "current" {
return false
}
version, err := strconv.Atoi(versionStr)
if err != nil {
panic(fmt.Sprintf(
"invalid API level returned from normalizeNdkApiLevel: %q",
versionStr))
}
return version < 21
} }
func staticUnwinder(ctx android.BaseModuleContext) string { func staticUnwinder(ctx android.BaseModuleContext) string {