From d7d4083025f3007b862dd500c8f5fc64e105055b Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Thu, 2 Jun 2016 15:19:20 -0400
Subject: Android: Select the STL type for NDK builds

Populate standard include directories and link libraries for the
platform.  Select the STL corresponding to CMAKE_ANDROID_STL_TYPE and
matching the current ABI and toolchain to be used.  Refer to the NDK
sources/cxx-stl/*/Android.mk files for the needed file locations.
---
 Modules/Platform/Android-Common.cmake              | 106 +++++++++++++++++++++
 Modules/Platform/Android/ndk-stl-c++.cmake         |  13 +++
 Modules/Platform/Android/ndk-stl-c++_shared.cmake  |   4 +
 Modules/Platform/Android/ndk-stl-c++_static.cmake  |   6 ++
 Modules/Platform/Android/ndk-stl-gabi++.cmake      |   7 ++
 .../Platform/Android/ndk-stl-gabi++_shared.cmake   |   4 +
 .../Platform/Android/ndk-stl-gabi++_static.cmake   |   4 +
 Modules/Platform/Android/ndk-stl-gnustl.cmake      |   9 ++
 .../Platform/Android/ndk-stl-gnustl_shared.cmake   |   4 +
 .../Platform/Android/ndk-stl-gnustl_static.cmake   |   4 +
 Modules/Platform/Android/ndk-stl-none.cmake        |   2 +
 Modules/Platform/Android/ndk-stl-stlport.cmake     |   7 ++
 .../Platform/Android/ndk-stl-stlport_shared.cmake  |   4 +
 .../Platform/Android/ndk-stl-stlport_static.cmake  |   4 +
 Modules/Platform/Android/ndk-stl-system.cmake      |   6 ++
 15 files changed, 184 insertions(+)
 create mode 100644 Modules/Platform/Android/ndk-stl-c++.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-c++_shared.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-c++_static.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-gabi++.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-gabi++_shared.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-gabi++_static.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-gnustl.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-gnustl_shared.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-gnustl_static.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-none.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-stlport.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-stlport_shared.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-stlport_static.cmake
 create mode 100644 Modules/Platform/Android/ndk-stl-system.cmake

diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index e77d2d8..6e86c10 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -17,6 +17,92 @@ if(__ANDROID_COMPILER_COMMON)
 endif()
 set(__ANDROID_COMPILER_COMMON 1)
 
+if(CMAKE_ANDROID_NDK)
+  # <ndk>/build/core/definitions.mk
+
+  set(_ANDROID_STL_TYPES
+    none
+    system
+    c++_static
+    c++_shared
+    gabi++_static
+    gabi++_shared
+    gnustl_static
+    gnustl_shared
+    stlport_static
+    stlport_shared
+    )
+
+  if(CMAKE_ANDROID_STL_TYPE)
+    list(FIND _ANDROID_STL_TYPES "${CMAKE_ANDROID_STL_TYPE}" _ANDROID_STL_TYPE_FOUND)
+    if(_ANDROID_STL_TYPE_FOUND EQUAL -1)
+      string(REPLACE ";" "\n  " _msg ";${_ANDROID_STL_TYPES}")
+      message(FATAL_ERROR
+        "The CMAKE_ANDROID_STL_TYPE '${CMAKE_ANDROID_STL_TYPE}' is not one of the allowed values:${_msg}\n"
+        )
+    endif()
+    unset(_ANDROID_STL_TYPE_FOUND)
+  else()
+    set(CMAKE_ANDROID_STL_TYPE "gnustl_static")
+  endif()
+
+  unset(_ANDROID_STL_TYPES)
+
+  # Forward Android-specific platform variables to try_compile projects.
+  list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
+    CMAKE_ANDROID_STL_TYPE
+    )
+endif()
+
+if(CMAKE_ANDROID_STL_TYPE)
+  if(CMAKE_ANDROID_NDK)
+
+    macro(__android_stl_inc lang dir req)
+      if(EXISTS "${dir}")
+        list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${dir}")
+      elseif(${req})
+        message(FATAL_ERROR
+          "Android: STL '${CMAKE_ANDROID_STL_TYPE}' include directory not found:\n"
+          "  ${dir}"
+          )
+      endif()
+    endmacro()
+
+    macro(__android_stl_lib lang lib req)
+      if(CMAKE_ANDROID_ARCH_ABI MATCHES "^armeabi" AND NOT CMAKE_ANDROID_ARM_MODE)
+        get_filename_component(_ANDROID_STL_LIBDIR "${lib}" DIRECTORY)
+        get_filename_component(_ANDROID_STL_LIBNAME "${lib}" NAME)
+        set(_ANDROID_STL_LIBTHUMB "${_ANDROID_STL_LIBDIR}/thumb/${_ANDROID_STL_LIBNAME}")
+        unset(_ANDROID_STL_LIBDIR)
+        unset(_ANDROID_STL_LIBNAME)
+      else()
+        set(_ANDROID_STL_LIBTHUMB "")
+      endif()
+
+      if(_ANDROID_STL_LIBTHUMB AND EXISTS "${_ANDROID_STL_LIBTHUMB}")
+        string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " \"${_ANDROID_STL_LIBTHUMB}\"")
+      elseif(EXISTS "${lib}")
+        string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " \"${lib}\"")
+      elseif(${req})
+        message(FATAL_ERROR
+          "Android: STL '${CMAKE_ANDROID_STL_TYPE}' library file not found:\n"
+          "  ${lib}"
+          )
+      endif()
+
+      unset(_ANDROID_STL_LIBTHUMB)
+    endmacro()
+
+    include(Platform/Android/ndk-stl-${CMAKE_ANDROID_STL_TYPE})
+  else()
+    macro(__android_stl lang)
+    endmacro()
+  endif()
+else()
+  macro(__android_stl lang)
+  endmacro()
+endif()
+
 # The NDK toolchain configuration files at:
 #
 #   <ndk>/[build/core/]toolchains/*/setup.mk
@@ -49,4 +135,24 @@ macro(__android_compiler_common lang)
       string(APPEND CMAKE_${t}_LINKER_FLAGS_INIT " ${_ANDROID_ABI_INIT_LDFLAGS}")
     endforeach()
   endif()
+
+  if(DEFINED _ANDROID_STL_EXCEPTIONS)
+    if(_ANDROID_STL_EXCEPTIONS)
+      string(APPEND CMAKE_${lang}_FLAGS_INIT " -fexceptions")
+    else()
+      string(APPEND CMAKE_${lang}_FLAGS_INIT " -fno-exceptions")
+    endif()
+  endif()
+
+  if("x${lang}" STREQUAL "xCXX" AND DEFINED _ANDROID_STL_RTTI)
+    if(_ANDROID_STL_RTTI)
+      string(APPEND CMAKE_${lang}_FLAGS_INIT " -frtti")
+    else()
+      string(APPEND CMAKE_${lang}_FLAGS_INIT " -fno-rtti")
+    endif()
+  endif()
+
+  if("x${lang}" STREQUAL "xCXX")
+    __android_stl(CXX)
+  endif()
 endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-c++.cmake b/Modules/Platform/Android/ndk-stl-c++.cmake
new file mode 100644
index 0000000..14748a1
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-c++.cmake
@@ -0,0 +1,13 @@
+# <ndk>/sources/cxx-stl/llvm-libc++/Android.mk
+set(_ANDROID_STL_RTTI 1)
+set(_ANDROID_STL_EXCEPTIONS 1)
+macro(__android_stl_cxx lang filename)
+  # Add the include directory.
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include" 1)
+
+  # Add a secondary include directory if it exists.
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/android/support/include" 0)
+
+  # Add the library file.
+  __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-c++_shared.cmake b/Modules/Platform/Android/ndk-stl-c++_shared.cmake
new file mode 100644
index 0000000..f585adb
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-c++_shared.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-c++)
+macro(__android_stl lang)
+  __android_stl_cxx(${lang} libc++_shared.so)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-c++_static.cmake b/Modules/Platform/Android/ndk-stl-c++_static.cmake
new file mode 100644
index 0000000..8e562f8
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-c++_static.cmake
@@ -0,0 +1,6 @@
+include(Platform/Android/ndk-stl-c++)
+macro(__android_stl lang)
+  __android_stl_cxx(${lang} libc++_static.a)
+  __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${CMAKE_ANDROID_ARCH_ABI}/libc++abi.a" 0)
+  __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${CMAKE_ANDROID_ARCH_ABI}/libandroid_support.a" 0)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-gabi++.cmake b/Modules/Platform/Android/ndk-stl-gabi++.cmake
new file mode 100644
index 0000000..850a47a
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-gabi++.cmake
@@ -0,0 +1,7 @@
+# <ndk>/sources/cxx-stl/gabi++/Android.mk
+set(_ANDROID_STL_RTTI 1)
+set(_ANDROID_STL_EXCEPTIONS 1)
+macro(__android_stl_gabixx lang filename)
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gabi++/include" 1)
+  __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-gabi++_shared.cmake b/Modules/Platform/Android/ndk-stl-gabi++_shared.cmake
new file mode 100644
index 0000000..314c1e0
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-gabi++_shared.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-gabi++)
+macro(__android_stl lang)
+  __android_stl_gabixx(${lang} libgabi++_shared.so)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-gabi++_static.cmake b/Modules/Platform/Android/ndk-stl-gabi++_static.cmake
new file mode 100644
index 0000000..f4a1d3c
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-gabi++_static.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-gabi++)
+macro(__android_stl lang)
+  __android_stl_gabixx(${lang} libgabi++_static.a)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-gnustl.cmake b/Modules/Platform/Android/ndk-stl-gnustl.cmake
new file mode 100644
index 0000000..b3226ee
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-gnustl.cmake
@@ -0,0 +1,9 @@
+# <ndk>/sources/cxx-stl/gnu-libstdc++/Android.mk
+set(_ANDROID_STL_RTTI 1)
+set(_ANDROID_STL_EXCEPTIONS 1)
+macro(__android_stl_gnustl lang filename)
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/include" 1)
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/libs/${CMAKE_ANDROID_ARCH_ABI}/include" 1)
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/include/backward" 1)
+  __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-gnustl_shared.cmake b/Modules/Platform/Android/ndk-stl-gnustl_shared.cmake
new file mode 100644
index 0000000..f20cc4d
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-gnustl_shared.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-gnustl)
+macro(__android_stl lang)
+  __android_stl_gnustl(${lang} libgnustl_shared.so)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-gnustl_static.cmake b/Modules/Platform/Android/ndk-stl-gnustl_static.cmake
new file mode 100644
index 0000000..af4cc2a
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-gnustl_static.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-gnustl)
+macro(__android_stl lang)
+  __android_stl_gnustl(${lang} libgnustl_static.a)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-none.cmake b/Modules/Platform/Android/ndk-stl-none.cmake
new file mode 100644
index 0000000..9049c91
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-none.cmake
@@ -0,0 +1,2 @@
+macro(__android_stl lang)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-stlport.cmake b/Modules/Platform/Android/ndk-stl-stlport.cmake
new file mode 100644
index 0000000..eab6b94
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-stlport.cmake
@@ -0,0 +1,7 @@
+# <ndk>/sources/cxx-stl/stlport/Android.mk
+set(_ANDROID_STL_RTTI 1)
+set(_ANDROID_STL_EXCEPTIONS 1)
+macro(__android_stl_stlport lang filename)
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/stlport/stlport" 1)
+  __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/stlport/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-stlport_shared.cmake b/Modules/Platform/Android/ndk-stl-stlport_shared.cmake
new file mode 100644
index 0000000..2b5846b
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-stlport_shared.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-stlport)
+macro(__android_stl lang)
+  __android_stl_stlport(${lang} libstlport_shared.so)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-stlport_static.cmake b/Modules/Platform/Android/ndk-stl-stlport_static.cmake
new file mode 100644
index 0000000..bf60307
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-stlport_static.cmake
@@ -0,0 +1,4 @@
+include(Platform/Android/ndk-stl-stlport)
+macro(__android_stl lang)
+  __android_stl_stlport(${lang} libstlport_static.a)
+endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-system.cmake b/Modules/Platform/Android/ndk-stl-system.cmake
new file mode 100644
index 0000000..dd554fe
--- /dev/null
+++ b/Modules/Platform/Android/ndk-stl-system.cmake
@@ -0,0 +1,6 @@
+# <ndk>/android-ndk-r11c/sources/cxx-stl/system/Android.mk
+set(_ANDROID_STL_RTTI 0)
+set(_ANDROID_STL_EXCEPTIONS 0)
+macro(__android_stl lang)
+  __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/system/include" 1)
+endmacro()
-- 
cgit v0.12