【问题标题】:cmake - find_library - custom library locationcmake - find_library - 自定义库位置
【发布时间】:2012-08-18 00:13:20
【问题描述】:

我目前正在尝试让 CMake 为我的项目运行(在 Windows 上)。我想使用安装所有库的自定义位置。为了让 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的目录结构有点不同。

boost -> include -> boost-1_50 -> *.hpp

当我将内容移动到“boost-1_50”到“包含”时,可以找到该库,但这样就无法处理多个版本,对吧?

【问题讨论】:

  • 首先,为什么要在 CMakeLists.txt 中设置 CMAKE_PREFIX_PATH?如果其他人尝试编译您的项目,这将不起作用。
  • 这只是为了测试 - 如果它可以工作,我会使用环境变量

标签: c++ windows cmake


【解决方案1】:

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

例如:

find_library(CURL_LIBRARY
    NAMES curl curllib libcurl_imp curllib_static
    HINTS "${CMAKE_PREFIX_PATH}/curl/lib"
)

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

【讨论】:

  • 我结合使用提示 + 环境变量(如 BOOST_DIR)来帮助 cmake 在 Windows 上找到我的库。同样对于某些库,如果标准模块不查看环境变量,我将检查我的 CMakeLists.txt,如果设置了环境变量但 CMake 变量为空,然后设置它期望帮助它的 CMake 变量。跨度>
  • HINTS 关键字完成了任务。就我而言,我正在使用本地文件夹中的数学库 libm.so。但是每次我编译时,它都是从系统文件夹中获取的。通过使用 HINTS 关键字并说明我的 libm.so 的路径,我可以成功链接到我自己的 libm.so。
  • 当我使用这个结构时,在生成的 msvc 项目中我得到错误“CURL_LIBRARY.lib not found”。我很奇怪为什么它会尝试按变量名搜索库,但确实如此。
【解决方案2】:

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

中搜索这些配置文件
CMAKE_PREFIX_PATH/<<package_name>>-<<version>>/<<package_name>>-config.cmake

(可以通过环境变量设置)。 因此,例如 boost 配置在路径中

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 )

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

希望这对其他人有帮助。

【讨论】:

    【解决方案3】:

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

    请注意,cmake 将在任何 following folders 中查找配置文件 CMAKE_PREFIX_PATH 中的任何路径在哪里,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)
    

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

    D:/develop/cmake/libs/libA;D:/develop/cmake/libB
    

    【讨论】:

      【解决方案4】:

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

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

      2. 将全局环境变量CMAKE_PREFIX_PATH 设置为D:/develop/cmake/libs/libA;D:/develop/cmake/libs/libB;...。当你运行 CMake 时,它​​会自动获取这个环境变量并填充它自己的 CMAKE_PREFIX_PATH

      3. 编写一个包装器 .bat 脚本,该脚本将调用带有 -D CMAKE_PREFIX_PATH=... 参数的 cmake 命令。

      【讨论】:

        【解决方案5】:

        您多了一层嵌套。 CMAKE 将在 $CMAKE_PREFIX_PATH/include 下搜索标题,在 $CMAKE_PREFIX_PATH/libs 下搜索库。

        来自 CMAKE documentation:

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

        【讨论】:

          【解决方案6】:

          我遇到过类似的情况。我通过在find_library() 之前添加以下代码来解决它:

          set(CMAKE_PREFIX_PATH /the/custom/path/to/your/lib/)
          

          然后它可以找到库位置。

          【讨论】:

          • CMAKE_PREFIX_PATH 是由用户(或任何调用cmake 的人)设置的。硬编码它可能对你有用,但不适用于其他系统。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-23
          • 2021-07-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-13
          相关资源
          最近更新 更多