From 29b51379de352980dd453243bea7ed37ed300c62 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 3 Jun 2016 15:06:58 -0400 Subject: [PATCH] Android: Detect and save a standalone toolchain without the NDK --- Modules/Platform/Android-Determine.cmake | 47 +++++++++++-- Modules/Platform/Android-Initialize.cmake | 2 + .../Determine-Compiler-Standalone.cmake | 69 +++++++++++++++++++ .../Platform/Android/Determine-Compiler.cmake | 2 + 4 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 Modules/Platform/Android/Determine-Compiler-Standalone.cmake diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index 0055ecb98..50ab40b53 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -26,6 +26,7 @@ endif() set(_ANDROID_SYSROOT_NDK "") set(_ANDROID_SYSROOT_API "") set(_ANDROID_SYSROOT_ARCH "") +set(_ANDROID_SYSROOT_STANDALONE_TOOLCHAIN "") if(CMAKE_SYSROOT) if(NOT IS_DIRECTORY "${CMAKE_SYSROOT}") message(FATAL_ERROR @@ -38,16 +39,20 @@ if(CMAKE_SYSROOT) set(_ANDROID_SYSROOT_NDK "${CMAKE_MATCH_1}") set(_ANDROID_SYSROOT_API "${CMAKE_MATCH_2}") set(_ANDROID_SYSROOT_ARCH "${CMAKE_MATCH_3}") + elseif(CMAKE_SYSROOT MATCHES "^([^\\\n]*)/sysroot$") + set(_ANDROID_SYSROOT_STANDALONE_TOOLCHAIN "${CMAKE_MATCH_1}") else() message(FATAL_ERROR "The value of CMAKE_SYSROOT:\n" " ${CMAKE_SYSROOT}\n" - "does not match the form:\n" + "does not match any of the forms:\n" " /platforms/android-/arch-\n" + " /sysroot\n" "where:\n" " = Android NDK directory (with forward slashes)\n" " = Android API version number (decimal digits)\n" - " = Android ARCH name (lower case)" + " = Android ARCH name (lower case)\n" + " = Path to standalone toolchain prefix\n" ) endif() endif() @@ -61,17 +66,46 @@ if(CMAKE_ANDROID_NDK) "does not exist." ) endif() +elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN) + if(NOT IS_DIRECTORY "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}") + message(FATAL_ERROR + "Android: The standalone toolchain directory specified by CMAKE_ANDROID_STANDALONE_TOOLCHAIN:\n" + " ${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}\n" + "does not exist." + ) + endif() + if(NOT EXISTS "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h") + message(FATAL_ERROR + "Android: The standalone toolchain directory specified by CMAKE_ANDROID_STANDALONE_TOOLCHAIN:\n" + " ${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}\n" + "does not contain a sysroot with a known layout. The file:\n" + " ${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h\n" + "does not exist." + ) + endif() else() if(IS_DIRECTORY "${_ANDROID_SYSROOT_NDK}") set(CMAKE_ANDROID_NDK "${_ANDROID_SYSROOT_NDK}") + elseif(IS_DIRECTORY "${_ANDROID_SYSROOT_STANDALONE_TOOLCHAIN}") + set(CMAKE_ANDROID_STANDALONE_TOOLCHAIN "${_ANDROID_SYSROOT_STANDALONE_TOOLCHAIN}") elseif(IS_DIRECTORY "$ENV{ANDROID_NDK_ROOT}") file(TO_CMAKE_PATH "$ENV{ANDROID_NDK_ROOT}" CMAKE_ANDROID_NDK) endif() - # TODO: Search harder for the NDK. + # TODO: Search harder for the NDK or standalone toolchain. endif() -if(NOT CMAKE_ANDROID_NDK) - message(FATAL_ERROR "Android: The NDK root directory was not found.") +set(_ANDROID_STANDALONE_TOOLCHAIN_API "") +if(CMAKE_ANDROID_STANDALONE_TOOLCHAIN) + set(_ANDROID_API_LEVEL_H_REGEX "^[\t ]*#[\t ]*define[\t ]+__ANDROID_API__[\t ]+([0-9]+)") + file(STRINGS "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" + _ANDROID_API_LEVEL_H_CONTENT REGEX "${_ANDROID_API_LEVEL_H_REGEX}") + if(_ANDROID_API_LEVEL_H_CONTENT MATCHES "${_ANDROID_API_LEVEL_H_REGEX}") + set(_ANDROID_STANDALONE_TOOLCHAIN_API "${CMAKE_MATCH_1}") + endif() +endif() + +if(NOT CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_STANDALONE_TOOLCHAIN) + message(FATAL_ERROR "Android: Neither the NDK or a standalone toolchain was found.") endif() # Select an API. @@ -83,6 +117,8 @@ elseif(CMAKE_ANDROID_API) elseif(_ANDROID_SYSROOT_API) set(CMAKE_SYSTEM_VERSION "${_ANDROID_SYSROOT_API}") set(_ANDROID_API_VAR CMAKE_SYSROOT) +elseif(_ANDROID_STANDALONE_TOOLCHAIN_API) + set(CMAKE_SYSTEM_VERSION "${_ANDROID_STANDALONE_TOOLCHAIN_API}") endif() if(CMAKE_SYSTEM_VERSION) if(CMAKE_ANDROID_API AND NOT "x${CMAKE_ANDROID_API}" STREQUAL "x${CMAKE_SYSTEM_VERSION}") @@ -215,6 +251,7 @@ endif() # Save the Android-specific information in CMakeSystem.cmake. set(CMAKE_SYSTEM_CUSTOM_CODE " set(CMAKE_ANDROID_NDK \"${CMAKE_ANDROID_NDK}\") +set(CMAKE_ANDROID_STANDALONE_TOOLCHAIN \"${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}\") set(CMAKE_ANDROID_ARCH \"${CMAKE_ANDROID_ARCH}\") set(CMAKE_ANDROID_ARCH_ABI \"${CMAKE_ANDROID_ARCH_ABI}\") ") diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake index f05357cbb..625490eb3 100644 --- a/Modules/Platform/Android-Initialize.cmake +++ b/Modules/Platform/Android-Initialize.cmake @@ -24,6 +24,8 @@ endif() if(NOT CMAKE_SYSROOT) if(CMAKE_ANDROID_NDK) set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}") + elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN) + set(CMAKE_SYSROOT "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/sysroot") endif() endif() diff --git a/Modules/Platform/Android/Determine-Compiler-Standalone.cmake b/Modules/Platform/Android/Determine-Compiler-Standalone.cmake new file mode 100644 index 000000000..64d4ccf09 --- /dev/null +++ b/Modules/Platform/Android/Determine-Compiler-Standalone.cmake @@ -0,0 +1,69 @@ +#============================================================================= +# Copyright 2015-2016 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(_ANDROID_TOOL_C_COMPILER "") +set(_ANDROID_TOOL_CXX_COMPILER "") +set(_ANDROID_TOOL_PREFIX "") +file(GLOB _gcc "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/*-gcc${_ANDROID_HOST_EXT}") +foreach(gcc IN LISTS _gcc) + if("${gcc}" MATCHES "/bin/([^/]*)gcc${_ANDROID_HOST_EXT}$") + set(_ANDROID_TOOL_PREFIX "${CMAKE_MATCH_1}") + break() + endif() +endforeach() + +if(NOT _ANDROID_TOOL_PREFIX) + message(FATAL_ERROR + "Android: No '*-gcc' compiler found in CMAKE_ANDROID_STANDALONE_TOOLCHAIN:\n" + " ${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}" + ) +endif() + +# Help CMakeFindBinUtils locate things. +set(_CMAKE_TOOLCHAIN_PREFIX "${_ANDROID_TOOL_PREFIX}") + +execute_process( + COMMAND "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/${_ANDROID_TOOL_PREFIX}gcc${_ANDROID_HOST_EXT}" -dumpversion + OUTPUT_VARIABLE _gcc_version + ERROR_VARIABLE _gcc_error + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +if(_gcc_version MATCHES "^([0-9]+\\.[0-9]+)") + set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "${CMAKE_MATCH_1}") +else() + message(FATAL_ERROR + "Android: Failed to extract the standalone toolchain version. The command:\n" + " '${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/${_ANDROID_TOOL_PREFIX}gcc${_ANDROID_HOST_EXT}' '-dumpversion'\n" + "produced output:\n" + " ${_gcc_version}\n" + ) +endif() + +set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/${_ANDROID_TOOL_PREFIX}") +set(_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}") + +set(_ANDROID_TOOL_CXX_TOOLCHAIN_VERSION "${_ANDROID_TOOL_C_TOOLCHAIN_VERSION}") +set(_ANDROID_TOOL_CXX_TOOLCHAIN_PREFIX "${_ANDROID_TOOL_C_TOOLCHAIN_PREFIX}") +set(_ANDROID_TOOL_CXX_TOOLCHAIN_SUFFIX "${_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX}") + +if(EXISTS "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${_ANDROID_HOST_EXT}") + set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${_ANDROID_HOST_EXT}") + set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}") + set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/clang++${_ANDROID_HOST_EXT}") + set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}") +else() + set(_ANDROID_TOOL_C_COMPILER "${_ANDROID_TOOL_C_TOOLCHAIN_PREFIX}gcc${_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX}") + set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN "") + set(_ANDROID_TOOL_CXX_COMPILER "${_ANDROID_TOOL_CXX_TOOLCHAIN_PREFIX}g++${_ANDROID_TOOL_CXX_TOOLCHAIN_SUFFIX}") + set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "") +endif() diff --git a/Modules/Platform/Android/Determine-Compiler.cmake b/Modules/Platform/Android/Determine-Compiler.cmake index 9649b3529..613ce321d 100644 --- a/Modules/Platform/Android/Determine-Compiler.cmake +++ b/Modules/Platform/Android/Determine-Compiler.cmake @@ -39,6 +39,8 @@ endif() if(CMAKE_ANDROID_NDK) include(Platform/Android/Determine-Compiler-NDK) +elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN) + include(Platform/Android/Determine-Compiler-Standalone) else() set(_ANDROID_TOOL_C_COMPILER "") set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "")