Merge "Merge cherrypicks of [1836175, 1836176, 1836177, 1836178, 1836179, 1836180, 1836181, 1836182, 1836183, 1836184, 1836185, 1836186, 1836187, 1836188, 1836189, 1836190, 1836195, 1836196] into ndk-release-r23" into ndk-release-r23
diff --git a/build/cmake/adjust_api_level.cmake b/build/cmake/adjust_api_level.cmake
new file mode 100644
index 0000000..780d76c
--- /dev/null
+++ b/build/cmake/adjust_api_level.cmake
@@ -0,0 +1,63 @@
+include(${CMAKE_ANDROID_NDK}/build/cmake/platforms.cmake)
+
+function(adjust_api_level api_level result_name)
+ # If no platform version was chosen by the user, default to the minimum
+ # version supported by this NDK.
+ if(NOT api_level)
+ message(STATUS
+ "ANDROID_PLATFORM not set. Defaulting to minimum supported version "
+ "${NDK_MIN_PLATFORM_LEVEL}.")
+
+ set(api_level "android-${NDK_MIN_PLATFORM_LEVEL}")
+ endif()
+
+ if(api_level STREQUAL "latest")
+ message(STATUS
+ "Using latest available ANDROID_PLATFORM: ${NDK_MAX_PLATFORM_LEVEL}.")
+ set(api_level "android-${NDK_MAX_PLATFORM_LEVEL}")
+ endif()
+
+ string(REPLACE "android-" "" result ${api_level})
+
+ # 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.
+ if(NOT "${NDK_PLATFORM_ALIAS_${result}}" STREQUAL "")
+ message(STATUS
+ "${api_level} is an alias for ${NDK_PLATFORM_ALIAS_${result}}. Adjusting "
+ "ANDROID_PLATFORM to match.")
+ set(api_level "${NDK_PLATFORM_ALIAS_${result}}")
+ string(REPLACE "android-" "" result ${api_level})
+ endif()
+
+ # Pull up to the minimum supported version if an old API level was requested.
+ if(result LESS NDK_MIN_PLATFORM_LEVEL)
+ message(STATUS
+ "${api_level} is unsupported. Using minimum supported version "
+ "${NDK_MIN_PLATFORM_LEVEL}.")
+ set(api_level "android-${NDK_MIN_PLATFORM_LEVEL}")
+ string(REPLACE "android-" "" result ${api_level})
+ endif()
+
+ # And for LP64 we need to pull up to 21. No diagnostic is provided here
+ # because minSdkVersion < 21 is valid for the project even though it may not
+ # be for this ABI.
+ if(ANDROID_ABI MATCHES "64(-v8a)?$" AND result LESS 21)
+ message(STATUS
+ "android-${result} is not supported for ${ANDROID_ABI}. Using minimum "
+ "supported LP64 version 21.")
+ set(api_level android-21)
+ set(result 21)
+ endif()
+
+ # ANDROID_PLATFORM beyond the maximum is an error. The correct way to specify
+ # the latest version is ANDROID_PLATFORM=latest.
+ if(result GREATER NDK_MAX_PLATFORM_LEVEL)
+ message(SEND_ERROR
+ "${api_level} is above the maximum supported version "
+ "${NDK_MAX_PLATFORM_LEVEL}. Choose a supported API level or set "
+ "ANDROID_PLATFORM to \"latest\".")
+ endif()
+
+ set(${result_name} ${result} PARENT_SCOPE)
+endfunction()
diff --git a/build/cmake/android-legacy.toolchain.cmake b/build/cmake/android-legacy.toolchain.cmake
index aac7750..b2fdd10 100644
--- a/build/cmake/android-legacy.toolchain.cmake
+++ b/build/cmake/android-legacy.toolchain.cmake
@@ -456,12 +456,6 @@
list(APPEND ANDROID_LINKER_FLAGS_EXE -Wl,--gc-sections)
# Debug and release flags.
-list(APPEND ANDROID_COMPILER_FLAGS_DEBUG -O0)
-if(ANDROID_ABI MATCHES "^armeabi" AND ANDROID_ARM_MODE STREQUAL thumb)
- list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -Oz)
-else()
- list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -O2)
-endif()
list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -DNDEBUG)
if(ANDROID_TOOLCHAIN STREQUAL clang)
list(APPEND ANDROID_COMPILER_FLAGS_DEBUG -fno-limit-debug-info)
diff --git a/build/cmake/android.toolchain.cmake b/build/cmake/android.toolchain.cmake
index 2467cad..b01340e 100644
--- a/build/cmake/android.toolchain.cmake
+++ b/build/cmake/android.toolchain.cmake
@@ -166,34 +166,8 @@
"https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md.")
endif()
-include(${CMAKE_ANDROID_NDK}/build/cmake/platforms.cmake)
-
-if(ANDROID_NATIVE_API_LEVEL AND NOT ANDROID_PLATFORM)
- if(ANDROID_NATIVE_API_LEVEL MATCHES "^android-[0-9]+$")
- set(ANDROID_PLATFORM ${ANDROID_NATIVE_API_LEVEL})
- elseif(ANDROID_NATIVE_API_LEVEL MATCHES "^[0-9]+$")
- set(ANDROID_PLATFORM android-${ANDROID_NATIVE_API_LEVEL})
- endif()
-endif()
-if(NOT CMAKE_SYSTEM_VERSION AND ANDROID_PLATFORM)
- if(ANDROID_PLATFORM STREQUAL "latest")
- message(STATUS
- "Using latest available ANDROID_PLATFORM: ${NDK_MAX_PLATFORM_LEVEL}.")
- set(CMAKE_SYSTEM_VERSION "${NDK_MAX_PLATFORM_LEVEL}")
- else()
- string(REPLACE "android-" "" CMAKE_SYSTEM_VERSION ${ANDROID_PLATFORM})
- # 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.
- if(NOT "${NDK_PLATFORM_ALIAS_${CMAKE_SYSTEM_VERSION}}" STREQUAL "")
- message(STATUS "\
- ${CMAKE_SYSTEM_VERSION} is an alias for \
- ${NDK_PLATFORM_ALIAS_${CMAKE_SYSTEM_VERSION}}.")
- string(REPLACE "android-" "" CMAKE_SYSTEM_VERSION
- "${NDK_PLATFORM_ALIAS_${CMAKE_SYSTEM_VERSION}}")
- endif()
- endif()
-endif()
+include(${CMAKE_ANDROID_NDK}/build/cmake/adjust_api_level.cmake)
+adjust_api_level("${ANDROID_PLATFORM}" CMAKE_SYSTEM_VERSION)
if(NOT DEFINED CMAKE_ANDROID_STL_TYPE AND DEFINED ANDROID_STL)
set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL})
@@ -265,6 +239,7 @@
ANDROID_PLATFORM
ANDROID_STL
ANDROID_TOOLCHAIN
+ ANDROID_USE_LEGACY_TOOLCHAIN_FILE
)
if(DEFINED ANDROID_NO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS)
@@ -278,11 +253,6 @@
set(ANDROID_ALLOW_UNDEFINED_SYMBOLS "${ANDROID_SO_UNDEFINED}")
endif()
-# https://github.com/android/ndk/issues/133
-if(CMAKE_ANDROID_ARCH_ABI MATCHES "^armeabi" AND NOT CMAKE_ANDROID_ARM_MODE)
- string(APPEND _ANDROID_NDK_INIT_CFLAGS_RELEASE " -Oz")
-endif()
-
# Exports compatible variables defined in exports.cmake.
set(_ANDROID_EXPORT_COMPATIBILITY_VARIABLES TRUE)
diff --git a/build/cmake/hooks/pre/Determine-Compiler.cmake b/build/cmake/hooks/pre/Determine-Compiler.cmake
index b8ed1bf..ef0228f 100644
--- a/build/cmake/hooks/pre/Determine-Compiler.cmake
+++ b/build/cmake/hooks/pre/Determine-Compiler.cmake
@@ -15,3 +15,26 @@
# This is a hook file that will be included by cmake at the beginning of
# Modules/Platform/Android/Determine-Compiler.cmake.
+# Skip hook for the legacy toolchain workflow.
+if(CMAKE_SYSTEM_VERSION EQUAL 1)
+ return()
+endif()
+
+# If we don't explicitly set the target CMake will ID the compiler using the
+# default target, causing MINGW to be defined when a Windows host is used.
+# https://github.com/android/ndk/issues/1581
+# https://gitlab.kitware.com/cmake/cmake/-/issues/22647
+if(CMAKE_ANDROID_ARCH_ABI STREQUAL armeabi-v7a)
+ set(ANDROID_LLVM_TRIPLE armv7-none-linux-androideabi)
+elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL arm64-v8a)
+ set(ANDROID_LLVM_TRIPLE aarch64-none-linux-android)
+elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL x86)
+ set(ANDROID_LLVM_TRIPLE i686-none-linux-android)
+elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL x86_64)
+ set(ANDROID_LLVM_TRIPLE x86_64-none-linux-android)
+else()
+ message(FATAL_ERROR "Invalid Android ABI: ${ANDROID_ABI}.")
+endif()
+set(CMAKE_ASM_COMPILER_TARGET "${ANDROID_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}")
+set(CMAKE_C_COMPILER_TARGET "${ANDROID_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}")
+set(CMAKE_CXX_COMPILER_TARGET "${ANDROID_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}")
diff --git a/docs/changelogs/Changelog-r23.md b/docs/changelogs/Changelog-r23.md
index 3fca9f4..7df6a5a 100644
--- a/docs/changelogs/Changelog-r23.md
+++ b/docs/changelogs/Changelog-r23.md
@@ -28,6 +28,51 @@
[Clang Migration Notes]: ClangMigration.md
+## r23b
+
+* Update LLVM to clang-r416183c1, based on LLVM 12 development.
+ * [Issue 1540]: Fixed compiler crash when using coroutines.
+ * [Issue 1544]: Now uses universal binaries for M1 Macs.
+ * [Issue 1551]: Prevent each translation unit from receiving its own copy of
+ emulated thread-local global variables.
+ * [Issue 1555]: Fixed compiler crash for armeabi-v7a.
+* [Issue 1492]: ndk-build.cmd: Stop using make's `-O` (`--output-sync`) flag on
+ Windows to avoid `fcntl(): Bad file descriptor` error.
+* [Issue 1553]: Updated sysroot to latest Android 12.
+* [Issue 1569]: Fixed `-fno-integrated-as` not being able to find the assembler.
+* CMake changes:
+ * [Issue 1536]: Make optimization flags used with CMake more consistent.
+ Historically thumb release builds used `-Oz`, but AGP switched to using
+ `RelWithDebInfo` for release builds in the latest release which was not
+ using `-Oz`. To reduce per-arch differences and behavior differences
+ compared to CMake's defaults, `-Oz` use was removed. You may see code size
+ increases for armeabi-v7a due to this, but also increased optimization. To
+ restore the prior behavior, add `-Oz` to your cflags.
+ * [Issue 1560]: Fixed pull-up of unsupported API levels when using the new
+ CMake toolchain file. This affects CMake 3.21 and
+ `ANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON` use cases, and was the common case
+ for AGP users with a `minSdkVersion` below 21.
+ * [Issue 1573]: Fixed `ANDROID_USE_LEGACY_TOOLCHAIN_FILE` not being obeyed
+ during CMake try-compile.
+ * [Issue 1581]: Added workaround for [CMake Issue 22647], which was causing
+ `MINGW` to be incorrectly defined by CMake when building for Android on a
+ Windows host. This only affected those using the Android toolchain file when
+ CMake 3.21 or newer was used. This likely was not a regression for users not
+ using the Android toolchain. The change will fix both use cases.
+
+[CMake Issue 22647]: https://gitlab.kitware.com/cmake/cmake/-/issues/22647
+[Issue 1492]: https://github.com/android/ndk/issues/1492
+[Issue 1536]: https://github.com/android/ndk/issues/1536
+[Issue 1540]: https://github.com/android/ndk/issues/1540
+[Issue 1544]: https://github.com/android/ndk/issues/1544
+[Issue 1551]: https://github.com/android/ndk/issues/1551
+[Issue 1553]: https://github.com/android/ndk/issues/1553
+[Issue 1555]: https://github.com/android/ndk/issues/1555
+[Issue 1560]: https://github.com/android/ndk/issues/1560
+[Issue 1569]: https://github.com/android/ndk/issues/1569
+[Issue 1573]: https://github.com/android/ndk/issues/1573
+[Issue 1581]: https://github.com/android/ndk/issues/1581
+
## Changes
* Includes Android 12 APIs.
diff --git a/ndk/checkbuild.py b/ndk/checkbuild.py
index 25360cf..b32d7a3 100755
--- a/ndk/checkbuild.py
+++ b/ndk/checkbuild.py
@@ -400,12 +400,12 @@
# https://github.com/android-ndk/ndk/issues/564#issuecomment-342307128
shutil.rmtree(install_path / 'include')
- if not self.host.is_windows:
- # The Linux and Darwin toolchains have Python compiler wrappers
- # that currently do nothing. We don't have these for Windows and we
- # want to make sure Windows behavior is consistent with the other
- # platforms, so just unwrap the compilers until they do something
- # useful and are available on Windows.
+ if self.host is Host.Linux:
+ # The Linux toolchain wraps the compiler to inject some behavior
+ # for the platform. They aren't used for every platform and we want
+ # consistent behavior across platforms, and we also don't want the
+ # extra cost they incur (fork/exec is cheap, but CreateProcess is
+ # expensive), so remove them.
(bin_dir / 'clang++.real').unlink()
(bin_dir / 'clang++').unlink()
(bin_dir / 'clang-cl').unlink()
diff --git a/ndk/cmake.py b/ndk/cmake.py
index fd8e71c..7290de9 100644
--- a/ndk/cmake.py
+++ b/ndk/cmake.py
@@ -15,6 +15,7 @@
#
"""APIs for dealing with cmake scripts."""
+from functools import cached_property
import os
from pathlib import Path
import pprint
@@ -23,7 +24,7 @@
import subprocess
from typing import Dict, List, Optional
-from ndk.hosts import Host, get_default_host
+from ndk.hosts import Host
import ndk.paths
import ndk.toolchains
@@ -40,6 +41,18 @@
}
+def find_cmake() -> Path:
+ host = Host.current()
+ return (ndk.paths.ANDROID_DIR / 'prebuilts' / 'cmake' / host.platform_tag /
+ 'bin' / 'cmake').with_suffix(host.exe_suffix)
+
+
+def find_ninja() -> Path:
+ host = Host.current()
+ return (ndk.paths.ANDROID_DIR / 'prebuilts' / 'ninja' / host.platform_tag /
+ 'ninja').with_suffix(host.exe_suffix)
+
+
class CMakeBuilder:
"""Builder for an cmake project."""
@@ -116,20 +129,20 @@
subprocess.check_call(cmd, env=subproc_env, cwd=self.working_directory)
- @property
+ @cached_property
def _cmake(self) -> Path:
- return (ndk.paths.ANDROID_DIR / 'prebuilts' / 'cmake' /
- (get_default_host().value + '-x86') / 'bin' / 'cmake')
+ return find_cmake()
- @property
+ @cached_property
def _ninja(self) -> Path:
- return (ndk.paths.ANDROID_DIR / 'prebuilts' / 'ninja' /
- (get_default_host().value + '-x86') / 'ninja')
+ return find_ninja()
@property
def _ctest(self) -> Path:
+ host = Host.current()
return (ndk.paths.ANDROID_DIR / 'prebuilts' / 'cmake' /
- (get_default_host().value + '-x86') / 'bin' / 'ctest')
+ host.platform_tag / 'bin' / 'ctest').with_suffix(
+ host.exe_suffix)
@property
def cmake_defines(self) -> Dict[str, str]:
diff --git a/ndk/config.py b/ndk/config.py
index b7e1179..6066c5a 100644
--- a/ndk/config.py
+++ b/ndk/config.py
@@ -2,7 +2,7 @@
major = 23
-hotfix = 0
+hotfix = 1
hotfix_str = chr(ord('a') + hotfix) if hotfix else ''
beta = 0
beta_str = '-beta{}'.format(beta) if beta > 0 else ''
diff --git a/ndk/hosts.py b/ndk/hosts.py
index e313e5b..ad00324 100644
--- a/ndk/hosts.py
+++ b/ndk/hosts.py
@@ -39,6 +39,26 @@
def tag(self) -> str:
return host_to_tag(self)
+ @property
+ def platform_tag(self) -> str:
+ """Returns the tag used for this host in the platform tree.
+
+ The NDK uses full architecture names like x86_64, whereas the platform
+ has always used just x86, even for the 64-bit tools.
+ """
+ if self is Host.Windows64:
+ # The value for this is still "windows64" since we historically
+ # supported 32-bit Windows. Can clean this up if we ever fix the
+ # value of the enum.
+ return 'windows-x86'
+ return f'{self.value}-x86'
+
+ @property
+ def exe_suffix(self) -> str:
+ if self is Host.Windows64:
+ return '.exe'
+ return ''
+
@classmethod
def current(cls) -> Host:
"""Returns the Host matching the current machine."""
diff --git a/ndk/test/scanner.py b/ndk/test/scanner.py
index 47c3ff9..8870db8 100644
--- a/ndk/test/scanner.py
+++ b/ndk/test/scanner.py
@@ -95,7 +95,6 @@
return [
PythonBuildTest(name, path, config, self.ndk_path)
for config in self.build_configurations
- if config.toolchain_file == CMakeToolchainFile.Default
]
def make_ndk_build_tests(self, path: str, name: str) -> List[Test]:
diff --git a/ndk/test/types.py b/ndk/test/types.py
index 22a5e08..23e22ab 100644
--- a/ndk/test/types.py
+++ b/ndk/test/types.py
@@ -32,11 +32,11 @@
from ndk.abis import Abi
import ndk.ansi
+from ndk.cmake import find_cmake, find_ninja
import ndk.ext.os
import ndk.ext.shutil
import ndk.ext.subprocess
import ndk.hosts
-from ndk.hosts import Host
import ndk.ndkbuild
import ndk.paths
from ndk.test.config import LibcxxTestConfig, TestConfig
@@ -185,9 +185,8 @@
_prep_build_dir(self.test_dir, build_dir)
with ndk.ext.os.cd(build_dir):
module = imp.load_source('test', 'test.py')
- assert self.api is not None
success, failure_message = module.run_test( # type: ignore
- self.ndk_path, self.abi, self.api)
+ self.ndk_path, self.config)
if success:
return Success(self), []
else:
@@ -384,23 +383,8 @@
use_legacy_toolchain_file: bool) -> TestResult:
_prep_build_dir(test_dir, obj_dir)
- # Add prebuilts to PATH.
- host = ndk.hosts.get_default_host()
- if host == Host.Windows64:
- # The value for this is still "windows64" since we historically
- # supported 32-bit Windows. Can clean this up if we ever fix the value
- # of the enum.
- prebuilts_host_tag = 'windows-x86'
- else:
- prebuilts_host_tag = ndk.hosts.get_default_host().value + '-x86'
- cmake_bin = ndk.paths.android_path(
- 'prebuilts', 'cmake', prebuilts_host_tag, 'bin', 'cmake')
- ninja_bin = ndk.paths.android_path(
- 'prebuilts', 'ninja', prebuilts_host_tag, 'ninja')
-
- if host == Host.Windows64:
- cmake_bin += '.exe'
- ninja_bin += '.exe'
+ cmake_bin = find_cmake()
+ ninja_bin = find_ninja()
toolchain_file = os.path.join(ndk_path, 'build', 'cmake',
'android.toolchain.cmake')
@@ -423,11 +407,11 @@
else:
args.append('-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF')
rc, out = ndk.ext.subprocess.call_output(
- [cmake_bin] + cmake_flags + args, encoding='utf-8')
+ [str(cmake_bin)] + cmake_flags + args, encoding='utf-8')
if rc != 0:
return Failure(test, out)
rc, out = ndk.ext.subprocess.call_output(
- [cmake_bin, '--build', abi_obj_dir, '--'] + _get_jobs_args(),
+ [str(cmake_bin), '--build', abi_obj_dir, '--'] + _get_jobs_args(),
encoding='utf-8')
if rc != 0:
return Failure(test, out)
diff --git a/ndk/testing/flag_verifier.py b/ndk/testing/flag_verifier.py
index 68acf08..82ed7e3 100644
--- a/ndk/testing/flag_verifier.py
+++ b/ndk/testing/flag_verifier.py
@@ -14,14 +14,16 @@
# limitations under the License.
#
"""Tools for verifying the presence or absence of flags in builds."""
+from __future__ import annotations
+
from pathlib import Path
import shutil
import subprocess
-from typing import List, Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
from ndk.hosts import Host
import ndk.paths
+from ndk.test.spec import BuildConfiguration, CMakeToolchainFile
class FlagVerifierResult:
@@ -34,7 +36,7 @@
"""Returns True if verification failed."""
raise NotImplementedError
- def make_test_result_tuple(self) -> Tuple[bool, Optional[str]]:
+ def make_test_result_tuple(self) -> tuple[bool, Optional[str]]:
"""Creates a test result tuple in the format expect by run_test."""
return not self.failed(), self.error_message
@@ -60,14 +62,22 @@
class FlagVerifier:
"""Verifies that a build receives the expected flags."""
- def __init__(self, project: Path, ndk_path: Path, abi: Abi,
- api: int) -> None:
+ def __init__(self, project: Path, ndk_path: Path,
+ config: BuildConfiguration) -> None:
self.project = project
self.ndk_path = ndk_path
- self.abi = abi
+ self.abi = config.abi
+ self.api = config.api
+ if config.toolchain_file is CMakeToolchainFile.Legacy:
+ self.toolchain_mode = 'ON'
+ else:
+ self.toolchain_mode = 'OFF'
+ self.expected_flags: list[str] = []
+ self.not_expected_flags: list[str] = []
+
+ def with_api(self, api: int) -> FlagVerifier:
self.api = api
- self.expected_flags: List[str] = []
- self.not_expected_flags: List[str] = []
+ return self
def expect_flag(self, flag: str) -> None:
"""Verify that the given string is present in the build output.
@@ -93,7 +103,7 @@
raise ValueError(f'Flag {flag} both expected and not expected')
self.not_expected_flags.append(flag)
- def _check_build(self, cmd: List[str]) -> FlagVerifierResult:
+ def _check_build(self, cmd: list[str]) -> FlagVerifierResult:
result = subprocess.run(cmd,
check=False,
stdout=subprocess.PIPE,
@@ -103,8 +113,8 @@
return FlagVerifierFailure(result.stdout)
words = result.stdout.split(' ')
- missing_flags: List[str] = []
- wrong_flags: List[str] = []
+ missing_flags: list[str] = []
+ wrong_flags: list[str] = []
for expected in self.expected_flags:
if expected not in words:
missing_flags.append(expected)
@@ -151,12 +161,17 @@
f'APP_PLATFORM=android-{self.api}',
])
- def verify_cmake(self) -> FlagVerifierResult:
+ def verify_cmake(
+ self,
+ cmake_flags: Optional[list[str]] = None) -> FlagVerifierResult:
"""Verifies that CMake behaves as specified.
Returns:
A FlagVerifierResult object describing the verification result.
"""
+ if cmake_flags is None:
+ cmake_flags = []
+
host = Host.current()
if host == Host.Windows64:
tag = 'windows-x86'
@@ -182,9 +197,10 @@
f'-DCMAKE_TOOLCHAIN_FILE={toolchain_file}',
f'-DANDROID_ABI={self.abi}',
f'-DANDROID_PLATFORM=android-{self.api}',
+ f'-DANDROID_USE_LEGACY_TOOLCHAIN_FILE={self.toolchain_mode}',
'-GNinja',
f'-DCMAKE_MAKE_PROGRAM={ninja}',
- ]
+ ] + cmake_flags
result = subprocess.run(cmd,
check=False,
stdout=subprocess.PIPE,
diff --git a/ndk/testing/standalone_toolchain.py b/ndk/testing/standalone_toolchain.py
index 88f24a8..5854600 100644
--- a/ndk/testing/standalone_toolchain.py
+++ b/ndk/testing/standalone_toolchain.py
@@ -18,16 +18,17 @@
import shutil
import subprocess
import tempfile
-from typing import Any, List, Tuple
+from typing import Any
import ndk.abis
+from ndk.test.spec import BuildConfiguration
def logger() -> logging.Logger:
return logging.getLogger(__name__)
-def call_output(cmd: List[str], *args: Any, **kwargs: Any) -> Tuple[int, Any]:
+def call_output(cmd: list[str], *args: Any, **kwargs: Any) -> tuple[int, Any]:
logger().info('COMMAND: %s', ' '.join(cmd))
kwargs.update({
'stdout': subprocess.PIPE,
@@ -38,15 +39,16 @@
return proc.returncode, out
-def make_standalone_toolchain(ndk_path: str, arch: str, api: int,
- extra_args: List[str],
- install_dir: str) -> Tuple[bool, str]:
+def make_standalone_toolchain(ndk_path: str, config: BuildConfiguration,
+ extra_args: list[str],
+ install_dir: str) -> tuple[bool, str]:
make_standalone_toolchain_path = os.path.join(
ndk_path, 'build/tools/make_standalone_toolchain.py')
+ arch = ndk.abis.abi_to_arch(config.abi)
cmd = [make_standalone_toolchain_path, '--force',
'--install-dir=' + install_dir, '--arch=' + arch,
- '--api={}'.format(api)] + extra_args
+ '--api={}'.format(config.api)] + extra_args
if os.name == 'nt':
# Windows doesn't process shebang lines, and we wouldn't be pointing at
@@ -67,7 +69,7 @@
def test_standalone_toolchain(install_dir: str, test_source: str,
- flags: List[str]) -> Tuple[bool, str]:
+ flags: list[str]) -> tuple[bool, str]:
compiler_name = 'clang++'
compiler = os.path.join(install_dir, 'bin', compiler_name)
@@ -81,14 +83,13 @@
return rc == 0, out.decode('utf-8')
-def run_test(ndk_path: str, abi: ndk.abis.Abi, api: int, test_source: str,
- extra_args: List[str], flags: List[str]) -> Tuple[bool, str]:
- arch = ndk.abis.abi_to_arch(abi)
+def run_test(ndk_path: str, config: BuildConfiguration, test_source: str,
+ extra_args: list[str], flags: list[str]) -> tuple[bool, str]:
install_dir = tempfile.mkdtemp()
try:
success, out = make_standalone_toolchain(
- ndk_path, arch, api, extra_args, install_dir)
+ ndk_path, config, extra_args, install_dir)
if not success:
return success, out
return test_standalone_toolchain(install_dir, test_source, flags)
diff --git a/ndk/toolchains.py b/ndk/toolchains.py
index 550533b..d5ea189 100644
--- a/ndk/toolchains.py
+++ b/ndk/toolchains.py
@@ -22,7 +22,7 @@
import ndk.paths
-CLANG_VERSION = 'clang-r416183b'
+CLANG_VERSION = 'clang-r416183c1'
HOST_TRIPLE_MAP = {
diff --git a/ndk/workqueue.py b/ndk/workqueue.py
index 82cade9..57aac48 100644
--- a/ndk/workqueue.py
+++ b/ndk/workqueue.py
@@ -47,7 +47,7 @@
if IS_WINDOWS:
- import ctypes
+ import ctypes.wintypes
ProcessGroup = Optional[ctypes.wintypes.HANDLE]
diff --git a/tests/build/NDK_ANALYZE/test.py b/tests/build/NDK_ANALYZE/test.py
index 54e8181..1113fbe 100644
--- a/tests/build/NDK_ANALYZE/test.py
+++ b/tests/build/NDK_ANALYZE/test.py
@@ -16,20 +16,19 @@
import os
import subprocess
import sys
-from typing import Tuple
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks ndk-build output for clang-tidy warnings."""
ndk_build = os.path.join(ndk_path, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
'NDK_ANALYZE=1',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
diff --git a/tests/build/build_id/test.py b/tests/build/build_id/test.py
index d49c4a3..bb6b43a 100644
--- a/tests/build/build_id/test.py
+++ b/tests/build/build_id/test.py
@@ -21,15 +21,16 @@
Studio.
"""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks correct --build-id use."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
verifier.expect_flag('-Wl,--build-id=sha1')
verifier.expect_not_flag('-Wl,--build-id')
return verifier.verify().make_test_result_tuple()
diff --git a/tests/build/clang_tidy/test.py b/tests/build/clang_tidy/test.py
index 6416bcc..888d0a1 100644
--- a/tests/build/clang_tidy/test.py
+++ b/tests/build/clang_tidy/test.py
@@ -17,20 +17,19 @@
import os
import subprocess
import sys
-from typing import Tuple
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks ndk-build V=1 output for clang-tidy warnings."""
ndk_build = os.path.join(ndk_path, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
'V=1',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
diff --git a/tests/build/cmake_api_pull_up/__init__.py b/tests/build/cmake_api_pull_up/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/cmake_api_pull_up/__init__.py
diff --git a/tests/build/cmake_api_pull_up/project/CMakeLists.txt b/tests/build/cmake_api_pull_up/project/CMakeLists.txt
new file mode 100644
index 0000000..ddcd353
--- /dev/null
+++ b/tests/build/cmake_api_pull_up/project/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.6)
+project(ApiLevelPullUpTest CXX)
+
+add_library(foo SHARED foo.cpp)
diff --git a/tests/build/cmake_api_pull_up/project/foo.cpp b/tests/build/cmake_api_pull_up/project/foo.cpp
new file mode 100644
index 0000000..b876b5c
--- /dev/null
+++ b/tests/build/cmake_api_pull_up/project/foo.cpp
@@ -0,0 +1,3 @@
+#if __ANDROID_API__ != 21
+#error API level was not pulled up to 21
+#endif
diff --git a/tests/build/cmake_api_pull_up/test.py b/tests/build/cmake_api_pull_up/test.py
new file mode 100644
index 0000000..c1c8be8
--- /dev/null
+++ b/tests/build/cmake_api_pull_up/test.py
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2021 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.
+#
+"""Check that pre-LP64 API levels are correctly pulled-up for CMake."""
+from pathlib import Path
+import subprocess
+
+from ndk.cmake import find_cmake, find_ninja
+from ndk.test.spec import BuildConfiguration, CMakeToolchainFile
+
+
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
+ """Check that pre-LP64 API levels are correctly pulled-up for CMake."""
+ cmake = find_cmake()
+ ninja = find_ninja()
+ toolchain_path = Path(ndk_path) / 'build/cmake/android.toolchain.cmake'
+ project_path = 'project'
+ if config.toolchain_file is CMakeToolchainFile.Legacy:
+ toolchain_mode = 'ON'
+ else:
+ toolchain_mode = 'OFF'
+ cmake_cmd = [
+ str(cmake),
+ f'-DCMAKE_TOOLCHAIN_FILE={toolchain_path}',
+ f'-DANDROID_ABI={config.abi}',
+ '-DANDROID_PLATFORM=android-19',
+ f'-DCMAKE_MAKE_PROGRAM={ninja}',
+ f'-DANDROID_USE_LEGACY_TOOLCHAIN_FILE={toolchain_mode}',
+ '-GNinja',
+ ]
+ result = subprocess.run(cmake_cmd,
+ check=False,
+ cwd=project_path,
+ capture_output=True,
+ text=True)
+ return result.returncode == 0, result.stdout
diff --git a/tests/build/cmake_api_pull_up/test_config.py b/tests/build/cmake_api_pull_up/test_config.py
new file mode 100644
index 0000000..aa58ee5
--- /dev/null
+++ b/tests/build/cmake_api_pull_up/test_config.py
@@ -0,0 +1,10 @@
+from typing import Optional
+
+from ndk.abis import LP32_ABIS
+from ndk.test.types import Test
+
+
+def build_unsupported(test: Test) -> Optional[str]:
+ if test.config.abi in LP32_ABIS:
+ return test.config.abi
+ return None
diff --git a/tests/build/cmake_default_flags/__init__.py b/tests/build/cmake_default_flags/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/cmake_default_flags/__init__.py
diff --git a/tests/build/cmake_default_flags/project/CMakeLists.txt b/tests/build/cmake_default_flags/project/CMakeLists.txt
new file mode 100644
index 0000000..4cf4562
--- /dev/null
+++ b/tests/build/cmake_default_flags/project/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.6)
+project(CMakeDefaultFlagsTest CXX)
+
+add_library(foo SHARED foo.cpp)
diff --git a/tests/build/cmake_default_flags/project/foo.cpp b/tests/build/cmake_default_flags/project/foo.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/cmake_default_flags/project/foo.cpp
diff --git a/tests/build/cmake_default_flags/test.py b/tests/build/cmake_default_flags/test.py
new file mode 100644
index 0000000..a7ead75
--- /dev/null
+++ b/tests/build/cmake_default_flags/test.py
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2021 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.
+#
+"""Check that the CMake toolchain uses the correct default flags."""
+from pathlib import Path
+from typing import Optional
+
+from ndk.test.spec import BuildConfiguration
+from ndk.testing.flag_verifier import FlagVerifier
+
+
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
+ """Check that the CMake toolchain uses the correct default flags.
+
+ Currently this only tests the optimization flags for RelWithDebInfo, but
+ it's probably worth expanding in the future.
+ """
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
+ verifier.expect_flag('-O2')
+ return verifier.verify_cmake(['-DCMAKE_BUILD_TYPE=RelWithDebInfo'
+ ]).make_test_result_tuple()
diff --git a/tests/build/cmake_not_mingw/CMakeLists.txt b/tests/build/cmake_not_mingw/CMakeLists.txt
new file mode 100644
index 0000000..9008214
--- /dev/null
+++ b/tests/build/cmake_not_mingw/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.6)
+project(CMakeNotMinGW ASM C CXX)
+
+if(DEFINED MINGW)
+ message(FATAL_ERROR "MINGW should not be defined")
+endif()
diff --git a/tests/build/cmake_toolchain_defaults/__init__.py b/tests/build/cmake_toolchain_defaults/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/cmake_toolchain_defaults/__init__.py
diff --git a/tests/build/cmake_toolchain_defaults/project/CMakeLists.txt b/tests/build/cmake_toolchain_defaults/project/CMakeLists.txt
new file mode 100644
index 0000000..350b9bf
--- /dev/null
+++ b/tests/build/cmake_toolchain_defaults/project/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.6)
+project(ToolchainDefaultsTest CXX)
+
+add_library(foo SHARED foo.cpp)
diff --git a/tests/build/cmake_toolchain_defaults/project/foo.cpp b/tests/build/cmake_toolchain_defaults/project/foo.cpp
new file mode 100644
index 0000000..83e1781
--- /dev/null
+++ b/tests/build/cmake_toolchain_defaults/project/foo.cpp
@@ -0,0 +1,8 @@
+#if !defined(__ARM_ARCH_7A__)
+#error ABI did not default to armeabi-v7a
+#endif
+
+// Update this whenever we raise the minimum API level in the NDK.
+#if __ANDROID_API__ != 19
+#error API level did not default to 19
+#endif
diff --git a/tests/build/cmake_toolchain_defaults/test.py b/tests/build/cmake_toolchain_defaults/test.py
new file mode 100644
index 0000000..f48a2a7
--- /dev/null
+++ b/tests/build/cmake_toolchain_defaults/test.py
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2021 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.
+#
+"""Check that the default CMake toolchain behavior works."""
+from pathlib import Path
+import subprocess
+
+from ndk.cmake import find_cmake, find_ninja
+from ndk.test.spec import BuildConfiguration, CMakeToolchainFile
+
+
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
+ """Check that the default CMake toolchain behavior works.
+
+ All our regular CMake tests pass the API level and ABI explicitly. This
+ test checks that the defaults (armeabi-v7a, minimum supported API level)
+ work.
+ """
+ cmake = find_cmake()
+ ninja = find_ninja()
+ toolchain_path = Path(ndk_path) / 'build/cmake/android.toolchain.cmake'
+ project_path = 'project'
+ if config.toolchain_file is CMakeToolchainFile.Legacy:
+ toolchain_mode = 'ON'
+ else:
+ toolchain_mode = 'OFF'
+ cmake_cmd = [
+ str(cmake),
+ f'-DCMAKE_TOOLCHAIN_FILE={toolchain_path}',
+ f'-DCMAKE_MAKE_PROGRAM={ninja}',
+ f'-DANDROID_USE_LEGACY_TOOLCHAIN_FILE={toolchain_mode}',
+ '-GNinja',
+ ]
+ result = subprocess.run(cmake_cmd,
+ check=False,
+ cwd=project_path,
+ capture_output=True,
+ text=True)
+ return result.returncode == 0, result.stdout
diff --git a/tests/build/cmake_toolchain_defaults/test_config.py b/tests/build/cmake_toolchain_defaults/test_config.py
new file mode 100644
index 0000000..aa58ee5
--- /dev/null
+++ b/tests/build/cmake_toolchain_defaults/test_config.py
@@ -0,0 +1,10 @@
+from typing import Optional
+
+from ndk.abis import LP32_ABIS
+from ndk.test.types import Test
+
+
+def build_unsupported(test: Test) -> Optional[str]:
+ if test.config.abi in LP32_ABIS:
+ return test.config.abi
+ return None
diff --git a/tests/build/link_order/test.py b/tests/build/link_order/test.py
index 2a6f6ee..e73fd88 100644
--- a/tests/build/link_order/test.py
+++ b/tests/build/link_order/test.py
@@ -21,12 +21,13 @@
import shlex
import subprocess
import sys
-from typing import Iterator, Optional, Tuple
+from typing import Iterator, Optional
from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
-def is_linked_item(arg):
+def is_linked_item(arg: str) -> bool:
"""Returns True if the argument is an object or library to be linked."""
if arg.endswith('.a'):
return True
@@ -39,7 +40,7 @@
return False
-def find_link_args(link_line):
+def find_link_args(link_line: str) -> list[str]:
"""Returns a list of objects and libraries in the link command."""
args = []
@@ -67,7 +68,7 @@
return args
-def builtins_basename(abi: Abi):
+def builtins_basename(abi: Abi) -> str:
runtimes_arch = {
'armeabi-v7a': 'arm',
'arm64-v8a': 'aarch64',
@@ -77,12 +78,14 @@
return 'libclang_rt.builtins-' + runtimes_arch + '-android.a'
-def check_link_order(link_line: str, abi: Abi,
- api: int) -> Tuple[bool, Optional[Iterator[str]]]:
+def check_link_order(
+ link_line: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[Iterator[str]]]:
"""Determines if a given link command has the correct ordering.
Args:
- link_line (string): The full ld command.
+ link_line: The full ld command.
+ config: The test's build configuration.
Returns:
Tuple of (success, diff). The diff will be None on success or a
@@ -90,7 +93,8 @@
suitable for use with `' '.join()`. The diff represents the changes
between the expected link order and the actual link order.
"""
- android_support_arg = ['libandroid_support.a'] if api < 21 else []
+ assert config.api is not None
+ android_support_arg = ['libandroid_support.a'] if config.api < 21 else []
expected = [
'crtbegin_so.o',
'foo.o',
@@ -105,11 +109,11 @@
'-lc',
'-lm',
'-lm',
- builtins_basename(abi),
+ builtins_basename(config.abi),
'-l:libunwind.a',
'-ldl',
'-lc',
- builtins_basename(abi),
+ builtins_basename(config.abi),
'-l:libunwind.a',
'-ldl',
'crtend_so.o',
@@ -120,15 +124,15 @@
return False, difflib.unified_diff(expected, link_args, lineterm='')
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks clang's -v output for proper link ordering."""
ndk_build = os.path.join(ndk_path, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
@@ -150,5 +154,5 @@
if link_line is None:
return False, 'Did not find link line in out:\n{}'.format(out)
- result, diff = check_link_order(link_line, abi, api)
+ result, diff = check_link_order(link_line, config)
return result, '' if diff is None else os.linesep.join(diff)
diff --git a/tests/build/lld_rosegment/test.py b/tests/build/lld_rosegment/test.py
index 68713d7..b36fd18 100644
--- a/tests/build/lld_rosegment/test.py
+++ b/tests/build/lld_rosegment/test.py
@@ -18,21 +18,24 @@
https://github.com/android/ndk/issues/1196
"""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, _api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks correct --no-rosegment use."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, 28)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path),
+ config).with_api(28)
verifier.expect_flag('-Wl,--no-rosegment')
verifier.expect_not_flag('-Wl,--rosegment')
result = verifier.verify()
if result.failed():
return result.make_test_result_tuple()
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, 29)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path),
+ config).with_api(29)
verifier.expect_not_flag('-Wl,--no-rosegment')
return verifier.verify().make_test_result_tuple()
diff --git a/tests/build/mstackrealign/test.py b/tests/build/mstackrealign/test.py
index ab3e4c9..5e581bb 100644
--- a/tests/build/mstackrealign/test.py
+++ b/tests/build/mstackrealign/test.py
@@ -19,16 +19,19 @@
issues. For these devices, verify that mstackrealign is used.
"""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks ndk-build V=1 output for mstackrealign flag."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
- if abi == Abi('x86') and api < 24:
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
+ assert config.api is not None
+ if config.abi == Abi('x86') and config.api < 24:
verifier.expect_flag('-mstackrealign')
else:
verifier.expect_not_flag('-mstackrealign')
diff --git a/tests/build/no_platform_gaps/test.py b/tests/build/no_platform_gaps/test.py
index 3b224a1..d6c0861 100644
--- a/tests/build/no_platform_gaps/test.py
+++ b/tests/build/no_platform_gaps/test.py
@@ -28,23 +28,22 @@
from pathlib import Path
import subprocess
import sys
-from typing import Tuple
import ndk.testing.standalone_toolchain
import ndk.abis
-from ndk.abis import Abi
from ndk.hosts import Host
+from ndk.test.spec import BuildConfiguration
-def build(ndk_dir: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def build(ndk_dir: str, config: BuildConfiguration) -> tuple[bool, str]:
ndk_build = os.path.join(ndk_dir, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
'V=1',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
@@ -53,13 +52,13 @@
return proc.returncode == 0, out.decode('utf-8')
-def run_test(ndk_path: str, abi: Abi, _api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks ndk-build V=1 output for correct compiler."""
min_api = None
max_api = None
apis = []
host = Host.current().tag
- triple = ndk.abis.arch_to_triple(ndk.abis.abi_to_arch(abi))
+ triple = ndk.abis.arch_to_triple(ndk.abis.abi_to_arch(config.abi))
toolchain_dir = Path(ndk_path) / f'toolchains/llvm/prebuilt/{host}'
lib_dir = toolchain_dir / f'sysroot/usr/lib/{triple}'
for path in lib_dir.iterdir():
@@ -83,7 +82,7 @@
missing_platforms = sorted(list(set(range(min_api, max_api)) - set(apis)))
for api in missing_platforms:
- result, out = build(ndk_path, abi, api)
+ result, out = build(ndk_path, config)
if not result:
return result, out
diff --git a/tests/build/standalone_toolchain/test.py b/tests/build/standalone_toolchain/test.py
index a9a4512..4b803f1 100644
--- a/tests/build/standalone_toolchain/test.py
+++ b/tests/build/standalone_toolchain/test.py
@@ -13,13 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-from typing import Tuple
-
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
import ndk.testing.standalone_toolchain
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
- return ndk.testing.standalone_toolchain.run_test(ndk_path, abi, api,
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
+ return ndk.testing.standalone_toolchain.run_test(ndk_path, config,
'foo.cpp',
['--stl=libc++'], [])
diff --git a/tests/build/standalone_toolchain_no_android_support/test.py b/tests/build/standalone_toolchain_no_android_support/test.py
index 4ead3a2..d42c168 100644
--- a/tests/build/standalone_toolchain_no_android_support/test.py
+++ b/tests/build/standalone_toolchain_no_android_support/test.py
@@ -13,12 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-from typing import Tuple
-
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
import ndk.testing.standalone_toolchain
-def run_test(ndk_path: str, abi: Abi, _api: int) -> Tuple[bool, str]:
- return ndk.testing.standalone_toolchain.run_test(ndk_path, abi, 21,
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
+ return ndk.testing.standalone_toolchain.run_test(ndk_path, config,
'foo.cpp', [], [])
diff --git a/tests/build/standalone_toolchain_thumb/test.py b/tests/build/standalone_toolchain_thumb/test.py
index f0502cc..3fc2cbb 100644
--- a/tests/build/standalone_toolchain_thumb/test.py
+++ b/tests/build/standalone_toolchain_thumb/test.py
@@ -13,12 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-from typing import Tuple
-
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
import ndk.testing.standalone_toolchain
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
return ndk.testing.standalone_toolchain.run_test(
- ndk_path, abi, api, 'foo.cpp', ['--stl=libc++'], ['-mthumb'])
+ ndk_path, config, 'foo.cpp', ['--stl=libc++'], ['-mthumb'])
diff --git a/tests/build/strip/test.py b/tests/build/strip/test.py
index d9e1be5..a0fcf36 100644
--- a/tests/build/strip/test.py
+++ b/tests/build/strip/test.py
@@ -15,14 +15,15 @@
#
"""Check for strip --strip-unneeded use."""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks ndk-build V=1 output for --strip-unneeded flag."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
verifier.expect_flag('--strip-unneeded')
return verifier.verify_ndk_build().make_test_result_tuple()
diff --git a/tests/build/strip_keep_symbols/test.py b/tests/build/strip_keep_symbols/test.py
index bf2ba85..fe8f94f 100644
--- a/tests/build/strip_keep_symbols/test.py
+++ b/tests/build/strip_keep_symbols/test.py
@@ -15,15 +15,16 @@
#
"""Check for strip --strip-debug use."""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks ndk-build V=1 output for --strip-debug flag."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
verifier.expect_flag('--strip-debug')
verifier.expect_not_flag('--strip-unneeded')
return verifier.verify_ndk_build().make_test_result_tuple()
diff --git a/tests/build/strip_keep_symbols_app/test.py b/tests/build/strip_keep_symbols_app/test.py
index bf2ba85..fe8f94f 100644
--- a/tests/build/strip_keep_symbols_app/test.py
+++ b/tests/build/strip_keep_symbols_app/test.py
@@ -15,15 +15,16 @@
#
"""Check for strip --strip-debug use."""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks ndk-build V=1 output for --strip-debug flag."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
verifier.expect_flag('--strip-debug')
verifier.expect_not_flag('--strip-unneeded')
return verifier.verify_ndk_build().make_test_result_tuple()
diff --git a/tests/build/strip_local_overrides_app/test.py b/tests/build/strip_local_overrides_app/test.py
index 5b566d1..c237130 100644
--- a/tests/build/strip_local_overrides_app/test.py
+++ b/tests/build/strip_local_overrides_app/test.py
@@ -15,15 +15,16 @@
#
"""Check for strip --strip-unneeded use."""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks ndk-build V=1 output for --strip-unneeded flag."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
verifier.expect_not_flag('--strip-debug')
verifier.expect_flag('--strip-unneeded')
return verifier.verify_ndk_build().make_test_result_tuple()
diff --git a/tests/build/strip_none/test.py b/tests/build/strip_none/test.py
index d655926..ed70424 100644
--- a/tests/build/strip_none/test.py
+++ b/tests/build/strip_none/test.py
@@ -15,15 +15,16 @@
#
"""Check that strip is not used."""
from pathlib import Path
-from typing import Optional, Tuple
+from typing import Optional
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
from ndk.testing.flag_verifier import FlagVerifier
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, Optional[str]]:
+def run_test(ndk_path: str,
+ config: BuildConfiguration) -> tuple[bool, Optional[str]]:
"""Checks ndk-build V=1 output for lack of strip."""
- verifier = FlagVerifier(Path('project'), Path(ndk_path), abi, api)
+ verifier = FlagVerifier(Path('project'), Path(ndk_path), config)
# TODO: Fix this test.
# This test has always been wrong, since it was only doing whole word
# search for 'strip' and we call strip with its full path.
diff --git a/tests/build/unwinder_hidden/test.py b/tests/build/unwinder_hidden/test.py
index cd23ce8..00b82ff 100644
--- a/tests/build/unwinder_hidden/test.py
+++ b/tests/build/unwinder_hidden/test.py
@@ -18,10 +18,10 @@
from pathlib import Path
import re
import subprocess
-from typing import Iterator, Tuple
+from typing import Iterator
-from ndk.abis import Abi
import ndk.hosts
+from ndk.test.spec import BuildConfiguration
def find_public_unwind_symbols(output: str) -> Iterator[str]:
@@ -55,7 +55,7 @@
stderr=subprocess.STDOUT).stdout
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Check that unwinder symbols are hidden in outputs."""
ndk_build = Path(ndk_path) / 'ndk-build'
host = ndk.hosts.get_default_host()
@@ -63,8 +63,8 @@
ndk_build = ndk_build.with_suffix('.cmd')
project_path = Path('project')
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
]
subprocess.run(
[str(ndk_build), '-C', str(project_path)] + ndk_args,
@@ -72,7 +72,7 @@
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
- library = project_path / 'libs' / str(abi) / 'libfoo.so'
+ library = project_path / 'libs' / str(config.abi) / 'libfoo.so'
readelf_output = readelf(Path(ndk_path), host, library, '-sW')
for symbol in find_public_unwind_symbols(readelf_output):
return False, f'Found public unwind symbol: {symbol}'
diff --git a/tests/build/wrap_sh/test.py b/tests/build/wrap_sh/test.py
index 45d28d1..6cf9744 100644
--- a/tests/build/wrap_sh/test.py
+++ b/tests/build/wrap_sh/test.py
@@ -19,20 +19,19 @@
import subprocess
import sys
import textwrap
-from typing import Tuple
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks that the proper wrap.sh scripts were installed."""
ndk_build = os.path.join(ndk_path, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
@@ -41,16 +40,16 @@
if proc.returncode != 0:
return proc.returncode == 0, out
- wrap_sh = os.path.join(project_path, 'libs', abi, 'wrap.sh')
+ wrap_sh = os.path.join(project_path, 'libs', config.abi, 'wrap.sh')
if not os.path.exists(wrap_sh):
return False, f'{wrap_sh} does not exist'
with open(wrap_sh) as wrap_sh_file:
contents = wrap_sh_file.read().strip()
- if contents != abi:
+ if contents != config.abi:
return False, textwrap.dedent(f"""\
wrap.sh file had wrong contents:
- Expected: {abi}
+ Expected: {config.abi}
Actual: {contents}""")
return True, ''
diff --git a/tests/build/wrap_sh_generic/test.py b/tests/build/wrap_sh_generic/test.py
index 13b1a68..b9d8f9a 100644
--- a/tests/build/wrap_sh_generic/test.py
+++ b/tests/build/wrap_sh_generic/test.py
@@ -19,20 +19,19 @@
import subprocess
import sys
import textwrap
-from typing import Tuple
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks that the proper wrap.sh scripts were installed."""
ndk_build = os.path.join(ndk_path, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
@@ -41,7 +40,7 @@
if proc.returncode != 0:
return proc.returncode == 0, out
- wrap_sh = os.path.join(project_path, 'libs', abi, 'wrap.sh')
+ wrap_sh = os.path.join(project_path, 'libs', config.abi, 'wrap.sh')
if not os.path.exists(wrap_sh):
return False, '{} does not exist'.format(wrap_sh)
@@ -49,7 +48,7 @@
contents = wrap_sh_file.read().strip()
if contents != 'generic':
return False, textwrap.dedent(f"""\
- {abi} wrap.sh file had wrong contents:
+ {config.abi} wrap.sh file had wrong contents:
Expected: generic
Actual: {contents}""")
diff --git a/tests/build/wrap_sh_none/test.py b/tests/build/wrap_sh_none/test.py
index 370b1ce..8611614 100644
--- a/tests/build/wrap_sh_none/test.py
+++ b/tests/build/wrap_sh_none/test.py
@@ -17,20 +17,19 @@
import os
import subprocess
import sys
-from typing import Tuple
-from ndk.abis import Abi
+from ndk.test.spec import BuildConfiguration
-def run_test(ndk_path: str, abi: Abi, api: int) -> Tuple[bool, str]:
+def run_test(ndk_path: str, config: BuildConfiguration) -> tuple[bool, str]:
"""Checks that the proper wrap.sh scripts were installed."""
ndk_build = os.path.join(ndk_path, 'ndk-build')
if sys.platform == 'win32':
ndk_build += '.cmd'
project_path = 'project'
ndk_args = [
- f'APP_ABI={abi}',
- f'APP_PLATFORM=android-{api}',
+ f'APP_ABI={config.abi}',
+ f'APP_PLATFORM=android-{config.api}',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
@@ -39,7 +38,7 @@
if proc.returncode != 0:
return proc.returncode == 0, out
- wrap_sh = os.path.join(project_path, 'libs', abi, 'wrap.sh')
+ wrap_sh = os.path.join(project_path, 'libs', config.abi, 'wrap.sh')
if os.path.exists(wrap_sh):
return False, '{} should not exist'.format(wrap_sh)
return True, ''