CMake FindThreads.cmake не найдет мой заголовок pthreads.h - PullRequest
4 голосов
/ 05 декабря 2011

Я использую android-cmake для компиляции приложения для Android.По сути, это создает файл набора инструментов CMake для использования набора инструментов, поставляемого с Android NDK.

Как и в случае этого связанного вопроса , у меня возникли проблемы со следующей строкой в ​​моем файле 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 CMAKE_INCLUDE_PATH позволяет установить путь поиска заголовка, CMAKE_LIBRARY_PATH позволяет установитьПуть поиска в библиотеке и, по-видимому, CMAKE_PREFIX_PATH обеспечивают оба для find_package.

Однако, несмотря на то, устанавливаю ли я переменные среды перед запуском 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

Iвсе еще получаю сообщение

Не удалось найти темы (отсутствует: Threads_FOUND)

У кого-нибудь есть предложения относительно того, что я делаю неправильно?

Ответы [ 2 ]

4 голосов
/ 07 декабря 2011

Я нашел решение этой проблемы после долгих отладок, и это довольно странно. По сути, FindThreads.cmake вызывает макрос с именем CHECK_INCLUDE_FILES, который пытается TRY_COMPILE исходный файл, который просто включает заголовки, которыми снабжен макрос CHECK_INCLUDE_FILES.

Обратите внимание, что он действительно использует CMAKE_REQUIRED_INCLUDES, как предлагает @sakra, так что это полезно.

Используя android-cmake, макрос TRY_COMPILE пытается компилироваться с помощью компилятора arm-linux-androideabi-gcc из NDK со всеми указанными флагами компиляции. Файл 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}" )
3 голосов
/ 05 декабря 2011

Настройка CMAKE_INCLUDE_PATH влияет только на команды CMake FIND_FILE и FIND_PATH . Функция CHECK_INCLUDE_FILES, вызываемая FindThreads.cmake, не поддерживает эту переменную. Для CHECK_INCLUDE_FILES вы можете установить переменную CMAKE_REQUIRED_INCLUDES вместо:

set(CMAKE_REQUIRED_INCLUDES 
  ${ANDROID_NDK_SYSROOT}/usr 
  ${ANDROID_NDK_SYSROOT}/usr/include)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...