Skip to content

Instantly share code, notes, and snippets.

@claydonkey
Last active November 23, 2018 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save claydonkey/a5b680ba0d355bec77ef33389ae0febd to your computer and use it in GitHub Desktop.
Save claydonkey/a5b680ba0d355bec77ef33389ae0febd to your computer and use it in GitHub Desktop.
cmake for android standalone toolchains
# Anthony (Anthony@claydonkey.com)
# This cmake is a bootstrap for the c++/c
# standalone toolchain for Android NDK.
# initializing relevant variables
#
# Setup Toolchain.
cmake_minimum_required(VERSION 3.4.1)
option(ANDROID "Build for Android" ON)
if (ANDROID)
message(STATUS "EmulationStation CMake Bootstrap")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(ANDROID_TOOLCHAIN_REGEX CACHE STRING "Regex to remove NDK prebuilt compiler flags")
set(STAMP_DIR .deps/logs)
set(TMP_DIR .deps/tmp)
file(MAKE_DIRECTORY ${TMP_DIR})
file(MAKE_DIRECTORY ${STAMP_DIR})
cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0053 NEW)
unset(CMAKE_C_COMPILER)
set(ANDROID_ABI x86 CACHE STRING "ABI Format")
set_property(CACHE ANDROID_ABI PROPERTY STRINGS armeabi-v7a win64 x86_64 x86 armeabi-v7a)
if (ANDROID_PLATFORM)
string(REPLACE "android-" "" ANDROID_NATIVE_API_LEVEL ${ANDROID_PLATFORM})
endif ()
if (NOT ANDROID_NATIVE_API_LEVEL)
set(ANDROID_NATIVE_API_LEVEL 24 CACHE STRING "Android API level")
set_property(CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28)
endif ()
if(ANDROID_NATIVE_API_LEVEL GREATER 28 OR NOT ANDROID_NATIVE_API_LEVEL MATCHES "^[0-9]+$")
message(ERROR "Set Android API Level")
endif()
if(NOT ANDROID_PLATFORM)
set(ANDROID_PLATFORM "android-${ANDROID_NATIVE_API_LEVEL}")
endif()
set(ANDROID_NDK /home/anthony/Android/Sdk/ndk-bundle)
option(ANDROID_STATIC_EXE "build static executable" OFF)
option(CMAKE_SHARED "build shared libraries" ON)
option(CMAKE_STATIC "build static libraries" ON)
if (CMAKE_SHARED)
set(SHARED_FLAG "--enable-shared")
else ()
set(SHARED_FLAG "--disable-shared")
endif ()
if (CMAKE_STATIC)
set(STATIC_FLAG "--enable-static")
else ()
set(STATIC_FLAG "--disable-static")
endif ()
if (ANDROID_STATIC_EXE)
set(ANDROID_STATIC_FLAG "-static-libstdc++")
endif ()
set(CMAKE_FIND_LIBRARY_PREFIXES lib)
set(CMAKE_FIND_LIBRARY_SUFFIXES .so;.a)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_DEBUG_FLAG "-g -O0 -fno-limit-debug-info ")
endif ()
if (CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
set(ANDROID_HOST_TAG linux-x86_64)
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
set(ANDROID_HOST_TAG darwin-x86_64)
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
set(ANDROID_HOST_TAG windows-x86_64)
endif (CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
if (ANDROID_ABI STREQUAL armeabi-v7a)
set(COMPILER_ROOT ${ANDROID_NDK}/armv7a-none-linux-android${ANDROID_NATIVE_API_LEVEL})
set(ANDROID_TRIPLE arm-linux-androideabi)
set(ANDROID_SYSROOT_ABI arm)
set(CMAKE_INSTALL_LIBDIR lib)
set(CMAKE_SYSTEM_PROCESSOR armv7-a)
set(CMAKE_GCC_TOOLCHAIN arm-linux-androideabi-4.9)
set(CMAKE_C_EXTRA_FLAGS "-DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security ${CMAKE_DEBUG_FLAG}")
elseif (ANDROID_ABI STREQUAL arm64-v8a)
set(COMPILER_ROOT ${ANDROID_NDK}/aarch64-none-linux-android${ANDROID_NATIVE_API_LEVEL})
set(ANDROID_TRIPLE aarch64-linux-android)
set(ANDROID_SYSROOT_ABI arm64)
set(CMAKE_INSTALL_LIBDIR lib64)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_GCC_TOOLCHAIN aarch64-linux-android-4.9)
elseif (ANDROID_ABI STREQUAL x86_64)
set(COMPILER_ROOT ${ANDROID_NDK}/x86_64-none-linux-android${ANDROID_NATIVE_API_LEVEL})
set(ANDROID_TRIPLE x86_64-linux-android)
set(ANDROID_SYSROOT_ABI x86_64)
set(CMAKE_INSTALL_LIBDIR lib64)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_GCC_TOOLCHAIN x86_64-4.9)
elseif (ANDROID_ABI STREQUAL x86)
set(COMPILER_ROOT ${ANDROID_NDK}/i686-none-linux-android${ANDROID_NATIVE_API_LEVEL})
set(ANDROID_TRIPLE i686-linux-android)
set(ANDROID_SYSROOT_ABI x86)
set(CMAKE_INSTALL_LIBDIR lib)
set(CMAKE_SYSTEM_PROCESSOR i686)
set(CMAKE_SIZEOF_VOID_P 4)
set(CMAKE_GCC_TOOLCHAIN x86-4.9)
set(CMAKE_CXX_EXTRA_FLAGS "-DANDROID -fPIC ${CMAKE_DEBUG_FLAG}")
set(CMAKE_C_EXTRA_FLAGS "-DANDROID -fPIC ${CMAKE_DEBUG_FLAG}")
endif (ANDROID_ABI STREQUAL armeabi-v7a)
set(CMAKE_GCC_TOOLCHAIN ${ANDROID_NDK}/toolchains/${CMAKE_GCC_TOOLCHAIN}/prebuilt/${ANDROID_HOST_TAG})
set(ANDROID_LLVM_TOOLCHAIN_PREFIX "${COMPILER_ROOT}/bin/")
set(CMAKE_SYSROOT ${COMPILER_ROOT}/sysroot)
#remove isystem includes for C from NDK Prebuilt via toolchain: android.standalone.cmake
if(CMAKE_C_FLAGS)
string(REGEX REPLACE "eabi" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
if(ANDROID_TOOLCHAIN_REGEX)
string(REGEX REPLACE ${ANDROID_TOOLCHAIN_REGEX} "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
else()
string(REGEX REPLACE "\-isystem((.|\/)+)android" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
endif()
endif()
set(ANDROID_SYSROOT "${CMAKE_SYSROOT}")
set(ANDROID_COMPILER_FLAGS "")
set(ANDROID_LINKER_FLAGS "")
#remove default includes for C++ from NDK Prebuilt via toolchain: android.standalone.cmake
unset(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
unset(ANDROID_COMPILER_FLAGS)
# Toolchain and ABI specific flags.
if (ANDROID_ABI STREQUAL armeabi)
list(APPEND ANDROID_COMPILER_FLAGS
-march=armv5te
-mtune=xscale
-msoft-float)
endif ()
if (ANDROID_ABI STREQUAL armeabi-v7a)
list(APPEND ANDROID_COMPILER_FLAGS
-march=armv7-a
-mfloat-abi=softfp
-mfpu=vfpv3-d16)
list(APPEND ANDROID_LINKER_FLAGS -Wl,--fix-cortex-a8)
endif ()
list(APPEND ANDROID_COMPILER_FLAGS)
list(APPEND ANDROID_COMPILER_FLAGS_CXX)
list(APPEND ANDROID_LINKER_FLAGS)
list(APPEND ANDROID_LINKER_FLAGS_EXE
-Wl,--gc-sections
-Wl,-z,nocopyreloc)
message(STATUS "CFLAGS ${CMAKE_C_FLAGS}")
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} ${CMAKE_C_EXTRA_FLAGS} -Wno-null-pointer-arithmetic -w -Wno-error -Wno-unused-command-line-argument ${ANDROID_COMPILER_FLAGS} --sysroot=${CMAKE_SYSROOT} --gcc-toolchain=${CMAKE_GCC_TOOLCHAIN} ")
set(CMAKE_CXX_FLAGS " ${ANDROID_COMPILER_FLAGS_CXX} ${CMAKE_CXX_FLAGS} ${ANDROID_STATIC_FLAG} ${CMAKE_CXX_EXTRA_FLAGS} -Wno-unsequenced -Wno-switch -Wno-deprecated-declarations -Wno-inconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-dangling-else -Wno-braced-scalar-init -fexceptions -fvisibility=hidden -I${COMPILER_ROOT}/include/c++/4.9.x -D__ANDROID_API__=${ANDROID_NATIVE_API_LEVEL}")
set(CMAKE_MODULE_LINKER_FLAGS " ${ANDROID_STATIC_FLAG} ")
set(CMAKE_CONFIGURE_COMMAND "--host=${ANDROID_TRIPLE}${ANDROID_NATIVE_API_LEVEL}" "--prefix=${CMAKE_INSTALL_PREFIX}" "--with-sysroot=${CMAKE_SYSROOT}" "CC=${CMAKE_C_COMPILER}" "CXXFLAGS=${CMAKE_CXX_FLAGS}" "CFLAGS=${CMAKE_C_FLAGS}" "${SHARED_FLAG}" "${STATIC_FLAG}")
set(CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${ANDROID_STATIC_FLAG} ${LOG_LIB}")
set(CMAKE_STATIC_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${ANDROID_STATIC_FLAG} ${LOG_LIB}")
if (NOT EXISTS COMPILER_ROOT)
message(STATUS "Installing standalone toochain for ${ANDROID_SYSROOT_ABI} apilevel-${ANDROID_NATIVE_API_LEVEL} ...")
execute_process(COMMAND python ${ANDROID_NDK}/build/tools/make_standalone_toolchain.py --arch ${ANDROID_SYSROOT_ABI} --api ${ANDROID_NATIVE_API_LEVEL} --install-dir ${COMPILER_ROOT})
endif ()
unset(CMAKE_C_COMPILER)
unset(CMAKE_CXX_COMPILER)
set(CMAKE_AR ${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-ar)
set(CMAKE_NM ${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-nm)
set(CMAKE_OBJCOPY ${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-objcopy)
set(CMAKE_RANLIB ${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-ranlib)
set(CMAKE_STRIP "${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-strip")
set(CMAKE_LINKER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-ld")
set(CMAKE_C_COMPILER ${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-gcc)
set(CMAKE_CXX_COMPILER ${ANDROID_LLVM_TOOLCHAIN_PREFIX}${ANDROID_TRIPLE}-g++)
set(ENV{PATH} ${COMPILER_ROOT}/bin:$ENV{PATH})
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/lib/pkgconfig)
LIST(APPEND CMAKE_PROGRAM_PATH ${COMPILER_ROOT}/bin)
list(APPEND CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX})
list(APPEND CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/lib)
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT})
set(CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/lib)
#sanity check
find_library(LOG_LIB log REQUIRED)
#/home/anthony/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/home/anthony/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules")
message(STATUS "Current ANDROID_NATIVE_API_LEVEL ${ANDROID_NATIVE_API_LEVEL}")
message(STATUS "Current ANDROID_PLATFORM ${ANDROID_PLATFORM}")
message(STATUS "Current CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}")
message(STATUS "Current LOG_INCLUDE_DIR ${LOG_INCLUDE_DIR}")
message(STATUS "Current LOG_LIB ${LOG_LIB}")
message(STATUS "Current CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}")
message(STATUS "Current ANDROID_NDK ${ANDROID_NDK}")
message(STATUS "Current COMPILER_ROOT ${COMPILER_ROOT}")
message(STATUS "Current CMAKE_SYSROOT ${CMAKE_SYSROOT}")
message(STATUS "Current ANDROID_ABI ${ANDROID_ABI}")
message(STATUS "Current ANDROID_NATIVE_API_LEVEL ${ANDROID_NATIVE_API_LEVEL}")
message(STATUS "Current CMAKE_C_COMPILER ${CMAKE_C_COMPILER}")
message(STATUS "Current CMAKE_C_FLAGS ${CMAKE_C_FLAGS}")
message(STATUS "Current CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}")
message(STATUS "Current ENV PATH $ENV{PATH}")
message(STATUS "Current TMP_DIR ${TMP_DIR}")
message(STATUS "Current STAMP_DIR ${STAMP_DIR}")
message(STATUS "Current CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}")
message(STATUS "Current CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "Current CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Current CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}")
message(STATUS "Current CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}")
message(STATUS "Current CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}")
list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}")
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT})
# Get all propreties that cmake supports
execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE CMAKE_PROPERTY_LIST)
# Convert command output into a CMake list
STRING(REGEX REPLACE ";" "\\\\;" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}")
STRING(REGEX REPLACE "\n" ";" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}")
function(print_properties)
message(STATUS "properties: CMAKE_PROPERTY_LIST = ${CMAKE_PROPERTY_LIST}")
endfunction(print_properties)
function(print_target_properties tgt)
if (NOT TARGET ${tgt})
message(ERROR "There is no target named '${tgt}'")
return()
endif ()
foreach (prop ${CMAKE_PROPERTY_LIST})
string(REPLACE "<CONFIG>" "${CMAKE_BUILD_TYPE}" prop ${prop})
if (prop STREQUAL "LOCATION" OR prop MATCHES "^LOCATION_" OR prop MATCHES "_LOCATION$")
continue()
endif ()
get_property(propval TARGET ${tgt} PROPERTY ${prop} SET)
if (propval)
get_target_property(propval ${tgt} ${prop})
message(STATUS "${tgt} ${prop} = ${propval}")
endif ()
endforeach (prop)
endfunction(print_target_properties)
endif ()
@claydonkey
Copy link
Author

Example arguments
"-DCMAKE_BUILD_TYPE=Debug"
"-DANDROID=ON"
"-DANDROID_PLATFORM=android-24"
"-DCMAKE_INSTALL_PREFIX=/usr"
"-DANDROID_ABI=x86"
Not required "-DANDROID_NATIVE_API_LEVEL=24"

        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment