CMake FindThreads.cmake will not find the pthreads.h header

I am using android-cmake to compile an android application. This essentially creates a CMake toolchain file to use the tool chain that comes with the Android NDK.

As in this related question , I am having problems with the following line in the CMakeLists.txt file:

find_package(Threads REQUIRED) 

The header file is in

 ~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/include/pthread.h 

The library file is in

 ~/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 does not seem to bother checking in this directory.

According to the CMake useful variables wiki page , CMAKE_LIBRARY_PATH allows CMAKE_LIBRARY_PATH to set the title search path, CMAKE_LIBRARY_PATH allows CMAKE_LIBRARY_PATH to set the library search path, and CMAKE_PREFIX_PATH appears as for find_package.

However, despite the fact that 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 I install 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 runs, messages are printed) and where ${ANDROID_NDK_SYSROOT} contains

 /Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm 

I'm still getting a message

Could not find threads (missing: Threads_FOUND)

Does anyone have any suggestions regarding what I am doing wrong?

+4
source share
2 answers

I found a solution to this problem after a lot of debugging, and it is rather strange. Essentially, FindThreads.cmake calls a macro called CHECK_INCLUDE_FILES , which tries to TRY_COMPILE source file, which simply includes the headers that are provided with the CHECK_INCLUDE_FILES macro.

Please note that it uses CMAKE_REQUIRED_INCLUDES as suggested by @sakra, so it is useful.

Using android-cmake, the TRY_COMPILE macro tries to compile with the arm-linux-androideabi-gcc compiler from the NDK with all the specified compilation flags. The android.toolchain.cmake file contains the following lines that set some of these compilation 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 macro failure TRY_COMPILE and according to 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.co /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.co -c /Users/martin/Repositories/Delta/build/android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c arm-linux-androideabi-gcc: no input files 

If you go right on the actual line of the compiler (second from the bottom), you can see the section --sysroot=;/... Although the above CMake strings use escaped strings, CMake turned this first escaped quote into a semicolon and left the second as a normal quote, resulting in a semicolon in the sysroot string, and then a string literal containing all CMAKE_CXX_FLAGS (easy see . with syntax highlighting SO).

The solution to this is to modify android.toolchain.cmake to remove the escaped quotes as they are not needed.

 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}" ) 
+4
source

The CMAKE_INCLUDE_PATH setting CMAKE_INCLUDE_PATH affects CMake FIND_FILE and FIND_PATH . The function CHECK_INCLUDE_FILES , called by FindThreads.cmake, does not execute this variable. Instead of CHECK_INCLUDE_FILES you can set the variable CMAKE_REQUIRED_INCLUDES :

 set(CMAKE_REQUIRED_INCLUDES ${ANDROID_NDK_SYSROOT}/usr ${ANDROID_NDK_SYSROOT}/usr/include) 
+3
source

Source: https://habr.com/ru/post/1384719/


All Articles