Преглед изворни кода

Android: Detect and save a standalone toolchain without the NDK

Brad King пре 9 година
родитељ
комит
29b51379de

+ 42 - 5
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"
       "  <ndk>/platforms/android-<api>/arch-<arch>\n"
+      "  <standalone-toolchain>/sysroot\n"
       "where:\n"
       "  <ndk>  = Android NDK directory (with forward slashes)\n"
       "  <api>  = Android API version number (decimal digits)\n"
-      "  <arch> = Android ARCH name (lower case)"
+      "  <arch> = Android ARCH name (lower case)\n"
+      "  <standalone-toolchain> = 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()
+
+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)
-  message(FATAL_ERROR "Android: The NDK root directory was not found.")
+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}\")
 ")

+ 2 - 0
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()
 

+ 69 - 0
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()

+ 2 - 0
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 "")