CMake FIND_PACKAGE успешно завершен, но возвращает неправильный путь
Я пытаюсь использовать ссылку CMake 2.8.6 для boost:: program_options, используя следующий код в CMakeLists.txt
FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIR})
ADD_EXECUTABLE (segment segment.cpp)
TARGET_LINK_LIBRARIES (segment ${Boost_LIBRARIES})
Команда find кажется успешной, но передает компоновщику неправильный каталог. Пакет фактически находится в папке
`/usr/lib64/libboost_program_options-mt.so.5`
но CMakeFiles/segment.dir/link.txt
перечисляет следующее:
/cm/shared/apps/gcc/4.4.6/bin/c++ CMakeFiles/segment.dir/segment.cpp.o -o segment -rdynamic /usr/lib64/lib64/libboost_program_options-mt.so.5 -lpthread -lrt -Wl,-rpath,/usr/lib64/lib64
Обратите внимание на дополнительный lib64
в пути. Кроме того, флаг -l перед дорогой кажется отсутствующим.
При запуске CMake он сообщает, что он правильно находит пакет, а переменная {$Boost_LIBRARIES}
, как представляется, перечисляет правильные библиотеки:
Boost found.
Found Boost components:
program_options
${Boost_LIBRARIES} - optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug
Сгенерированный файл CMakeCache.txt начинается с:
//The directory containing a CMake configuration file for Boost.
Boost_DIR:PATH=/usr/lib64/boost
//Boost include directory
Boost_INCLUDE_DIR:FILEPATH=/usr/include
Что кажется правильным. Но при запуске make он использует путь в link.txt выше, и я получаю ошибку:
make[2]: *** No rule to make target `/usr/lib64/lib64/libboost_program_options-mt.so.5', needed by `segment'. Stop.
make[1]: *** [CMakeFiles/segment.dir/all] Error 2
make: *** [all] Error 2
Что может вызвать эту дополнительную инъекцию субдира в путь? Что может вызвать создание link.txt таким образом? И как мне исправить (или обойти его)?
Ответы
Ответ 1
Эта проблема возникает при использовании некоторых более старых версий boost с cmake-2.8.6-rc2
или более поздней версией, где был изменен код поиска пакета boost.
Проблема может быть решена путем указания -DBoost_NO_BOOST_CMAKE=ON
в командной строке cmake.
Фактическая фиксация, где вводится эта проблема, - 7da796d1fdd7cca07df733d010cd343f6f8787a9 и может быть просмотрена здесь.
Ответ 2
Проблема заключается в распределенном файле boost-devel:/usr/lib64/boost/Boost-relwithdebinfo.cmake
Пакет cmake-2.6 вообще не использует этот файл, потому что файл FindBoost.cmake возвращает (правильные) полные пути для расширения библиотек. Файл cmake28-2.8.8 FindBoost.cmake возвращает строки библиотеки, такие как "boost_date_time-mt-shared", которые являются объектами, определенными в /usr/lib 64/boost/Boost-relwithdebinfo.cmake.
В самой верхней части /usr/lib 64/boost/Boost-relwithdebinfo.cmake переменная с именем _IMPORT_PREFIX определяется из местоположения самого файла cmake и затем используется так:
#----------------------------------------------------------------
# Generated CMake target import file for configuration "RelWithDebInfo".
#----------------------------------------------------------------
# Commands may need to know the format version.
SET(CMAKE_IMPORT_FILE_VERSION 1)
# Compute the installation prefix relative to this file.
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Import target "boost_date_time-static" for configuration "RelWithDebInfo"
SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES
IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a"
)
Это устанавливает _IMPORT_PREFIX в "/usr/lib64", который соединен с другой строкой, в которой есть /lib 64/. Я обнаружил, что если просто изменить файл, чтобы включить третий вызов GET_FILENAME_COMPONENT, он отлично работает. Например:
#----------------------------------------------------------------
# Generated CMake target import file for configuration "RelWithDebInfo".
#----------------------------------------------------------------
# Commands may need to know the format version.
SET(CMAKE_IMPORT_FILE_VERSION 1)
# Compute the installation prefix relative to this file.
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Import target "boost_date_time-static" for configuration "RelWithDebInfo"
SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES
IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a"
)
Ответ 3
Это похоже на проблему с CMake 2.8.6 на CentOS. Выполняя то же самое с 2.6.4 или 2.8.3, он работает правильно. Также с 2.8.7 на OS X он также работает правильно.
Ответ 4
Я также вижу проблему с предварительно скомпилированной версией cmake версии 2.8.8 с использованием CentOS 64-bit 6.2
Ответ 5
Я заметил эту проблему на cmake версии 2.8.11.2 с boost-1.41.0-18.el6.x86_64
Утвержденный ответ не кажется удовлетворительным, потому что добавление этого параметра определяет время выполнения cmake:
Предупреждение CMake: Указанные вручную переменные не использовались проектом:
Boost_NO_BOOST_CMAKE
Я не могу комментировать или понижать из-за недостаточного участия в stackoverflow. Это проблема с курицей и яйцом!
Я также, похоже, не могу выдвинуть объяснения Кай Майер. Однако, я думаю, это действительно объясняет проблему.
Из того, что я собираю, кажется, что в итоге, FindBoost.cmake, предоставленный CMake, кажется, внезапно не находит Boost, поэтому код find теперь ищет через boost при условии script для cmake, который в turn имеет ошибку и, кажется, не возвращает правильный путь.