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



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 ()
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
)
set ( lang CXX )

include ( Platform/Android-GNU )

set ( lang C )

include ( Platform/Android-GNU )

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 ()

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to