I'm using android-cmake to compile an application for Android. This essentially creates a CMake toolchain file for using the toolchain provided with Android's NDK.
As with this related question, I'm having problems with the following line in my CMakeLists.txt file:
find_package(Threads REQUIRED)
The header file is located at
~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/include/pthread.h
The library file is located at
~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/lib/libthread_db.so
The problem is that FindThreads.cmake calls CHECK_INCLUDE_FILES("pthread.h", CMAKE_HAVE_PTHREAD_H)
and this seems to not bother to check in that directory.
According to CMake's Useful Variables wiki page CMAKE_INCLUDE_PATH
allows the setting of the header search path, CMAKE_LIBRARY_PATH
allows setting of the library search path, and CMAKE_PREFIX_PATH
seems provide both for find_package.
However, despite whether I set environment variables before running cmake...
export CMAKE_INCLUDE_PATH=~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr:~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/include
... or whether I set them directly in CMakeLists.txt...
if(ANDROID)
set(CMAKE_INCLUDE_PATH
${ANDROID_NDK_SYSROOT}/usr
${ANDROID_NDK_SYSROOT}/usr/include
${CMAKE_INCLUDE_PATH}
)
set(CMAKE_LIBRARY_PATH
${ANDROID_NDK_SYSROOT}/usr
${ANDROID_NDK_SYSROOT}/usr/lib
${CMAKE_LIBRARY_PATH})
set(CMAKE_PREFIX_PATH
${ANDROID_NDK_SYSROOT}
${CMAKE_PREFIX_PATH})
message(${ANDROID_NDK_SYSROOT})
message(${CMAKE_INCLUDE_PATH})
endif()
find_package(Threads REQUIRED)
... (and this does get executed, the messages are printed), and where ${ANDROID_NDK_SYSROOT}
contains
/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm
I still get the message
Could NOT find Threads (missing: Threads_FOUND)
Does anybody have any suggestions as to what I am doing wrong?
Setting CMAKE_INCLUDE_PATH
will only affect the CMake find_file
and find_path
commands. The CHECK_INCLUDE_FILES
function called by FindThreads.cmake does not honor that variable. For CHECK_INCLUDE_FILES
you can set the variable CMAKE_REQUIRED_INCLUDES
instead:
set(CMAKE_REQUIRED_INCLUDES
${ANDROID_NDK_SYSROOT}/usr
${ANDROID_NDK_SYSROOT}/usr/include)
I found the solution to this problem after a lot of debugging and it's quite strange. Essentially, FindThreads.cmake calls a macro called CHECK_INCLUDE_FILES
which tries to TRY_COMPILE
a source file which simply includes the headers that the CHECK_INCLUDE_FILES
macro is provided with.
Note that it does use CMAKE_REQUIRED_INCLUDES
as suggested by @sakra so that's useful.
Using android-cmake, the TRY_COMPILE
macro tries to compile with the arm-linux-androideabi-gcc compiler from the NDK with all of the specified compile flags. The android.toolchain.cmake file contains the following lines that set some of these compile flags:
if( BUILD_WITH_ANDROID_NDK )
set( CMAKE_CXX_FLAGS "--sysroot=\"${ANDROID_NDK_SYSROOT}\" ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "--sysroot=\"${ANDROID_NDK_SYSROOT}\" ${CMAKE_C_FLAGS}" )
The TRY_COMPILE macro fails and as per the CMakeError.log file contains the following:
Run Build Command:/opt/local/bin/gmake "cmTryCompileExec/fast"
/opt/local/bin/gmake -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build
gmake[1]: Entering directory '/Users/martin/Repositories/Delta/build/android/CMakeFiles/CMakeTmp'
"/Applications/CMake 2.8-4.app/Contents/bin/cmake" -E cmake_progress_report /Users/martin/Repositories/Delta/build/android/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o
/Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc --sysroot=;/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm" -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -march=armv7-a -mfloat-abi=softfp " -I/Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -I/Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include -I/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm/usr -I/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -c /Users/martin/Repositories/Delta/build/android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c
arm-linux-androideabi-gcc: no input files
If you scroll to the right on the actual compiler line (second from the bottom) you can see the --sysroot=;/...
section. Even though the CMake lines above use escaped strings, CMake has turned this first escaped quotation into a semicolon and left the second as a normal quotation, resulting in a semicolon in the sysroot line and then a string literal containing all the CMAKE_CXX_FLAGS afterwards (easy to see with SO's syntax highlighting).
The solution to this is to modify android.toolchain.cmake to remove the escaped quotations as they are unnecessary.
if( BUILD_WITH_ANDROID_NDK )
set( CMAKE_CXX_FLAGS "--sysroot=${ANDROID_NDK_SYSROOT} ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "--sysroot=${ANDROID_NDK_SYSROOT} ${CMAKE_C_FLAGS}" )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With