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 имеет ошибку и, кажется, не возвращает правильный путь.