From 16ca12ccd6e43c0faf898b12de359301ceec89cf Mon Sep 17 00:00:00 2001 From: Tom Finegan Date: Tue, 8 May 2018 09:19:20 -0700 Subject: [PATCH] Improve Android CMake toolchains. - Use the NDK directly instead of requiring standalone toolchains. - Add x86 and x86_64 toolchains. --- README.md | 23 +++++++++++++------ .../arm64-android-clang-libstdc++.cmake | 18 --------------- .../toolchains/arm64-android-ndk-libcpp.cmake | 12 ++++++++++ .../armv7-android-clang-libstdc++.cmake | 18 --------------- .../toolchains/armv7-android-ndk-libcpp.cmake | 12 ++++++++++ cmake/toolchains/x86-android-ndk-libcpp.cmake | 12 ++++++++++ .../x86_64-android-ndk-libcpp.cmake | 12 ++++++++++ cmake/util.cmake | 21 +++++++++++++++++ 8 files changed, 85 insertions(+), 43 deletions(-) delete mode 100644 cmake/toolchains/arm64-android-clang-libstdc++.cmake create mode 100644 cmake/toolchains/arm64-android-ndk-libcpp.cmake delete mode 100644 cmake/toolchains/armv7-android-clang-libstdc++.cmake create mode 100644 cmake/toolchains/armv7-android-ndk-libcpp.cmake create mode 100644 cmake/toolchains/x86-android-ndk-libcpp.cmake create mode 100644 cmake/toolchains/x86_64-android-ndk-libcpp.cmake diff --git a/README.md b/README.md index 9930eb5..7b78ef6 100644 --- a/README.md +++ b/README.md @@ -321,20 +321,29 @@ It's sometimes useful to build Draco command line tools and run them directly on Android devices via adb. ~~~~~ bash +# all targets require CMAKE_ANDROID_NDK. It can be set in the environment or +# within CMake. For example, this would set it in your environment. +$ export CMAKE_ANDROID_NDK=path/to/ndk +# To set it within CMake, add -DCMAKE_ANDROID_NDK=path/to/ndk to your CMake +# command. + # arm -$ cmake path/to/draco -DCMAKE_TOOLCHAIN_FILE=path/to/draco/cmake/toolchains/armv7-android-clang-libstdc++.cmake +$ cmake path/to/draco -DCMAKE_TOOLCHAIN_FILE=path/to/draco/cmake/toolchains/armv7-android-ndk-libcpp.cmake $ make # arm64 -$ cmake path/to/draco -DCMAKE_TOOLCHAIN_FILE=path/to/draco/cmake/toolchains/arm64-android-clang-libstdc++.cmake +$ cmake path/to/draco -DCMAKE_TOOLCHAIN_FILE=path/to/draco/cmake/toolchains/arm64-android-ndk-libcpp.cmake +$ make + +# x86 +$ cmake path/to/draco -DCMAKE_TOOLCHAIN_FILE=path/to/draco/cmake/toolchains/x86-android-ndk-libcpp.cmake +$ make + +# x86_64 +$ cmake path/to/draco -DCMAKE_TOOLCHAIN_FILE=path/to/draco/cmake/toolchains/x86_64-android-ndk-libcpp.cmake $ make ~~~~~ -Note: The above assumes that make_standalone_toolchain.py has been used to -generate a standalone NDK toolchain for arm or arm64. In addition, Draco, as of -this writing, requires that libc++ is used for the stl argument when the -toolchain is generated. - After building the tools they can be moved to an android device via the use of `adb push`, and then run within an `adb shell` instance. diff --git a/cmake/toolchains/arm64-android-clang-libstdc++.cmake b/cmake/toolchains/arm64-android-clang-libstdc++.cmake deleted file mode 100644 index 919d271..0000000 --- a/cmake/toolchains/arm64-android-clang-libstdc++.cmake +++ /dev/null @@ -1,18 +0,0 @@ -if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_CLANG_LIBSTDCPP_CMAKE_) -set(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_CLANG_LIBSTDCPP_CMAKE_ 1) - -set(CMAKE_SYSTEM_NAME "Linux") - -if ("${CROSS}" STREQUAL "") - # Default the cross compiler prefix to something known to work. - set(CROSS aarch64-linux-android-) -endif () - -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_C_COMPILER ${CROSS}clang) -set(CMAKE_CXX_COMPILER ${CROSS}clang++) -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -static-libstdc++") -set(AS_EXECUTABLE ${CROSS}as) -set(CMAKE_SYSTEM_PROCESSOR "arm64") - -endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_CLANG_LIBSTDCPP_CMAKE_ diff --git a/cmake/toolchains/arm64-android-ndk-libcpp.cmake b/cmake/toolchains/arm64-android-ndk-libcpp.cmake new file mode 100644 index 0000000..bd04419 --- /dev/null +++ b/cmake/toolchains/arm64-android-ndk-libcpp.cmake @@ -0,0 +1,12 @@ +if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_) +set(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake") + +set(CMAKE_SYSTEM_NAME Android) +set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) +require_variable(CMAKE_ANDROID_NDK) +set_variable_if_unset(CMAKE_SYSTEM_VERSION 21) +set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static) + +endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_ diff --git a/cmake/toolchains/armv7-android-clang-libstdc++.cmake b/cmake/toolchains/armv7-android-clang-libstdc++.cmake deleted file mode 100644 index 5f8d9bd..0000000 --- a/cmake/toolchains/armv7-android-clang-libstdc++.cmake +++ /dev/null @@ -1,18 +0,0 @@ -if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_CLANG_LIBSTDCPP_CMAKE_) -set(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_CLANG_LIBSTDCPP_CMAKE_ 1) - -set(CMAKE_SYSTEM_NAME "Linux") - -if ("${CROSS}" STREQUAL "") - # Default the cross compiler prefix to something known to work. - set(CROSS arm-linux-androideabi-) -endif () - -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_C_COMPILER ${CROSS}clang) -set(CMAKE_CXX_COMPILER ${CROSS}clang++) -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -static-libstdc++") -set(AS_EXECUTABLE ${CROSS}as) -set(CMAKE_SYSTEM_PROCESSOR "armv7") - -endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_CLANG_LIBSTDCPP_CMAKE_ diff --git a/cmake/toolchains/armv7-android-ndk-libcpp.cmake b/cmake/toolchains/armv7-android-ndk-libcpp.cmake new file mode 100644 index 0000000..fd50def --- /dev/null +++ b/cmake/toolchains/armv7-android-ndk-libcpp.cmake @@ -0,0 +1,12 @@ +if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_) +set(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake") + +set(CMAKE_SYSTEM_NAME Android) +set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) +require_variable(CMAKE_ANDROID_NDK) +set_variable_if_unset(CMAKE_SYSTEM_VERSION 18) +set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static) + +endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_ diff --git a/cmake/toolchains/x86-android-ndk-libcpp.cmake b/cmake/toolchains/x86-android-ndk-libcpp.cmake new file mode 100644 index 0000000..7bb3717 --- /dev/null +++ b/cmake/toolchains/x86-android-ndk-libcpp.cmake @@ -0,0 +1,12 @@ +if (NOT DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_) +set(DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake") + +set(CMAKE_SYSTEM_NAME Android) +set(CMAKE_ANDROID_ARCH_ABI x86) +require_variable(CMAKE_ANDROID_NDK) +set_variable_if_unset(CMAKE_SYSTEM_VERSION 18) +set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static) + +endif () # DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_ diff --git a/cmake/toolchains/x86_64-android-ndk-libcpp.cmake b/cmake/toolchains/x86_64-android-ndk-libcpp.cmake new file mode 100644 index 0000000..3b86b9d --- /dev/null +++ b/cmake/toolchains/x86_64-android-ndk-libcpp.cmake @@ -0,0 +1,12 @@ +if (NOT DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_) +set(DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake") + +set(CMAKE_SYSTEM_NAME Android) +set(CMAKE_ANDROID_ARCH_ABI x86_64) +require_variable(CMAKE_ANDROID_NDK) +set_variable_if_unset(CMAKE_SYSTEM_VERSION 21) +set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static) + +endif () # DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_ diff --git a/cmake/util.cmake b/cmake/util.cmake index 84798b5..f0c8ae6 100644 --- a/cmake/util.cmake +++ b/cmake/util.cmake @@ -51,5 +51,26 @@ function (set_compiler_launcher launcher_flag launcher_name) endif () endfunction () +# Terminates CMake execution when $var_name is unset in CMake and environment, +# and then calls set_variable_if_unset() to ensure variable is set for caller. +macro(require_variable var_name) + if ((NOT DEFINED ${var_name}) AND ("$ENV{${var_name}}" STREQUAL "")) + message(FATAL_ERROR "${var_name} must be set in cmake or environment.") + endif () + set_variable_if_unset(${var_name} "") +endmacro () + +# Sets $var_name to $default_value if not already set in CMake or the +# environment. +macro (set_variable_if_unset var_name default_value) + if (DEFINED ${var_name}) + return () + elseif (NOT "$ENV{${var_name}}" STREQUAL "") + set(${var_name} $ENV{${var_name}}) + else () + set(${var_name} ${default_value}) + endif () +endmacro () + endif() # DRACO_CMAKE_UTIL_CMAKE_