diff options
Diffstat (limited to 'cc')
| -rw-r--r-- | cc/androidmk.go | 3 | ||||
| -rw-r--r-- | cc/cc.go | 11 | ||||
| -rw-r--r-- | cc/config/global.go | 4 | ||||
| -rw-r--r-- | cc/linker.go | 7 | ||||
| -rw-r--r-- | cc/ndk_library.go | 40 | ||||
| -rw-r--r-- | cc/scriptlib/Android.bp | 32 | ||||
| -rw-r--r-- | cc/scriptlib/__init__.py | 0 | ||||
| -rwxr-xr-x | cc/scriptlib/gen_stub_libs.py (renamed from cc/gen_stub_libs.py) | 1 | ||||
| -rwxr-xr-x | cc/scriptlib/ndk_api_coverage_parser.py | 134 | ||||
| -rwxr-xr-x | cc/scriptlib/test_gen_stub_libs.py (renamed from cc/test_gen_stub_libs.py) | 0 | ||||
| -rw-r--r-- | cc/scriptlib/test_ndk_api_coverage_parser.py | 66 | ||||
| -rw-r--r-- | cc/sdk.go | 1 |
12 files changed, 283 insertions, 16 deletions
diff --git a/cc/androidmk.go b/cc/androidmk.go index 52480ea68..b3ad610d6 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -457,6 +457,9 @@ func (c *stubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android. entries.SetString("LOCAL_MODULE_PATH", path) entries.SetString("LOCAL_MODULE_STEM", stem) entries.SetBool("LOCAL_NO_NOTICE_FILE", true) + if c.parsedCoverageXmlPath.String() != "" { + entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String()) + } }) } @@ -825,15 +825,8 @@ func (c *Module) Init() android.Module { } c.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool { - switch class { - case android.Device: - return ctx.Config().DevicePrefer32BitExecutables() - case android.HostCross: - // Windows builds always prefer 32-bit - return true - default: - return false - } + // Windows builds always prefer 32-bit + return class == android.HostCross }) android.InitAndroidArchModule(c, c.hod, c.multilib) android.InitApexModule(c) diff --git a/cc/config/global.go b/cc/config/global.go index 1dd8a2d03..7b651bc84 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -128,8 +128,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r383902" - ClangDefaultShortVersion = "11.0.1" + ClangDefaultVersion = "clang-r383902b" + ClangDefaultShortVersion = "11.0.2" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/linker.go b/cc/linker.go index 57a0c016a..c9cbd9baf 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -177,7 +177,10 @@ type BaseLinkerProperties struct { Version_script *string `android:"path,arch_variant"` // list of static libs that should not be used to build this module - Exclude_static_libs []string + Exclude_static_libs []string `android:"arch_variant"` + + // list of shared libs that should not be used to build this module + Exclude_shared_libs []string `android:"arch_variant"` } func NewBaseLinker(sanitize *sanitize) *baseLinker { @@ -223,6 +226,8 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...) deps.ReexportGeneratedHeaders = append(deps.ReexportGeneratedHeaders, linker.Properties.Export_generated_headers...) + deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Exclude_shared_libs) + deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Exclude_static_libs) deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Exclude_static_libs) if Bool(linker.Properties.Use_version_lib) { diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 1597b88d0..d79badbc4 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -25,8 +25,12 @@ import ( "android/soong/android" ) +func init() { + pctx.HostBinToolVariable("ndk_api_coverage_parser", "ndk_api_coverage_parser") +} + var ( - toolPath = pctx.SourcePathVariable("toolPath", "build/soong/cc/gen_stub_libs.py") + toolPath = pctx.SourcePathVariable("toolPath", "build/soong/cc/scriptlib/gen_stub_libs.py") genStubSrc = pctx.AndroidStaticRule("genStubSrc", blueprint.RuleParams{ @@ -35,6 +39,12 @@ var ( CommandDeps: []string{"$toolPath"}, }, "arch", "apiLevel", "apiMap", "flags") + parseNdkApiRule = pctx.AndroidStaticRule("parseNdkApiRule", + blueprint.RuleParams{ + Command: "$ndk_api_coverage_parser $in $out --api-map $apiMap", + CommandDeps: []string{"$ndk_api_coverage_parser"}, + }, "apiMap") + ndkLibrarySuffix = ".ndk" ndkPrebuiltSharedLibs = []string{ @@ -111,8 +121,9 @@ type stubDecorator struct { properties libraryProperties - versionScriptPath android.ModuleGenPath - installPath android.Path + versionScriptPath android.ModuleGenPath + parsedCoverageXmlPath android.ModuleOutPath + installPath android.Path } // OMG GO @@ -308,14 +319,35 @@ func compileStubLibrary(ctx ModuleContext, flags Flags, symbolFile, apiLevel, ge return compileObjs(ctx, flagsToBuilderFlags(flags), subdir, srcs, nil, nil), versionScriptPath } +func parseSymbolFileForCoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath { + apiLevelsJson := android.GetApiLevelsJson(ctx) + symbolFilePath := android.PathForModuleSrc(ctx, symbolFile) + outputFileName := strings.Split(symbolFilePath.Base(), ".")[0] + parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFileName+".xml") + ctx.Build(pctx, android.BuildParams{ + Rule: parseNdkApiRule, + Description: "parse ndk api symbol file for api coverage: " + symbolFilePath.Rel(), + Outputs: []android.WritablePath{parsedApiCoveragePath}, + Input: symbolFilePath, + Args: map[string]string{ + "apiMap": apiLevelsJson.String(), + }, + }) + return parsedApiCoveragePath +} + func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { if !strings.HasSuffix(String(c.properties.Symbol_file), ".map.txt") { ctx.PropertyErrorf("symbol_file", "must end with .map.txt") } - objs, versionScript := compileStubLibrary(ctx, flags, String(c.properties.Symbol_file), + symbolFile := String(c.properties.Symbol_file) + objs, versionScript := compileStubLibrary(ctx, flags, symbolFile, c.properties.ApiLevel, "") c.versionScriptPath = versionScript + if c.properties.ApiLevel == "current" && ctx.PrimaryArch() { + c.parsedCoverageXmlPath = parseSymbolFileForCoverage(ctx, symbolFile) + } return objs } diff --git a/cc/scriptlib/Android.bp b/cc/scriptlib/Android.bp new file mode 100644 index 000000000..ff9a2f0f3 --- /dev/null +++ b/cc/scriptlib/Android.bp @@ -0,0 +1,32 @@ +// +// Copyright (C) 2020 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. +// + +python_test_host { + name: "test_ndk_api_coverage_parser", + main: "test_ndk_api_coverage_parser.py", + srcs: [ + "test_ndk_api_coverage_parser.py", + ], +} + +python_binary_host { + name: "ndk_api_coverage_parser", + main: "ndk_api_coverage_parser.py", + srcs: [ + "gen_stub_libs.py", + "ndk_api_coverage_parser.py", + ], +} diff --git a/cc/scriptlib/__init__.py b/cc/scriptlib/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/cc/scriptlib/__init__.py diff --git a/cc/gen_stub_libs.py b/cc/scriptlib/gen_stub_libs.py index 7deb804c3..d61dfbb07 100755 --- a/cc/gen_stub_libs.py +++ b/cc/scriptlib/gen_stub_libs.py @@ -246,6 +246,7 @@ class Symbol(object): def __eq__(self, other): return self.name == other.name and set(self.tags) == set(other.tags) + class SymbolFileParser(object): """Parses NDK symbol files.""" def __init__(self, input_file, api_map, arch, api, llndk, apex): diff --git a/cc/scriptlib/ndk_api_coverage_parser.py b/cc/scriptlib/ndk_api_coverage_parser.py new file mode 100755 index 000000000..d74035b2a --- /dev/null +++ b/cc/scriptlib/ndk_api_coverage_parser.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# +# Copyright (C) 2020 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. +# +"""Generates xml of NDK libraries used for API coverage analysis.""" +import argparse +import json +import os +import sys + +from xml.etree.ElementTree import Element, SubElement, tostring +from gen_stub_libs import ALL_ARCHITECTURES, FUTURE_API_LEVEL, MultiplyDefinedSymbolError, SymbolFileParser + + +ROOT_ELEMENT_TAG = 'ndk-library' +SYMBOL_ELEMENT_TAG = 'symbol' +ARCHITECTURE_ATTRIBUTE_KEY = 'arch' +DEPRECATED_ATTRIBUTE_KEY = 'is_deprecated' +PLATFORM_ATTRIBUTE_KEY = 'is_platform' +NAME_ATTRIBUTE_KEY = 'name' +VARIABLE_TAG = 'var' +EXPOSED_TARGET_TAGS = ( + 'vndk', + 'apex', + 'llndk', +) +API_LEVEL_TAG_PREFIXES = ( + 'introduced=', + 'introduced-', +) + + +def parse_tags(tags): + """Parses tags and save needed tags in the created attributes. + + Return attributes dictionary. + """ + attributes = {} + arch = [] + for tag in tags: + if tag.startswith(tuple(API_LEVEL_TAG_PREFIXES)): + key, _, value = tag.partition('=') + attributes.update({key: value}) + elif tag in ALL_ARCHITECTURES: + arch.append(tag) + elif tag in EXPOSED_TARGET_TAGS: + attributes.update({tag: 'True'}) + attributes.update({ARCHITECTURE_ATTRIBUTE_KEY: ','.join(arch)}) + return attributes + + +class XmlGenerator(object): + """Output generator that writes parsed symbol file to a xml file.""" + def __init__(self, output_file): + self.output_file = output_file + + def convertToXml(self, versions): + """Writes all symbol data to the output file.""" + root = Element(ROOT_ELEMENT_TAG) + for version in versions: + if VARIABLE_TAG in version.tags: + continue + version_attributes = parse_tags(version.tags) + _, _, postfix = version.name.partition('_') + is_platform = postfix == 'PRIVATE' or postfix == 'PLATFORM' + is_deprecated = postfix == 'DEPRECATED' + version_attributes.update({PLATFORM_ATTRIBUTE_KEY: str(is_platform)}) + version_attributes.update({DEPRECATED_ATTRIBUTE_KEY: str(is_deprecated)}) + for symbol in version.symbols: + if VARIABLE_TAG in symbol.tags: + continue + attributes = {NAME_ATTRIBUTE_KEY: symbol.name} + attributes.update(version_attributes) + # If same version tags already exist, it will be overwrite here. + attributes.update(parse_tags(symbol.tags)) + SubElement(root, SYMBOL_ELEMENT_TAG, attributes) + return root + + def write_xml_to_file(self, root): + """Write xml element root to output_file.""" + parsed_data = tostring(root) + output_file = open(self.output_file, "wb") + output_file.write(parsed_data) + + def write(self, versions): + root = self.convertToXml(versions) + self.write_xml_to_file(root) + + +def parse_args(): + """Parses and returns command line arguments.""" + parser = argparse.ArgumentParser() + + parser.add_argument('symbol_file', type=os.path.realpath, help='Path to symbol file.') + parser.add_argument( + 'output_file', type=os.path.realpath, + help='The output parsed api coverage file.') + parser.add_argument( + '--api-map', type=os.path.realpath, required=True, + help='Path to the API level map JSON file.') + return parser.parse_args() + + +def main(): + """Program entry point.""" + args = parse_args() + + with open(args.api_map) as map_file: + api_map = json.load(map_file) + + with open(args.symbol_file) as symbol_file: + try: + versions = SymbolFileParser(symbol_file, api_map, "", FUTURE_API_LEVEL, + True, True).parse() + except MultiplyDefinedSymbolError as ex: + sys.exit('{}: error: {}'.format(args.symbol_file, ex)) + + generator = XmlGenerator(args.output_file) + generator.write(versions) + +if __name__ == '__main__': + main() diff --git a/cc/test_gen_stub_libs.py b/cc/scriptlib/test_gen_stub_libs.py index 0b45e7110..0b45e7110 100755 --- a/cc/test_gen_stub_libs.py +++ b/cc/scriptlib/test_gen_stub_libs.py diff --git a/cc/scriptlib/test_ndk_api_coverage_parser.py b/cc/scriptlib/test_ndk_api_coverage_parser.py new file mode 100644 index 000000000..a3c9b708c --- /dev/null +++ b/cc/scriptlib/test_ndk_api_coverage_parser.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 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. +# +"""Tests for ndk_api_coverage_parser.py.""" +import io +import textwrap +import unittest + +from xml.etree.ElementTree import tostring +from gen_stub_libs import FUTURE_API_LEVEL, SymbolFileParser +import ndk_api_coverage_parser as nparser + + +# pylint: disable=missing-docstring + + +class ApiCoverageSymbolFileParserTest(unittest.TestCase): + def test_parse(self): + input_file = io.StringIO(textwrap.dedent(u"""\ + LIBLOG { # introduced-arm64=24 introduced-x86=24 introduced-x86_64=24 + global: + android_name_to_log_id; # apex llndk introduced=23 + android_log_id_to_name; # llndk arm + __android_log_assert; # introduced-x86=23 + __android_log_buf_print; # var + __android_log_buf_write; + local: + *; + }; + + LIBLOG_PLATFORM { + android_fdtrack; # llndk + android_net; # introduced=23 + }; + + LIBLOG_FOO { # var + android_var; + }; + """)) + parser = SymbolFileParser(input_file, {}, "", FUTURE_API_LEVEL, True, True) + generator = nparser.XmlGenerator(io.StringIO()) + result = tostring(generator.convertToXml(parser.parse())).decode() + expected = '<ndk-library><symbol apex="True" arch="" introduced="23" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_name_to_log_id" /><symbol arch="arm" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_log_id_to_name" /><symbol arch="" introduced-arm64="24" introduced-x86="23" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_assert" /><symbol arch="" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_buf_write" /><symbol arch="" is_deprecated="False" is_platform="True" llndk="True" name="android_fdtrack" /><symbol arch="" introduced="23" is_deprecated="False" is_platform="True" name="android_net" /></ndk-library>' + self.assertEqual(expected, result) + + +def main(): + suite = unittest.TestLoader().loadTestsFromName(__name__) + unittest.TextTestRunner(verbosity=3).run(suite) + + +if __name__ == '__main__': + main() @@ -43,6 +43,7 @@ func sdkMutator(ctx android.BottomUpMutatorContext) { if ctx.Config().UnbundledBuild() { modules[0].(*Module).Properties.HideFromMake = true + modules[0].(*Module).Properties.PreventInstall = true } else { modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true modules[1].(*Module).Properties.PreventInstall = true |