cmake使用教程(实操版)(四) 您所在的位置:网站首页 cmake命令行添加头文件路径 cmake使用教程(实操版)(四)

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

2024-07-05 16:22| 来源: 网络整理| 查看: 265

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

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

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 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_LIBRARY_PATH可以用在FIND_LIBRARY。

7、小节

如何通过INCLUDE_DIRECTORIES指令加入非标准的头文件搜索路径。 如何通过LINK_DIRECTORIES指令加入非标准的库文件搜索路径。 如何通过TARGET_LINK_LIBRARIES为库或可执行二进制加入库链接。 并解释了如何链接到静态库。下面会介绍一些高级话题,比如编译条件检查、编译器定义、平台判断、如何跟pkgconfig配合使用等等。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有