0


cmake使用教程(实操版)(四)

一、如何使用外部共享库和头文件

使用上一节中构建的共享库。

1、准备工作

在cmake中创建t4用来存储这一节的资源。

2、编码

编写源文件main.c如下:
在这里插入图片描述
t4下的CMakeLists.txt如下:
在这里插入图片描述
t4下的src下的CMakeLists.txt如下:
在这里插入图片描述

3、外部构建

建立build文件夹,使用cmake …来构建。

cmake ..make

会的到如下的错误:

/backup/cmake/t4/src/main.c:1:19: error: hello.h:

没有那个文件或目录

4、引入头文件搜索路径

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

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

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

CMAKE_INCLUDE_DIRECTORIES_BEFORE

通过

SET

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

现在我们在src/CMakeLists.txt添加一个头文件搜索路径,如下:
添加

INCLUDE_DIRECTORIES(/usr/include/hello)

在这里插入图片描述
如果只添加头文件搜索路径,则还是会出现一个错误:

main.c:(.text+0x12): undefined reference to `HelloFunc'

因为我们还没有将link到共享库libhello上。所以我们需要为target添加共享库,需要将目标文件连接到libhello,这里我们需要引入两个新的指令:

LINK_DIRECTORIES
TARHGET_LINK_LIBRARIES
LINK_DIRECTORIES(directtory1 directory2 ...)

添加非标准的共享库搜索路径,比如在工程内部同时存在共享库和可执行二进制,在编译时就需要指定一下这些共享库的路径。

TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2...)

这个指令可以用来为target添加需要连接的共享库,但是同样可以用于为自己编写的共享库添加共享库添加共享库连接。

进入build/src目录,运行main的结果可能还会出现错误+_+.
在这里插入图片描述
出现错误的原因是:链接器ld找不到库文件。ld默认目录是/lib和/usr/lib,如果放在其他路径也可以,需要让ld知道文件的所在路径。
解决方法如下:
方案一:

# vim /etc/ld.so.conf      //在新的一行中加入库文件所在目录
  /usr/lib  
# ldconfig                 //更新/etc/ld.so.cache文件

方案二:

1.将用户用到的库统一放到一个目录,如 /usr/loca/lib
# cp libXXX.so.X /usr/loca/lib/           2.向库配置文件中,写入库文件所在目录
# vim /etc/ld.so.conf.d/usr-libs.conf    
  /usr/local/lib  
3.更新/etc/ld.so.cache文件
# ldconfig  

我这里为了方便采用了方案一。如果共享库文件安装到了/lib或/usr/lib目录下, 那么需执行一下ldconfig命令,ldconfig命令的用途, 主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*), 进而创建出动态装入程序(ld.so)所需的连接和缓存文件. 缓存文件默认为/etc/ld.so.cache, 此文件保存已排好序的动态连接库。

得到的结果是:
在这里插入图片描述

查看main的动态链接库情况:
在这里插入图片描述
可以看到main确实连接到了共享库libhello,而且链接的是动态库libhello.so.1.

那如何链接到动态库?
方法很简单:

TARGET_LINK_LIBRERIES

(main libhello.a),重新编译连接后。使用指令
指令:ldd src/main(在目录build下)
结果如下:
在这里插入图片描述
可以看到,main确实连接到了静态库libhello.a。

6、特殊的环境变量CMAKE_INCLUUDE_PATH和CMAKE_LIBRARY_PATH

注意,这两个是环境变量不是cmake变量。使用的方法是要在bash中使用export或者在csh中使用

SET

命令设置或者

CMAKE_INCLUDE_PATH

=/home/include
cmake …等方式。
这两个变量指的是,如果头文件没有存放在常规路径中,比如(/usr/include,/usr/local/include等),则可以通过这些变量来弥补。
之前在CMakeList.txt中使用了

INCLUDE_DIRECTORIES

(/usr/include/hello)告诉头文件这个头文件目录。
为了将程序更智能一点,我们可以使用

CMAKE_INCLUDE_PATH

来进行,使用bash的方法如下:
在指令行中输入:
在这里插入图片描述
然后,再将src/CMakeLisrs.txt中的

INCLUDE_DIRECTORIES

(/usr/include/hello)替换为:
在这里插入图片描述
指令:

FIND_PATH

(myHeader NAMES hello.h PATHS /usr/include /usr/include/hello)
这里cmake.h仍然可以找到hello.h存放的路径,就是因为我们设置了环境变量

CMAKE_INCLUDE_PATH

.

如果你不使用

FIND_PATH

CMAKE_INCLUDE_PATH

变量是没有作用的,你不能指望他会为变化一起命令添加参数-I<

CMAKE_INCLUDE_PATH

以此为例,

CMAKE_LIBRARY_PATH

可以用在

FIND_LIBRARY

7、小节

如何通过

INCLUDE_DIRECTORIES

指令加入非标准的头文件搜索路径。
如何通过

LINK_DIRECTORIES

指令加入非标准的库文件搜索路径。
如何通过

TARGET_LINK_LIBRARIES

为库或可执行二进制加入库链接。
并解释了如何链接到静态库。下面会介绍一些高级话题,比如编译条件检查、编译器定义、平台判断、如何跟pkgconfig配合使用等等。

标签:

本文转载自: https://blog.csdn.net/qq_34796146/article/details/119064900
版权归原作者 知愚 所有, 如有侵权,请联系我们删除。

“cmake使用教程(实操版)(四)”的评论:

还没有评论