cmake 工具 三 add_libary, set_target_properties,target_link_libary,link_directories, link_libary

一起通过一个例子学一下  add_libary, set_target_properties,link_libary, target_link_libary 四个命令

首先创建如下的文件:

 其中 build用于cmake编译,防止大量编译的中间文件污染代码文件夹具体可见cmake 构建工具 一 hello world_kangshuangzhu的博客-CSDN博客

 int_plus 的作用就是两个数相加,int_con就是两个数相减,特别简单,这里不放代码了

add_libary 

生成动态库和静态库

add_library(<name> [STATIC | SHARED | MODULE]

            [EXCLUDE_FROM_ALL]

            [source1] [source2 ...])

上面参数看着复杂,其实用的最多的也就三个:

1.<name>  生成的库名

2.[STATIC | SHARED | MODULE] 库类型

STATIC  生成静态库

SHARED  生成动态库

MODULE  这个我没用过,网上看也几乎没有什么人用,晚些时间补上

应该注意的是这三个参数必须用大写

3. source 代码路径,也可以不指定,在后续target_sources() 中指定

add_libary和add_execute是唯二能够产生target的配置。target我的理解就是最终生成的编译结果。

我们来实践一下,CMakeLists.txt配置如下:

# cmake 最低版本需求
cmake_minimum_required(VERSION 3.13)

# 工程名称
project(cmake_study1)

# 设置
set(CMAKE_CXX_STANDARD 11)


include_directories(src/include)
include_directories(src)
AUX_SOURCE_DIRECTORY(src/include INCLUDE)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)
message(${INCLUDE})

add_library(int_plus STATIC ${INCLUDE})

add_executable(cmake_study ${DIR_SRCS} ${INCLUDE})






打开build文件夹, 输入

cmake..
make

 可以看到build文件夹下除了cmake_study使我们的编译目标意外,还生成了一个libint_plus.a的库文件。这就是生成的库文件,mac会在生成的库文件中自动加上lib前缀

同时我们打开CMakefiles,可以看到比没有使用add_libary的时候多了一个int_plus.dir。 这个文件夹的命名方法和cmake_study.dir类似,说明int_plus也走完了预编译,编译,汇编等过程,唯一和cmake_study不同的是,int_plus没有main函数,会生成一个库文件。

导入已经生成的库

add_library(<name> <type> IMPORTED [GLOBAL])

这个最常用的参数是2个

name:库名,可以自己随意起名字

<type>  库类型,[STATIC | SHARED | MODULE]

应该注意的是,type 和  IMPORTED  都应该大写

如果要用导入的库,只用add_library(<name> <type> IMPORTED [GLOBAL]) 是不够的。首先我们不知道这个库的地址,而且也没有指定哪些代码依赖这个库。

指定库的地址 用set_target_properties 或者 set_properties(target) 来实现。两个命令直接看名字就知道是设置target的属性。set_properties(target)与set_target_properties 本质上没有区别,可以认为set_target_properties 是 set_properties 的一种特殊情况。target的属性多到令人发指具体可以看cmake-properties(7) — CMake 3.25.0-rc4 Documentation

这里只介绍路径

set_target_properties(<name> PROPERTIES  IMPORTED_LOCATION  <path>)

name  库名,和上面的库名对应

path    库文件的路径

还用刚才的例子,在项目中创建一个新文件夹叫lib,把刚刚生成的库文件放进lib中,清空build。形成如下的文件结构。

添加 CMakeLists.txt配置如下:

# cmake 最低版本需求
cmake_minimum_required(VERSION 3.13)

# 工程名称
project(cmake_study1)

# 设置
set(CMAKE_CXX_STANDARD 11)

include_directories(src/include)
include_directories(src)
AUX_SOURCE_DIRECTORY(src/include INCLUDE)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)
message(${INCLUDE})

add_library(libint_plus STATIC IMPORTED )
set_target_properties(int_plus PROPERTIES
    IMPORTED_LOCATION ../lib/libint_plus.a
)


# 编译源码生成目标
add_executable(cmake_study ${DIR_SRCS} ${INCLUDE})
target_link_libraries(cmake_study PRIVATE libint_plus)

在build中执行

cmake..
make

可以顺利编译。这里需要注意一点 

库文件的路径如果写相对路径,应该是以build文件夹为当前路径,而不是项目文件夹。

考虑一个问题,既然我们已经加载了INCLUDE 文件夹编译的库文件,那么是不是可以不再编译INCLUDE了?

add_executable(cmake_study ${DIR_SRCS} ${INCLUDE})

改成

add_executable(cmake_study ${DIR_SRCS} )

事实上这样确实是可以的。

以上用的是静态库,我们知道静态库会被包含进最终的可执行文件中,动态库则是在运行的时候调用。这里可以验证一下。把刚刚保存的静态库libint_plus.a 删除,输入命令运行可执行文件:

cmake_study

可以运行。

如果把上面的静态库换成动态库,把库文件删掉后则会报错。如果把可执行文件换一个路径,也会报错,因为可执行文件调用动态库是从可执行文件的路径通过相对路径调用,移动了位置以后就会找不到动态库的位置。

在上面的例子中,add_libary , set_target_properties, target_link_libaries在一起使用,他们各自起了什么作用呢?

实际上如果我们只添加配置

add_library(libint_plus STATIC IMPORTED)

set_target_properties(libint_plus PROPERTIES

IMPORTED_LOCATION ../lib/libint_plus.a

)

编译的时候是什么都不做的,我们在加上这一行以后,输入cmake ..   。然后生成的配置文件中搜索libint_plus, 什么都搜不到。这是因为我们只配置这两行,只是告诉cmake我们会使用这个库文件,但是没告诉它我们要在哪个程序中链接这个库文件,所以cmake实际上不会把他们放进编译配置中。

真正让库文件生效的是target_link_libary

target_link_libary

target_link_libary用于指定target的库链接

target_link_libraries(<target>
                      <PRIVATE|PUBLIC|INTERFACE> <item>...
                     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

 其中

<target> 是编译目标,必须是add_libary或者add_executable的结果。

item是要连接的库,一个目标可以链接多个库

还是刚才的那个例子,我们在cmakefile.txt 中添加 

target_link_libraries(cmake_study libint_plus)

后,然后运行cmake .. 。可以发现最明显的区别就是在 build/CMakeFiles/cmake_study.dir/link.txt 中生成了一个配置

 说明link配置文件已经把库文件和最终的可执行程序建立了联系。

link_libary和link_directories

link_library 只可以用于连接一个现有的库文件,一般和link_directories 搭配使用。

link_libraries([item1 [item2 [...]]]
               [[debug|optimized|general] <item>] ...)

例如,还是上面的例子:

# cmake 最低版本需求
cmake_minimum_required(VERSION 3.13)

# 工程名称
project(cmake_study1)

# 设置
set(CMAKE_CXX_STANDARD 11)


include_directories(src/include)
include_directories(src)
AUX_SOURCE_DIRECTORY(src/include INCLUDE)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)

link_directories("lib")
link_libraries(libint_plus.a)

add_executable(cmake_study ${DIR_SRCS} )
这里应该注意的是,link_directories 这里应该填库文件的路径,而且如果要写相对路径,应该从代码路径开始。所以上面写的是lib 而不是../lib。link_library 的输入是库文件名。

cmake 官方文档中明确写了,推荐使用target_link_library。

The target_link_libraries() command should be preferred whenever possible. Library dependencies are chained automatically, so directory-wide specification of link libraries is rarely needed.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值