Подтвердить что ты не робот

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" "включить", библиотека может быть найдена, но таким образом невозможно обрабатывать несколько версий правильно?

4b9b3361

Ответ 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/)

то он может найти расположение библиотеки.