Make use of meta/platforms.json in ndk-build.
Test: nose2 build
Test: ./checkbuild.py && ./run_tests.py
Bug: None
Change-Id: Ie97f3fae5a9cafcd30c223d312bc29d24cd1d2c2
diff --git a/build/core/init.mk b/build/core/init.mk
index 827cc46..11736b9 100644
--- a/build/core/init.mk
+++ b/build/core/init.mk
@@ -449,23 +449,6 @@
$(eval include $(BUILD_SYSTEM)/add-platform.mk)\
)
-# we're going to find the maximum platform number of the form android-<number>
-# ignore others, which could correspond to special and experimental cases
-NDK_ALL_PLATFORM_LEVELS := $(filter android-%,$(NDK_ALL_PLATFORMS))
-NDK_ALL_PLATFORM_LEVELS := $(patsubst android-%,%,$(NDK_ALL_PLATFORM_LEVELS))
-$(call ndk_log,Found stable platform levels: $(NDK_ALL_PLATFORM_LEVELS))
-
-NDK_MIN_PLATFORM_LEVEL := 16
-NDK_MIN_PLATFORM := android-$(NDK_MIN_PLATFORM_LEVEL)
-
-NDK_MAX_PLATFORM_LEVEL := 3
-$(foreach level,$(NDK_ALL_PLATFORM_LEVELS),\
- $(eval NDK_MAX_PLATFORM_LEVEL := $$(call max,$$(NDK_MAX_PLATFORM_LEVEL),$$(level)))\
-)
-NDK_MAX_PLATFORM := android-$(NDK_MAX_PLATFORM_LEVEL)
-
-$(call ndk_log,Found max platform level: $(NDK_MAX_PLATFORM_LEVEL))
-
# Allow the user to point at an alternate location for the toolchains. This is
# particularly helpful if we want to use prebuilt toolchains for building an NDK
# module. Specifically, we use this to build libc++ using ndk-build instead of
@@ -494,13 +477,25 @@
# the build script to include in each toolchain config.mk
ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
-# ABI information is kept in meta/abis.json so it can be shared among multiple
-# build systems. Use Python to convert the JSON into make, replace the newlines
-# as necessary (make helpfully turns newlines into spaces for us...
-# https://www.gnu.org/software/make/manual/html_node/Shell-Function.html) and
-# eval the result.
-$(eval $(subst %NEWLINE%,$(newline),$(shell $(HOST_PYTHON) \
- $(BUILD_PY)/import_abi_metadata.py $(NDK_ROOT)/meta/abis.json)))
+# Invokes a Python script that is expected to return make code and evaluates it.
+#
+# The Python script itself must use the string '%NEWLINE%' in place of actual
+# newlines because make helpfully turns newlines from $(shell) into spaces for
+# us (https://www.gnu.org/software/make/manual/html_node/Shell-Function.html).
+#
+# Args:
+# 1: Path to the script to be executed.
+# 2: Argument list.
+eval_python = \
+ $(eval $(subst %NEWLINE%,$(newline),$(shell $(HOST_PYTHON) $1 $2)))
+
+# NDK configuration metadata in JSON files in $NDK/meta so it can be shared
+# among multiple build systems. Delegate to Python rather than write a JSON
+# parser in make...
+$(call eval_python,\
+ $(BUILD_PY)/import_abi_metadata.py,$(NDK_ROOT)/meta/abis.json)
+$(call eval_python,\
+ $(BUILD_PY)/import_platforms_metadata.py,$(NDK_ROOT)/meta/platforms.json)
NDK_KNOWN_DEVICE_ABIS := $(NDK_KNOWN_DEVICE_ABI64S) $(NDK_KNOWN_DEVICE_ABI32S)
@@ -508,6 +503,11 @@
NDK_APP_ABI_ALL32_EXPANDED := $(NDK_KNOWN_DEVICE_ABI32S)
NDK_APP_ABI_ALL64_EXPANDED := $(NDK_KNOWN_DEVICE_ABI64S)
+NDK_MIN_PLATFORM := android-$(NDK_MIN_PLATFORM_LEVEL)
+NDK_MAX_PLATFORM := android-$(NDK_MAX_PLATFORM_LEVEL)
+
+$(call ndk_log,Found max platform level: $(NDK_MAX_PLATFORM_LEVEL))
+
# the list of all toolchains in this NDK
NDK_ALL_TOOLCHAINS :=
NDK_ALL_ABIS :=
diff --git a/build/core/setup-app-platform.mk b/build/core/setup-app-platform.mk
index 9a1fa06..9326f97 100644
--- a/build/core/setup-app-platform.mk
+++ b/build/core/setup-app-platform.mk
@@ -53,52 +53,22 @@
endif
endif
+endif # APP_PROJECT_PATH == null
+
ifeq ($(APP_PLATFORM),latest)
$(call __ndk_info,Using latest available APP_PLATFORM: $(NDK_MAX_PLATFORM).)
override APP_PLATFORM := $(NDK_MAX_PLATFORM)
endif
-# Handle any platform codenames.
-ifeq ($(APP_PLATFORM),android-I)
- override APP_PLATFORM := android-14
-else ifeq ($(APP_PLATFORM),android-J)
- override APP_PLATFORM := android-16
-else ifeq ($(APP_PLATFORM),android-J-MR1)
- override APP_PLATFORM := android-17
-else ifeq ($(APP_PLATFORM),android-J-MR2)
- override APP_PLATFORM := android-18
-else ifeq ($(APP_PLATFORM),android-K)
- override APP_PLATFORM := android-19
-else ifeq ($(APP_PLATFORM),android-L)
- override APP_PLATFORM := android-21
-else ifeq ($(APP_PLATFORM),android-L-MR1)
- override APP_PLATFORM := android-22
-else ifeq ($(APP_PLATFORM),android-M)
- override APP_PLATFORM := android-23
-else ifeq ($(APP_PLATFORM),android-N)
- override APP_PLATFORM := android-24
-else ifeq ($(APP_PLATFORM),android-N-MR1)
- override APP_PLATFORM := android-25
-else ifeq ($(APP_PLATFORM),android-O)
- override APP_PLATFORM := android-26
-else ifeq ($(APP_PLATFORM),android-O-MR1)
- override APP_PLATFORM := android-27
-else ifeq ($(APP_PLATFORM),android-P)
- override APP_PLATFORM := android-28
-endif
-
-endif # APP_PROJECT_PATH == null
-
-# Though the platform emits library directories for every API level, the
-# deprecated headers have gaps, and we only end up shipping libraries that match
-# a directory for which we actually have deprecated headers. We'll need to fix
-# this soon since we'll be adding O APIs to only the new headers, but for now
-# just preserve the old behavior.
+# Aliases defined by meta/platforms.json include codename aliases for platform
+# API levels as well as cover any gaps in platforms that may not have had NDK
+# APIs.
APP_PLATFORM_LEVEL := $(strip $(subst android-,,$(APP_PLATFORM)))
-ifneq (,$(filter 20,$(APP_PLATFORM_LEVEL)))
- override APP_PLATFORM := android-19
-else ifneq (,$(filter 25,$(APP_PLATFORM_LEVEL)))
- override APP_PLATFORM := android-24
+ifdef NDK_PLATFORM_ALIAS_$(APP_PLATFORM_LEVEL)
+ _alias_target := $(NDK_PLATFORM_ALIAS_$(APP_PLATFORM_LEVEL))
+ $(call __ndk_info,$(APP_PLATFORM) is an alias for $(_alias_target). \
+ Adjusting APP_PLATFORM to match.)
+ override APP_PLATFORM := $(_alias_target)
endif
# For APP_PLATFORM values set below the minimum supported version, we could
diff --git a/build/import_abi_metadata.py b/build/import_abi_metadata.py
index 61fdffe..7ca4e30 100644
--- a/build/import_abi_metadata.py
+++ b/build/import_abi_metadata.py
@@ -17,33 +17,7 @@
"""Generates Make-importable code from meta/abis.json."""
from __future__ import print_function
-import argparse
-import json
-import os
-
-
-NEWLINE = '%NEWLINE%'
-
-
-def parse_args():
- parser = argparse.ArgumentParser()
-
- parser.add_argument(
- 'abis_file', metavar='ABIS_FILE', type=os.path.abspath,
- help='Path to the abis.json file.')
-
- return parser.parse_args()
-
-
-def generate_make_vars(abi_vars):
- lines = []
- for var, value in abi_vars.items():
- lines.append('{} := {}'.format(var, value))
- # https://www.gnu.org/software/make/manual/html_node/Shell-Function.html
- # Make's $(shell) function replaces real newlines with spaces. Use
- # something we can easily identify that's unlikely to appear in a variable
- # so we can replace it in make.
- return NEWLINE.join(lines)
+import make # pylint: disable=relative-import
def metadata_to_make_vars(meta):
@@ -77,14 +51,5 @@
return abi_vars
-def main():
- args = parse_args()
- with open(args.abis_file) as abis_file:
- abis = json.load(abis_file)
-
- abi_vars = metadata_to_make_vars(abis)
- print(generate_make_vars(abi_vars))
-
-
if __name__ == '__main__':
- main()
+ make.metadata_to_make(metadata_to_make_vars)
diff --git a/build/import_platforms_metadata.py b/build/import_platforms_metadata.py
new file mode 100644
index 0000000..2c2aa85
--- /dev/null
+++ b/build/import_platforms_metadata.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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 Make-importable code from meta/platforms.json."""
+from __future__ import print_function
+
+import make # pylint: disable=relative-import
+
+
+def metadata_to_make_vars(meta):
+ min_api = meta['min']
+ max_api = meta['max']
+
+ make_vars = {
+ 'NDK_MIN_PLATFORM_LEVEL': min_api,
+ 'NDK_MAX_PLATFORM_LEVEL': max_api,
+ }
+
+ for src, dst in meta['aliases'].items():
+ name = 'NDK_PLATFORM_ALIAS_{}'.format(src)
+ value = 'android-{}'.format(dst)
+ make_vars[name] = value
+
+ return make_vars
+
+
+if __name__ == '__main__':
+ make.metadata_to_make(metadata_to_make_vars)
diff --git a/build/make.py b/build/make.py
new file mode 100644
index 0000000..017d946
--- /dev/null
+++ b/build/make.py
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2018 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.
+#
+"""APIs for interfacing with make."""
+from __future__ import absolute_import
+from __future__ import print_function
+
+import argparse
+import json
+import os
+
+
+NEWLINE = '%NEWLINE%'
+
+
+def generate_make_vars(abi_vars):
+ lines = []
+ for var, value in abi_vars.items():
+ lines.append('{} := {}'.format(var, value))
+ # https://www.gnu.org/software/make/manual/html_node/Shell-Function.html
+ # Make's $(shell) function replaces real newlines with spaces. Use
+ # something we can easily identify that's unlikely to appear in a variable
+ # so we can replace it in make.
+ return NEWLINE.join(lines)
+
+
+def metadata_to_make(conversion_func):
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument(
+ 'metadata_file', metavar='METADATA_FILE', type=os.path.abspath,
+ help='Path to the metadata JSON file.')
+
+ args = parser.parse_args()
+ with open(args.metadata_file) as metadata_file:
+ metadata = json.load(metadata_file)
+
+ metadata_vars = conversion_func(metadata)
+ print(generate_make_vars(metadata_vars))
diff --git a/build/test_import_abi_metadata.py b/build/test_import_abi_metadata.py
index f82b0cb..b33b203 100644
--- a/build/test_import_abi_metadata.py
+++ b/build/test_import_abi_metadata.py
@@ -23,17 +23,6 @@
class ImportAbiMetadataTest(unittest.TestCase):
- def test_generate_make_vars(self):
- self.assertEqual(
- 'foo := bar',
- build.import_abi_metadata.generate_make_vars(
- {'foo': 'bar'}))
- self.assertEqual(
- build.import_abi_metadata.NEWLINE.join(
- ['foo := bar', 'baz := qux']),
- build.import_abi_metadata.generate_make_vars(
- {'foo': 'bar', 'baz': 'qux'}))
-
def test_metadata_to_make_vars(self):
make_vars = build.import_abi_metadata.metadata_to_make_vars({
'armeabi': {
diff --git a/build/test_import_platforms_metadata.py b/build/test_import_platforms_metadata.py
new file mode 100644
index 0000000..2c37b36
--- /dev/null
+++ b/build/test_import_platforms_metadata.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 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 import_abi_metadata.py."""
+from __future__ import print_function
+
+import unittest
+
+import build.import_platforms_metadata
+
+
+class ImportPlatformsMetadataTest(unittest.TestCase):
+ def test_metadata_to_make_vars(self):
+ make_vars = build.import_platforms_metadata.metadata_to_make_vars({
+ 'min': 16,
+ 'max': 28,
+ 'aliases': {
+ '20': 19,
+ 'J': 16,
+ 'O': 26,
+ },
+ })
+
+ self.assertDictEqual({
+ 'NDK_MIN_PLATFORM_LEVEL': 16,
+ 'NDK_MAX_PLATFORM_LEVEL': 28,
+ 'NDK_PLATFORM_ALIAS_20': 'android-19',
+ 'NDK_PLATFORM_ALIAS_J': 'android-16',
+ 'NDK_PLATFORM_ALIAS_O': 'android-26',
+ }, make_vars)
diff --git a/build/test_make.py b/build/test_make.py
new file mode 100644
index 0000000..59bdc64
--- /dev/null
+++ b/build/test_make.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 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 build.make."""
+from __future__ import print_function
+
+import unittest
+
+import build.make
+
+
+class MakeVarsTest(unittest.TestCase):
+ def test_generate_make_vars(self):
+ self.assertEqual(
+ 'foo := bar',
+ build.make.generate_make_vars({'foo': 'bar'}))
+ self.assertEqual(
+ build.make.NEWLINE.join(['foo := bar', 'baz := qux']),
+ build.make.generate_make_vars({'foo': 'bar', 'baz': 'qux'}))