CMake FindThreads.cmake won't find my pthreads.h header

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}" )

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)

Tags:

Android

Cmake