cmake - find_library - 自定义库位置

Dan*_*iel 51 c++ windows cmake

我正在尝试让CMake运行我的项目(在Windows上).我想使用安装所有库的自定义位置.要通知CMake我尝试这样做的路径:

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs)
Run Code Online (Sandbox Code Playgroud)

但是当我试图找到库时

find_library(CURL_LIBRARY NAMES curl curllib libcurl_imp curllib_static)
Run Code Online (Sandbox Code Playgroud)

CMake找不到它.当我将前缀路径设置为

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs/curl)
Run Code Online (Sandbox Code Playgroud)

...图书馆所在地.

所以我的问题是:如何正确配置CMake以在自定义位置使用目录结构,如下所示:

D:/develop/cmake/libs/
-> libA
   -> include
   -> lib
-> libB
   -> include
   -> lib
-> ...
   -> include
   -> lib
Run Code Online (Sandbox Code Playgroud)

在"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()
Run Code Online (Sandbox Code Playgroud)

但是这样,boost的默认模块就不会找到它,因为boost的目录结构有点不同.

boost -> include -> boost-1_50 -> *.hpp
Run Code Online (Sandbox Code Playgroud)

当我移动内容如果"boost-1_50"到"include"时,可以找到库,但是这样就不能处理多个版本了吗?

Sil*_*ker 27

最简单的解决方案可能是添加HINTS到每个find_*请求.

例如:

find_library(CURL_LIBRARY
    NAMES curl curllib libcurl_imp curllib_static
    HINTS "${CMAKE_PREFIX_PATH}/curl/lib"
)
Run Code Online (Sandbox Code Playgroud)

对于Boost,我强烈建议使用FindBoost标准模块并将BOOST_DIR变量设置为指向Boost库.


Dan*_*iel 16

我看到有两个人把这个问题提到他们的最爱,所以我会尝试回答适用于我的解决方案:我没有使用查找模块,而是为所有已安装的库编写配置文件.这些文件极其简单,也可用于设置非标准变量.CMake将(至少在Windows上)搜索那些配置文件

CMAKE_PREFIX_PATH/<<package_name>>-<<version>>/<<package_name>>-config.cmake
Run Code Online (Sandbox Code Playgroud)

(可以通过环境变量设置).例如,升压配置在路径中

CMAKE_PREFIX_PATH/boost-1_50/boost-config.cmake
Run Code Online (Sandbox Code Playgroud)

在该配置中,您可以设置变量.我的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 )
Run Code Online (Sandbox Code Playgroud)

非常简单+当你编写一些辅助函数时,可以缩小配置文件的大小.我对这个设置唯一的问题是我找不到一种方法来给配置文件优先于查找模块 - 所以你需要删除查找模块.

希望这对其他人有帮助.


arr*_*owd 7

无法以CMAKE_PREFIX_PATH您想要的方式自动设置.我看到以下方法来解决这个问题:

  1. 将所有库文件放在同一个目录中.也就是说,include/将包含所有库的标头,lib/- 二进制文件等.FYI,这是大多数类UNIX系统的通用布局.

  2. 将全局环境变量设置CMAKE_PREFIX_PATHD:/develop/cmake/libs/libA;D:/develop/cmake/libs/libB;....当你运行CMake时,它会自动选择这个env var并填充它自己的CMAKE_PREFIX_PATH.

  3. 编写一个包装器.bat脚本,它将cmake使用-D CMAKE_PREFIX_PATH=...参数调用命令.


小智 7

您有一层额外的嵌套。CMAKE 将在下面搜索$CMAKE_PREFIX_PATH/include标题和$CMAKE_PREFIX_PATH/libs库。

从 CMAKE文档

对于 CMAKE_PREFIX_PATH 列表中的每个路径,CMake 将在调用 FIND_PATH() 时检查“PATH/include”和“PATH”,在调用 FIND_PROGRAM() 时检查“PATH/bin”和“PATH”,以及“PATH/lib 和” PATH”,当调用 FIND_LIBRARY() 时。


Pie*_*igi 7

通过添加多个路径(以分号分隔且没有空格)来使用CMAKE_PREFIX_PATH 。您可以将其设置为环境变量,以避免在cmake配置文件中包含绝对路径

请注意,cmake将在以下任何文件夹 中查找配置文件,其中CMAKE_PREFIX_PATH中的任何路径为name,而name为您要查找的库的名称。

<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)
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您需要将以下两个路径添加到CMAKE_PREFIX_PATH:

D:/develop/cmake/libs/libA;D:/develop/cmake/libB
Run Code Online (Sandbox Code Playgroud)