CMake FindThreads.cmake将找不到我的pthreads.h标头

时间:2011-12-05 14:35:27

标签: android cmake

我正在使用android-cmake来编译Android应用程序。这实际上创建了一个CMake工具链文件,用于使用Android NDK提供的工具链。

this related question一样,我的CMakeLists.txt文件中的以下行出现问题:

find_package(Threads REQUIRED)

头文件位于

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

库文件位于

~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/lib/libthread_db.so

问题是FindThreads.cmake调用了CHECK_INCLUDE_FILES("pthread.h", CMAKE_HAVE_PTHREAD_H),这似乎没有办法检查该目录。

根据CMake's Useful Variables wiki page CMAKE_INCLUDE_PATH允许设置标题搜索路径,CMAKE_LIBRARY_PATH允许设置库搜索路径,CMAKE_PREFIX_PATH似乎同时为find_package提供。< / p>

但是,尽管我在运行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

...或者我是否直接在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)

...(这会执行,打印消息),${ANDROID_NDK_SYSROOT}包含

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

我仍然收到消息

  

无法找到线程(缺少:Threads_FOUND)

有人对我做错了什么有任何建议吗?

2 个答案:

答案 0 :(得分:4)

经过大量调试后我找到了解决这个问题的方法,这很奇怪。从本质上讲,FindThreads.cmake调用一个名为CHECK_INCLUDE_FILES的宏,它会尝试TRY_COMPILE一个源文件,该文件只包含提供CHECK_INCLUDE_FILES宏的标头。

请注意,它确实使用@sakra建议的CMAKE_REQUIRED_INCLUDES,因此非常有用。

使用android-cmake,TRY_COMPILE宏尝试使用带有所有指定编译标志的NDK中的arm-linux-androideabi-gcc编译器进行编译。 android.toolchain.cmake文件包含以下行,用于设置其中一些编译标志:

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

TRY_COMPILE宏失败,根据CMakeError.log文件包含以下内容:

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

如果您在实际编译器行上向右滚动(从底部开始第二个),您可以看到--sysroot=;/...部分。即使上面的CMake行使用转义字符串,CMake已将第一个转义的引号转换为分号,并将第二个作为正常引号,导致sysroot行中的分号,然后是包含所有CMAKE_CXX_FLAGS的字符串文字(易于请参阅SO的语法突出显示)。

解决方案是修改android.toolchain.cmake以删除转义的引文,因为它们是不必要的。

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

答案 1 :(得分:3)

设置CMAKE_INCLUDE_PATH只会影响CMake FIND_FILEFIND_PATH命令。 FindThreads.cmake调用的CHECK_INCLUDE_FILES函数不支持该变量。对于CHECK_INCLUDE_FILES,您可以设置变量CMAKE_REQUIRED_INCLUDES

set(CMAKE_REQUIRED_INCLUDES 
  ${ANDROID_NDK_SYSROOT}/usr 
  ${ANDROID_NDK_SYSROOT}/usr/include)