Cmake命令之find_library介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cmake命令之find_library介绍相关的知识,希望对你有一定的参考价值。

参考技术A

  该命令用于查找库(动态库或者静态库),当构建依赖于第三方库/系统库,可以使用该命令来查找并使用库(Cmake中有另外一个命令 find_package ,能获取库的更多信息,具体可以参考 Cmake命令之find_package介绍 )

  通过一个例子来看下基本的使用,假设我们目录和文件树如下,:

  我们在 mylib 中生成最终的库 libmymath.a ,然后在顶层的 CMakeLists.txt 中查找这个库文件,几个文件的具体内容如下:

  在 ./mylib/ 下执行 cmake . 和 make 以便生成库 libmymath.a ,然后在 ./ 目录下执行 cmake . 和 make ,得到可执行文件 test ,运行 test 的结果为:

  库的搜索路径分为两大类: 默认搜索路径 和 附加搜索路径 。
   默认搜索 路径包含 cmake 定义的以 CMAKE 开头的一些变量(例如 CMAKE_LIBRARY_ARCHITECTURE 、 CMAKE_PREFIX_PATH 、 CMAKE_LIBRARY_PATH 、 CMAKE_FRAMEWORK_PATH )、标准的系统环境变量(例如系统环境变量 LIB 和 PATH 定义的路径)、系统的默认的库安装路径(例如 /usr 、 /usr/lib 等);
   附加搜索路径 即 find_library 命令中通过 HINTS 或 PATHS 指定的路径;

 1) 通过命令行使用 -D 指定的 CMAKE_XXX_PATH 变量,也就是形如 cmake . -DCMAKE_XXX_PATH=paths 的格式。其中 CMAKE_XXX_PATH 包含如下几个:
   CMAKE_PREFIX_PATH :指定搜索目录的前缀,如果前缀有多个,需要以 分号分割的列表 方式提供,该变量默认为空,一旦该变量非空,那么会搜索该变量提供的目录,以及 $CMAKE_PREFIX_PATH/lib ;例如 CMAKE_PREFIX_PATH=A;B ,那么 find_library 会从 A 、 B 以及 A/lib 、 B/lib 中搜索库是否存在;
   CMAKE_LIBRARY_ARCHITECTURE :如果该变量被设置,那么会搜索目录 $CMAKE_PREFIX_PATH/lib/$CMAKE_LIBRARY_ARCHITECTURE ;
   CMAKE_LIBRARY_PATH :指定 find_library 的库查找目录,默认值为空,多个值时需要以分号分割列表指定;
   CMAKE_FRAMEWORK_PATH *:指定 macOS 的框架作为搜索路径。

 2) 通过在 环境变量 中指定 CMAKE_XXX_PATH 变量,例如在 window 的环境变量中增加 CMAKE_XXX_PATH (以 ; 分割多个路径)、 Linux 中 shell 配置文件中添加(以 : 分割多个路径)。用法和 cmake -D 指定类似,例如在我的机器中( macOS ),在 .zshrc (我的命令行配置文件)中增加 export CMAKE_LIBRARY_PATH="/XXX/……/mylib" ,即可在将该目录加入到搜索路径中。
 3) HINTS 选项指定的路径。
 4) 系统环境变量指定的目录,默认是 LIB 和 PATH 指定的路径。例如在 PATH 中指定库搜索目录;

 也可以通过 find_library 中的 PATHS ENV 环境变量名称 ( cmake 中使用环境变量名称的格式为 $ENV环境变量名称 )来指定从哪个环境变量名称中获取路径,例如定义一个 TESTPATH 环境变量并赋值为 ./mylib ,并在 find_library 命令中指定使用该环境变量:

 5)跟当前系统相关的平台文件路径,一般来说指的是当前系统安装软件的标准目录,不同的操作系统对应的路径有所不同。 camke 中 find_library 与此相关的也有如下几个, CMAKE_SYSTEM_XXX_PATH 变量,这些:
   CMAKE_SYSTEM_PREFIX_PATH :指定安装目录的前缀,例如在 Windows 下的 /XXXX/Program Files , Linux 下的 /usr 或 /usr/local 等。 find_library 命令会搜索这些前缀目录,也会以这些目录加上 lib 进行搜索,例如搜索 /usr/local/lib ;
   CMAKE_SYSTEM_LIBRARY_PATH :默认是当前系统的标准目录,不建议修改它;例如在我的系统,这个变量的值是 /usr/lib/X11 ;
   CMAKE_SYSTEM_FRAMEWORK_PATH : macOS 框架路径,默认是当前系统的标准目录,不建议修改它;例如在我的系统,这个变量的值包含了路径 /Library/Frameworks ;
 6) PATHS 选项指定的路径。

CMAKE 链接器找不到库;但是通过 find_library 找到了库

【中文标题】CMAKE 链接器找不到库;但是通过 find_library 找到了库【英文标题】:CMAKE linker does not find library; but library is found with find_library 【发布时间】:2018-11-13 13:37:55 【问题描述】:

我有一个名为 mylib 的 catkin 库,我使用 catkin build 构建它 此外,我有一个使用这个库中的函数的节点。我像往常一样在节点的 CMakeLists.txt 中启用了这个链接:

find_package(catkin REQUIRED COMPONENTS
  mylib
)

add_executable(exec
  src/main.cpp
)

target_link_libraries(exec
  $catkin_LIBRARIES
)

不过这次没有成功。链接器错误 然后我补充说:

find_package(catkin REQUIRED COMPONENTS
  mylib
)
find_library( MYLIB NAMES
    mylib
)
message($MYLIB)

add_executable(exec
  src/main.cpp
)

add_dependencies(exec $MYLIB)

target_link_libraries(exec
  $catkin_LIBRARIES
  $MYLIB
)

问题是 message() 语句打印了库的正确路径,我也可以在资源管理器中找到它。 但是我收到警告:

(add_dependencies):   Policy CMP0046 is not set: Error on non-existent dependency in   add_dependencies.

它指的是库的完全相同的路径并表示它不存在。

链接器错误是

/usr/bin/ld: cannot find -lmylib

备注:我可以通过手动添加库的路径来解决错误

link_directories($ENVHOME/test/devel/lib)

我不明白为什么首先找到该库,但无法链接为它的包名。但它通过提供完整路径来工作。 我很感激任何见解!

【问题讨论】:

无论如何,去掉add_dependencies调用:这个函数调整targets之间的依赖关系,但是库的路径不是target 【参考方案1】:

该库不在您的链接器路径中。例如。您的链接器在/link 中查找,并且您在/home 中有一个库。您知道在哪里查找并且可以在文件浏览器中看到它,但链接器找不到它,因为它只在“/link”中查找。

'find_package' 查找包并设置一些变量,但不会更改链接器路径。

您必须自己设置链接器路径。在大多数情况下,find_package 设置一个包含链接器路径的变量。

find_package 提供了一些类似catkin_package() 的功能。这些函数设置您的构建环境。

catkin_package() 是 catkin 提供的 CMake 宏。这是为构建系统指定 catkin 特定信息所必需的,而构建系统又用于生成 pkg-config 和 CMake 文件。

必须在使用 add_library() 或 add_executable() 声明任何目标之前调用此函数。

【讨论】:

以上是关于Cmake命令之find_library介绍的主要内容,如果未能解决你的问题,请参考以下文章

CMake中find_library的使用

CMake中find_library的使用

如何将框架添加到 CMake

CMake 在错误的路径上查找库

CMAKE 如何告诉 makefile 链接库?

C++学习(二六七)find_package() find_library()