CMake使用外部动态库/静态库和头文件
创始人
2024-05-04 02:14:39
0

CMake使用外部动态库/静态库和头文件

  • 一、准备工作
  • 二、新建一个新的CMake工程
  • 三、开始构建
  • 四、为target添加共享库
  • 五、链接静态库

一、准备工作

在博文《使用CMake构建静态库和动态库》中已经介绍了libhello动态库的构建和安装,现在我们看看如何使用这个外部动态库。

本文中的示例前提是已经安装了libhello.so共享库。

二、新建一个新的CMake工程

创建一个新的名为usehellolib的CMake工程,在main.cpp中使用libhello.so中提供的函数say_hello().

main.cpp

#include 
#include "hello.hpp"int main(int, char**) {say_hello();
}

工程根目录下的CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.0.0)
project(usehellolib VERSION 0.1.0)add_subdirectory(src)# 以下内容非必须
include(CTest)
enable_testing()set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

src 目录下的 CMakeLists.txt内容如下:

add_executable(usehellolib main.cpp)

整个工程的目录结构看起来是这样的:

20230101212438

三、开始构建

按照惯例,到build目录下进行构建

cd build
cmake ..
make

此时会发现报错了,提示找不到hello.hpp

20230101212658

hello.hpp 位于/usr/include/hello 目录中,并没有位于系统标准的头文件路径, 为了让我们的工程能够找到hello.hpp,我们需要引入一个新的指令INCLUDE_DIRECTORIES:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的后面,你可以通过两种方式来进行控制搜索路径添加的方式:

  • CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以
    将添加的头文件搜索路径放在已有路径的前面。
  • 通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前。

现在我们在 src/CMakeLists.txt 中添加一个头文件搜索路径,方式很简单,加入

INCLUDE_DIRECTORIES(/usr/include/hello)

20230101213311

进入build目录重新构建,发现找不到头文件的错误已经消失,但是出现了一个新错误:

20230101213236

这是因为我们并没有 link 到共享库 libhello 上。

四、为target添加共享库

我们现在需要完成的任务是将目标文件链接到 libhello,这里我们需要引入两个新的指令
LINK_DIRECTORIES 和 TARGET_LINK_LIBRARIES。

LINK_DIRECTORIES 的全部语法是:

LINK_DIRECTORIES(directory1 directory2 ...)

这个指令非常简单,添加非标准的共享库搜索路径,比如,在工程内部同时存在共享库和可执行二进制,在编译时就需要指定一下这些共享库的路径。这个例子中我们没有用到这个指令。

TARGET_LINK_LIBRARIES 的全部语法是:

TARGET_LINK_LIBRARIES(target library1 library2...)

这个指令可以用来为 target 添加需要链接的共享库,本例中target是一个可执行文件,但是同样可以用于为自己编写的共享库添加共享库链接。

为了解决上面遇到的函数未定义错误,我们向 src/CMakeLists.txt 中添加如下指令:

TARGET_LINK_LIBRARIES(main hello)
也可以写成
TARGET_LINK_LIBRARIES(main libhello.so)

20230101214207

重新构建,这时我们就得到了一个连接到libhello的可执行程序usehellolib,位于build/src目录:

20230101214520

执行看是否能运行成功, 发现仍然有报错:

./usehellolib: error while loading shared libraries: libhello.so.1: cannot open shared object file: No such file or directory

20230101215501

可是文件明明是存在的:
20230101215639

我们来看看ldconfig这个程序,位于/sbin下,它的作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。

执行一下ldconfig

ldconfig

如果是普通用户的话,需要使用sudo

20230101221409

再次执行程序,此时已经可以正常运行:

20230101221539

检查一下程序的链接情况,可以看到确实链接了libhello共享库:

20230101221759

五、链接静态库

那么如何链接到静态库呢? 很简单,只需要将
TARGET_LINK_LIBRRARIES 指令修改为:
TARGET_LINK_LIBRARIES(usehellolib libhello.a)

重新构建并查看链接情况:

20230101223755

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...