cmake简洁教程 - 第四篇

由于cmake内容较多,篇幅较长,为了不让人疲倦,分成了多篇博客,全部博客链接如下

cmake简洁教程 - 第一篇_YZF_Kevin的博客-CSDN博客_cmake教程详解

cmake简洁教程 - 第二篇_YZF_Kevin的博客-CSDN博客

cmake简洁教程 - 第三篇_YZF_Kevin的博客-CSDN博客

cmake简洁教程 - 第四篇_YZF_Kevin的博客-CSDN博客

cmake简洁教程 - 第五篇_YZF_Kevin的博客-CSDN博客

本篇博客讲解如何使用cmake编译,链接动态库,静态库

第一小节:如何使用cmake编译动态库,静态库

举例,我们把下面源码编译出动态库和静态库,文件架构图如下(就是把cmake第三篇博客的文件重新挪了下位置,新添加了空目录lib用来存放最终编译出来的库文件)

 其中CMakeLists.txt文件内容如下

cmake_minimum_required (VERSION 3.5)
project (demo)

set (SRC_LIST ${PROJECT_SOURCE_DIR}/func1/func1.c)

add_library (func1_shared SHARED ${SRC_LIST})
add_library (func1_static STATIC ${SRC_LIST})

set_target_properties (func1_shared PROPERTIES OUTPUT_NAME "func1")
set_target_properties (func1_static PROPERTIES OUTPUT_NAME "func1")

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

解释下

第4行:简单的set命令。变量 PROJECT_SOURCE_DIR 前篇博客已经讲过了,表工程根目录,也就是当前CMakeLists.txt文件所在目录。所以第4行的意思是把工程根目录下func1/func1.c文件设置到变量 SRC_LIST中

第6,7行:新命令,生成动态库或静态库,第一个参数表库的名字,第二个参数表动态库还是静态库,第三个参数表编译库所需的源文件

第9,10行:新命令,设置目标文件的属性,这里我们是设置了属性 OUTPUT_NAME 也就是最终的目标文件名字为func1,所以最终生成的动态库文件名为 libfunc1.so , 最终生成的静态库文件名为 libfunc1.a。注意该命令还可以设置目标文件的其他属性

第12行:仍然是普通的set命令,但使用了新的cmake全局变量,变量 LIBRARY_OUTPUT_PATH 表库文件的输出路径,这里我们设置在工程根目录下的lib文件夹下

注意:第9,10行可以没有,那么生成库文件的名字就是第6,7行的add_library命令的第一个参数。只是add_library命令有个缺点,就是连续两个 add_library命令的第一个参数不能一样。而 命令 set_target_properties就没有这样的限制,该命令指定的库名字可以一样,比如我们都指定叫func1,实际生成的文件一个是libfunc1.so,一个是libfunc1.a

好了,我们cd到build目录下,执行命令 cmake ..     意思是在当前目录执行cmake命令,但用的CMakeLists.txt文件在上层目录

再执行 make 命令,可以看到lib目录下已经产生了两个库文件

第二小节:如何使用cmake链接动态库,静态库

上一小节我们已经编译出了动态库(.so文件),静态库(.a文件),下面开始讲怎么使用这些动态库,静态库。

我们新建一个目录,把上面示例的.h头文件,编译的库文件都拷贝过来,文件架构图如下

 其中main.c文件内容如下(也就是包含了库func1里面的头文件func.h后,调用了其函数func1)

#include <stdio.h>
#include "func1.h"
int main(void)
{
    printf("Hello World\n");
    func1();
    return 0;
}

其中CMakeLists.txt文件内容如下

cmake_minimum_required (VERSION 3.5)
project (demo)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)

include_directories (${PROJECT_SOURCE_DIR}/include)

find_library(FUNC1_LIB func1 HINTS ${PROJECT_SOURCE_DIR}/lib)

add_executable(main ${SRC_LIST})

target_link_libraries(main ${FUNC1_LIB})

解释下

第4行:简单的set命令,变量 EXECUTABLE_OUTPUT_PATH  用来设置最终输出的可执行文件的目录为工程根目录下的bin目录下

第5行:简单的set命令,变量 SRC_LIST 用来记录源文件列表

第7行:设置工程的头文件目录

第9行:新命令,在指定目录下查找指定库,并把库的绝对路径赋值给指定变量。第一个参数是变量名,第二个参数是库的名字,如果不写完整的库名字,则默认查找名字为libxxxx.so文件。第三个参数是HINTS,第四个参数是在哪个目录下查找

第11行:指定生成的可执行文件名,以及使用的源文件列表

第13行:新命令,把库文件和可执行程序进行链接,第一个参数是可执行程序名,第一个参数代表库

好了,我们cd到目录build下,依次执行命令 cmake .. make,再cd到bin目录下执行 ./main 可以看到执行成功了,如下图

 注意:

之前cmake版本有使用命令 link_directories 来链接库的,但是某些情况下可能会有问题。

这里建议使用命令 find_library 来查找库,因为这样在执行cmake ..时就会去查找库是否存在,可以提前发现错误,不用等到真正链接时才出错

目前官方也是建议放弃 link_directories,转而使用 find_library 或 find_package

本篇总结(2个新命令)

1. 命令 find_library()  在指定目录下查找指定库,并把库的绝对路径赋值给第一个参数

2. 命令 target_link_libraries 把库文件和可执行程序进行链接

至此,我们已经学习了基本的cmake用法,编译可执行程序,库文件,使用库文件

下一篇我们将会讲解更多扩展用法

cmake简洁教程 - 第五篇_YZF_Kevin的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值