Generate "current" API level.
Support for using this coming in an upcoming patch. Test: nose2 readelf to check the following: * bsd_signal unversioned before current * bsd_signal versioned in current * catclose missing before current * catclose present and versioned in current Bug: None Change-Id: I861862161426d3ec5b530e3156d3a8ae96fed468
This commit is contained in:
@@ -18,7 +18,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
@@ -217,7 +216,7 @@ func (installer *baseInstaller) AndroidMk(ctx AndroidMkContext, ret *android.And
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
ret.SubName = "." + strconv.Itoa(c.properties.ApiLevel)
|
ret.SubName = "." + c.properties.ApiLevel
|
||||||
ret.Class = "SHARED_LIBRARIES"
|
ret.Class = "SHARED_LIBRARIES"
|
||||||
|
|
||||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
||||||
|
@@ -31,11 +31,30 @@ ALL_ARCHITECTURES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Arbitrary magic number. We use the same one in api-level.h for this purpose.
|
||||||
|
FUTURE_API_LEVEL = 10000
|
||||||
|
|
||||||
|
|
||||||
def logger():
|
def logger():
|
||||||
"""Return the main logger for this module."""
|
"""Return the main logger for this module."""
|
||||||
return logging.getLogger(__name__)
|
return logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def api_level_arg(api_str):
|
||||||
|
"""Parses an API level, handling the "current" special case.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
api_str: (string) Either a numeric API level or "current".
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(int) FUTURE_API_LEVEL if `api_str` is "current", else `api_str` parsed
|
||||||
|
as an integer.
|
||||||
|
"""
|
||||||
|
if api_str == "current":
|
||||||
|
return FUTURE_API_LEVEL
|
||||||
|
return int(api_str)
|
||||||
|
|
||||||
|
|
||||||
def get_tags(line):
|
def get_tags(line):
|
||||||
"""Returns a list of all tags on this line."""
|
"""Returns a list of all tags on this line."""
|
||||||
_, _, all_tags = line.strip().partition('#')
|
_, _, all_tags = line.strip().partition('#')
|
||||||
@@ -105,10 +124,7 @@ def symbol_in_api(tags, arch, api):
|
|||||||
introduced_tag = tag
|
introduced_tag = tag
|
||||||
arch_specific = True
|
arch_specific = True
|
||||||
elif tag == 'future':
|
elif tag == 'future':
|
||||||
# This symbol is not in any released API level.
|
return api == FUTURE_API_LEVEL
|
||||||
# TODO(danalbert): These need to be emitted for api == current.
|
|
||||||
# That's not a construct we have yet, so just skip it for now.
|
|
||||||
return False
|
|
||||||
|
|
||||||
if introduced_tag is None:
|
if introduced_tag is None:
|
||||||
# We found no "introduced" tags, so the symbol has always been
|
# We found no "introduced" tags, so the symbol has always been
|
||||||
@@ -310,7 +326,8 @@ def parse_args():
|
|||||||
parser.add_argument('-v', '--verbose', action='count', default=0)
|
parser.add_argument('-v', '--verbose', action='count', default=0)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--api', type=int, required=True, help='API level being targeted.')
|
'--api', type=api_level_arg, required=True,
|
||||||
|
help='API level being targeted.')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--arch', choices=ALL_ARCHITECTURES, required=True,
|
'--arch', choices=ALL_ARCHITECTURES, required=True,
|
||||||
help='Architecture being targeted.')
|
help='Architecture being targeted.')
|
||||||
|
@@ -88,7 +88,7 @@ type libraryProperties struct {
|
|||||||
First_version string
|
First_version string
|
||||||
|
|
||||||
// Private property for use by the mutator that splits per-API level.
|
// Private property for use by the mutator that splits per-API level.
|
||||||
ApiLevel int `blueprint:"mutated"`
|
ApiLevel string `blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubDecorator struct {
|
type stubDecorator struct {
|
||||||
@@ -147,14 +147,15 @@ func generateStubApiVariants(mctx android.BottomUpMutatorContext, c *stubDecorat
|
|||||||
mctx.PropertyErrorf("first_version", err.Error())
|
mctx.PropertyErrorf("first_version", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
versionStrs := make([]string, maxVersion-firstVersion+1)
|
var versionStrs []string
|
||||||
for version := firstVersion; version <= maxVersion; version++ {
|
for version := firstVersion; version <= maxVersion; version++ {
|
||||||
versionStrs[version-firstVersion] = strconv.Itoa(version)
|
versionStrs = append(versionStrs, strconv.Itoa(version))
|
||||||
}
|
}
|
||||||
|
versionStrs = append(versionStrs, "current")
|
||||||
|
|
||||||
modules := mctx.CreateVariations(versionStrs...)
|
modules := mctx.CreateVariations(versionStrs...)
|
||||||
for i, module := range modules {
|
for i, module := range modules {
|
||||||
module.(*Module).compiler.(*stubDecorator).properties.ApiLevel = firstVersion + i
|
module.(*Module).compiler.(*stubDecorator).properties.ApiLevel = versionStrs[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +189,7 @@ func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) O
|
|||||||
ndkLibrarySuffix)
|
ndkLibrarySuffix)
|
||||||
}
|
}
|
||||||
libName := strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix)
|
libName := strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix)
|
||||||
fileBase := fmt.Sprintf("%s.%s.%d", libName, arch, c.properties.ApiLevel)
|
fileBase := fmt.Sprintf("%s.%s.%s", libName, arch, c.properties.ApiLevel)
|
||||||
stubSrcName := fileBase + ".c"
|
stubSrcName := fileBase + ".c"
|
||||||
stubSrcPath := android.PathForModuleGen(ctx, stubSrcName)
|
stubSrcPath := android.PathForModuleGen(ctx, stubSrcName)
|
||||||
versionScriptName := fileBase + ".map"
|
versionScriptName := fileBase + ".map"
|
||||||
@@ -201,7 +202,7 @@ func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) O
|
|||||||
Input: symbolFilePath,
|
Input: symbolFilePath,
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"arch": arch,
|
"arch": arch,
|
||||||
"apiLevel": strconv.Itoa(c.properties.ApiLevel),
|
"apiLevel": c.properties.ApiLevel,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -252,7 +253,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-%d/arch-%s/usr/%s", apiLevel, arch, libDir))
|
"platforms/android-%s/arch-%s/usr/%s", apiLevel, arch, libDir))
|
||||||
stub.installPath = ctx.InstallFile(installDir, path).String()
|
stub.installPath = ctx.InstallFile(installDir, path).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -75,6 +75,8 @@ class SymbolPresenceTest(unittest.TestCase):
|
|||||||
['introduced=9', 'introduced-x86=21'], 'arm', 14))
|
['introduced=9', 'introduced-x86=21'], 'arm', 14))
|
||||||
self.assertTrue(gsl.symbol_in_api(
|
self.assertTrue(gsl.symbol_in_api(
|
||||||
['introduced=21', 'introduced-arm=9'], 'arm', 14))
|
['introduced=21', 'introduced-arm=9'], 'arm', 14))
|
||||||
|
self.assertTrue(gsl.symbol_in_api(
|
||||||
|
['future'], 'arm', gsl.FUTURE_API_LEVEL))
|
||||||
|
|
||||||
self.assertFalse(gsl.symbol_in_api(['introduced=14'], 'arm', 9))
|
self.assertFalse(gsl.symbol_in_api(['introduced=14'], 'arm', 9))
|
||||||
self.assertFalse(gsl.symbol_in_api(['introduced-arm=14'], 'arm', 9))
|
self.assertFalse(gsl.symbol_in_api(['introduced-arm=14'], 'arm', 9))
|
||||||
|
Reference in New Issue
Block a user