[cmake-developers] [RFC] FindAndroidNDK and UseAndroidNDK
Xiaolei Yu
dreifachstein at gmail.com
Sat Mar 12 04:05:58 EST 2016
Hello,
my team decided to ditch ndk-build and migrate to cmake. And I would
like to upstream these two modules, which are currently used in my hobby
projects.
They are intended to be used by custom toolchain files in place of
android.cmake. The goal is to preserve as much information as possible
as I am using a cmake super build to drive dozens of external projects,
while android.cmake merges most info into linker and c/cxx flags.
I am aware of the code style problems and will fix them in the formal
patch. In this mail I am seeking your feedbacks on several issues:
1. using CMAKE_LIBRARY_ARCHITECTURE to represent android
TARGET_ARCH_ABI. The way android handles native libraries is similar to
debian multiarch and I am reusing this property.
Android-GNU-{C, CXX}.cmake will setup compiler flags based on it. I can
think of another use case when a super build decides where to pull
prebuilt blobs.
2. clang support is lacking. I am not using clang for android but can
add the support if deemed necessary.
3. the FindAndroidNDK module is saving many values and I am not sure if
all of them are worth to keep.
Best Regards
-------------- next part --------------
macro ( android_use_cxx_gnustl variant version )
set ( _gnustl ${ANDROID_NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/${version} )
if ( "${variant}" STREQUAL "SHARED" )
set ( CMAKE_CXX_STANDARD_LIBRARIES_INIT
${_gnustl}/libs/${CMAKE_LIBRARY_ARCHITECTURE}/libgnustl_shared.so
)
elseif ( "${variant}" STREQUAL "STATIC" )
set ( CMAKE_CXX_STANDARD_LIBRARIES_INIT
${_gnustl}/libs/${CMAKE_LIBRARY_ARCHITECTURE}/libgnustl_static.a
${_gnustl}/libs/${CMAKE_LIBRARY_ARCHITECTURE}/libsupc++.a
)
else ()
message ( FATAL_ERROR "invalid gnustl variant: ${variant}")
endif ()
include_directories ( SYSTEM
${_gnustl}/libs/${CMAKE_LIBRARY_ARCHITECTURE}/include
${_gnustl}/include
)
endmacro ()
macro ( android_use_toolchain version )
set ( CMAKE_C_COMPILER ${AndroidNDK_GNU_CROSSPREFIX_${version}}gcc )
set ( CMAKE_CXX_COMPILER ${AndroidNDK_GNU_CROSSPREFIX_${version}}g++ )
endmacro ()
-------------- next part --------------
cmake_minimum_required ( VERSION 3.4 )
set ( _target_arch_abi_list
armeabi armeabi-v7a armeabi-v7a-hard arm64
x86 x86_64 mips mips64
)
if ( NOT "${CMAKE_LIBRARY_ARCHITECTURE}" IN_LIST _target_arch_abi_list )
message ( FATAL_ERROR "invalid value: CMAKE_LIBRARY_ARCHITECTURE=${CMAKE_LIBRARY_ARCHITECTURE}" )
endif ()
set ( _target_arch_list
arm arm64
x86 x86_64
mips mips64
)
set ( _target_arch )
set ( _gnu_mach )
set ( _gnu_os )
set ( _gnu_toolchain_name )
if ( CMAKE_LIBRARY_ARCHITECTURE MATCHES "^armeabi" )
set ( _target_arch arm )
set ( _gnu_mach arm )
set ( _gnu_os linux-androideabi )
elseif ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL "arm64-v8a" )
set ( _target_arch arm64 )
set ( _gnu_mach aarch64 )
elseif ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL "mips" )
set ( _gnu_mach mipsel )
elseif ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL "mips64" )
set ( _gnu_mach mips64el )
elseif ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL "x86" )
set ( _gnu_mach i686 )
set ( _gnu_toolchain_name x86 )
elseif ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL "x86_64" )
set ( _gnu_toolchain_name x86_64 )
endif ()
if ( NOT _target_arch )
set ( _target_arch ${CMAKE_LIBRARY_ARCHITECTURE} )
endif ()
if ( NOT _gnu_mach )
set ( _gnu_mach ${CMAKE_LIBRARY_ARCHITECTURE} )
endif ()
if ( NOT _gnu_os )
set ( _gnu_os linux-android )
endif ()
set ( _gnu_triplet ${_gnu_mach}-${_gnu_os} )
if ( NOT _gnu_toolchain_name )
set ( _gnu_toolchain_name ${_gnu_triplet} )
endif ()
macro ( _do_find_info )
file ( READ ${ANDROID_NDK_ROOT}/RELEASE.TXT _release_txt_str )
string ( REGEX MATCH "^r[^ ]+" AndroidNDK_VERSION_STRING ${_release_txt_str} )
if ( ${_release_txt_str} MATCHES "64\\-bit" )
set ( AndroidNDK_64BIT TRUE )
else ()
set ( AndroidNDK_64BIT FALSE )
endif ()
set ( AndroidNDK_64BIT ${AndroidNDK_64BIT} CACHE BOOL "64-bit" )
find_path ( AndroidNDK_HOST_PREBUILT_DIR bin
PATHS ${ANDROID_NDK_ROOT}/prebuilt/*
NO_DEFAULT_PATH
)
get_filename_component ( AndroidNDK_HOST
${AndroidNDK_HOST_PREBUILT_DIR} NAME CACHE
)
endmacro ()
macro ( _do_find_sysroot )
file ( GLOB _sysroot_list RELATIVE "${ANDROID_NDK_ROOT}/"
"${ANDROID_NDK_ROOT}/platforms/android-*/arch-${_target_arch}"
)
foreach ( _sysroot ${_sysroot_list} )
string ( REGEX REPLACE ".*/android-(.*)/.*" "\\1" _sysroot_version "${_sysroot}" )
set ( AndroidNDK_SYSROOT_${_sysroot_version}
${ANDROID_NDK_ROOT}/${_sysroot} CACHE PATH
"SYSROOT ${_sysroot_version}"
)
mark_as_advanced ( AndroidNDK_SYSROOT_${_sysroot_version} )
endforeach ()
endmacro ()
macro ( _do_find_gnu_toolchain )
file ( GLOB _gnu_toolchain_list RELATIVE "${ANDROID_NDK_ROOT}/"
"${ANDROID_NDK_ROOT}/toolchains/${_gnu_toolchain_name}-[0-9].[0-9]/prebuilt/${AndroidNDK_HOST}"
)
set ( AndroidNDK_GNU_TRIPLET ${_gnu_triplet} CACHE PATH "target triplet" )
mark_as_advanced ( AndroidNDK_GNU_TRIPLET )
foreach ( toolchain ${_gnu_toolchain_list} )
string ( REGEX REPLACE ".*-([0-9]\.[0-9])/prebuilt/.*" "\\1"
_toolchain_version "${toolchain}"
)
set ( AndroidNDK_GNU_TOOLCHAIN_${_toolchain_version}
${ANDROID_NDK_ROOT}/${toolchain} CACHE PATH
"GNU TOOLCHAIN ${_toolchain_version}"
)
mark_as_advanced ( AndroidNDK_GNU_TOOLCHAIN_${_toolchain_version} )
set ( AndroidNDK_GNU_CROSSPREFIX_${_toolchain_version}
${AndroidNDK_GNU_TOOLCHAIN_${_toolchain_version}}/bin/${_gnu_triplet}- CACHE STRING
"GNU CROSSPREFIX ${_toolchain_version}"
)
mark_as_advanced ( AndroidNDK_GNU_TOOLCHAIN_${_toolchain_version} )
endforeach ()
endmacro ()
find_file ( AndroidNDK_NDK_BUILD ndk-build
PATHS ${ANDROID_NDK_ROOT} $ENV{ANDROID_NDK_ROOT}
)
mark_as_advanced ( AndroidNDK_NDK_BUILD )
if ( AndroidNDK_NDK_BUILD )
get_filename_component ( ANDROID_NDK_ROOT ${AndroidNDK_NDK_BUILD} DIRECTORY )
set ( ANDROID_NDK_ROOT "${ANDROID_NDK_ROOT}" CACHE STRING "Android NDK" )
_do_find_info ()
_do_find_sysroot ()
_do_find_gnu_toolchain ()
endif ()
include ( FindPackageHandleStandardArgs )
find_package_handle_standard_args ( AndroidNDK
FOUND_VAR AndroidNDK_FOUND
REQUIRED_VARS ANDROID_NDK_ROOT AndroidNDK_HOST
VERSION_VAR AndroidNDK_VERSION_STRING
HANDLE_COMPONENTS
)
-------------- next part --------------
set ( lang CXX )
include ( Platform/Android-GNU )
-------------- next part --------------
set ( lang C )
include ( Platform/Android-GNU )
-------------- next part --------------
if ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL armeabi-v7a )
set ( compiler_flags "-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp" )
set ( linker_flags "-lm" )
elseif ( CMAKE_LIBRARY_ARCHITECTURE STREQUAL armeabi-v7a-hard )
set ( compiler_flags "-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard -D_NDK_MATH_NO_SOFTFP=1" )
set ( linker_flags "-lm_hard -Wl,--no-warn-mismatch" )
else ()
set ( compiler_flags )
set ( linker_flags )
endif ()
set ( compiler_flags "${compiler_flags} -DANDROID" )
foreach ( build_type DEBUG MINSIZEREL RELEASE RELWITHDEBINFO )
set ( CMAKE_${lang}_FLAGS_${build_type}_INIT "${CMAKE_${lang}_FLAGS_${build_type}_INIT} ${compiler_flags}" )
endforeach ()
if ( linker_flags )
set ( CMAKE_${lang}_STANDARD_LIBRARIES_INIT "${CMAKE_${lang}_STANDARD_LIBRARIES_INIT} ${linker_flags}" )
endif ()
More information about the cmake-developers
mailing list