Cmake - find_library - расположение пользовательской библиотеки
В настоящее время я пытаюсь запустить CMake для моего проекта (в окнах). Я хочу использовать настраиваемое место, где установлены все библиотеки. Чтобы сообщить CMake об этом пути, я попытался сделать это:
set(CMAKE_PREFIX_PATH D:/develop/cmake/libs)
Но когда я пытаюсь найти библиотеку с
find_library(CURL_LIBRARY NAMES curl curllib libcurl_imp curllib_static)
CMake не может найти его.
Когда я устанавливаю свой префиксный путь на
set(CMAKE_PREFIX_PATH D:/develop/cmake/libs/curl)
... находится библиотека.
Итак, мой вопрос:
Как я могу правильно настроить CMake для работы с структурированным каталогом в настраиваемом месте, которое выглядит так:
D:/develop/cmake/libs/
-> libA
-> include
-> lib
-> libB
-> include
-> lib
-> ...
-> include
-> lib
В "include" лежат публичные заголовки, а в "lib" - скомпилированные библиотеки.
Надеюсь, кто-то может мне помочь - Спасибо заранее
изменить:
Нынешний обходной путь для меня - сделать это, прежде чем я буду искать библиотеки:
set(CUSTOM_LIBRARY_PATH D:/develop/cmake/libs)
file(GLOB sub-dir ${CUSTOM_LIBRARY_PATH}/*)
foreach(dir ${sub-dir})
if(IS_DIRECTORY ${dir})
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir})
endif()
endforeach()
Но таким образом модуль по умолчанию для повышения не найдет его до тех пор, пока структура каталогов boost не будет немного отличаться.
boost -> include -> boost-1_50 -> *.hpp
Когда я перемещаю содержимое, если "boost-1_50" "включить", библиотека может быть найдена, но таким образом невозможно обрабатывать несколько версий правильно?
Ответы
Ответ 1
Я видел, что два человека задали этот вопрос своим избранникам, поэтому я постараюсь ответить на решение, которое работает для меня:
Вместо использования модулей поиска я пишу файлы конфигурации для всех установленных библиотек. Эти файлы чрезвычайно просты и могут также использоваться для установки нестандартных переменных. CMake будет (по крайней мере, в Windows) искать эти файлы конфигурации в
CMAKE_PREFIX_PATH/<<package_name>>-<<version>>/<<package_name>>-config.cmake
(который может быть задан через переменную окружения).
Так, например, форсированная конфигурация находится на пути
CMAKE_PREFIX_PATH/boost-1_50/boost-config.cmake
В этой конфигурации вы можете установить переменные. Мой конфигурационный файл для boost выглядит следующим образом:
set(boost_INCLUDE_DIRS ${boost_DIR}/include)
set(boost_LIBRARY_DIR ${boost_DIR}/lib)
foreach(component ${boost_FIND_COMPONENTS})
set(boost_LIBRARIES ${boost_LIBRARIES} debug ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-gd-1_50.lib)
set(boost_LIBRARIES ${boost_LIBRARIES} optimized ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-1_50.lib)
endforeach()
add_definitions( -D_WIN32_WINNT=0x0501 )
Довольно прямо вперед +, возможно даже уменьшить размер конфигурационных файлов, когда вы пишете некоторые вспомогательные функции. Единственная проблема, с которой я сталкиваюсь с этой настройкой, - это то, что я не нашел способ предоставить конфигурационным файлам приоритет над модулями поиска, поэтому вам нужно удалить модули поиска.
Надеюсь, это поможет другим людям.
Ответ 2
Простейшим решением может быть добавление HINTS
в каждый find_*
запрос.
Например:
find_library(CURL_LIBRARY
NAMES curl curllib libcurl_imp curllib_static
HINTS "${CMAKE_PREFIX_PATH}/curl/lib"
)
Для Boost я настоятельно рекомендую использовать стандартный модуль FindBoost и установить переменную BOOST_DIR
для указания на ваши библиотеки Boost.
Ответ 3
Невозможно автоматически установить CMAKE_PREFIX_PATH
так, как вы хотите. Я вижу следующие способы решения этой проблемы:
-
Поместите все файлы библиотек в один каталог. То есть include/
будет содержать заголовки для всех библиотек, lib/
- двоичные файлы и т.д. FYI, это общий макет для большинства UNIX-подобных систем.
-
Установите глобальную переменную окружения CMAKE_PREFIX_PATH
в D:/develop/cmake/libs/libA;D:/develop/cmake/libs/libB;...
. Когда вы запускаете CMake, он автоматически подберет этот env var и заполнит его собственный CMAKE_PREFIX_PATH
.
-
Напишите обертку .bat script, которая вызовет команду cmake
с аргументом -D CMAKE_PREFIX_PATH=...
.
Ответ 4
У вас есть один дополнительный уровень гнездования.
CMAKE будет искать в $CMAKE_PREFIX_PATH/include
для заголовков и $CMAKE_PREFIX_PATH/libs
для библиотек.
Из CMAKE документация:
Для каждого пути в списке CMAKE_PREFIX_PATH CMake будет проверять "PATH/include" и "PATH", когда вызывается FIND_PATH(), "PATH/bin" и "PATH", когда вызывается FIND_PROGRAM(), и "PATH/lib и" PATH ", когда Вызывается FIND_LIBRARY().
Ответ 5
Используйте CMAKE_PREFIX_PATH, добавив несколько путей (разделенных точкой с запятой и без пробелов). Вы можете установить его как переменную окружения, чтобы избежать абсолютных путей в конфигурационных файлах cmake.
Обратите внимание, что cmake будет искать конфигурационный файл в любом из следующих папок
где любой из путей в CMAKE_PREFIX_PATH, а имя - это имя библиотеки, которую вы ищете
<prefix>/ (W)
<prefix>/(cmake|CMake)/ (W)
<prefix>/<name>*/ (W)
<prefix>/<name>*/(cmake|CMake)/ (W)
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/ (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)
В вашем случае вам нужно добавить в CMAKE_PREFIX_PATH следующие два пути:
D:/develop/cmake/libs/libA;D:/develop/cmake/libB
Ответ 6
Я столкнулся с похожим сценарием. Я решил это, добавив в этот следующий код непосредственно перед find_library()
:
set(CMAKE_PREFIX_PATH /the/custom/path/to/your/lib/)
то он может найти расположение библиотеки.