CMake教程系列-04-编译相关函数

1.引入

编译过程与链接过程需要向编译器及链接器传入不同的参数,而这些参数分为以下几类:

  • 编译选项(包括宏定义)
  • 头文件路径
  • 链接库文件名称
  • 链接库查找路径

2.target_compile_options

此函数向目标添加编译选项,

  • 其原型为:
target_compile_options(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

  • eg:
target_compile_options(sample PUBLIC /arch=avx2 /Wall)

需要注意的是,如果要设置c / c++ 标准,不仅可以使用该函数添加 -std=STANDARD,还可以且更推荐设置以下两个cmake预设宏的值:

  • 直接填标准号的数字即可,cmake会自动设置标准相关的选项。
CMAKE_C_STANDARD
CMAKE_CXX_STANDARD

2.target_compile_definitions

此函数专门向目标添加预设宏声明及定义。

  • 当然,你也可使用上面的函数完成这个操作,毕竟最后都是要变成命令行中的参数不是?
  • 不过专业的人干专业的事情,建议使用此函数添加宏定义。其原型为:
target_compile_definitions(<target>
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • eg:
target_compile_definitions(sample PRIVATE BUILD_DLL PUBLIC "-DPI=3.14159")

3.target_compile_features

此函数专门向目标设置c / c++版本。当然,你仍然可以选择第一个函数中的两种做法。

  • 其原型为:
target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
  • 例如:
target_compile_features(sample PUBLIC cxx_std_17)

4.target_precompile_headers

该函数向目标添加了预编译头文件。

  • 就是使用Visual Studio 创建新工程后自动创建的pch.h这种文件。
  • 其原型为:
target_precompile_headers(<target>
  <INTERFACE|PUBLIC|PRIVATE> [header1...]
  [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
  • eg:
target_precompile_headers(sample PRIVATE pch.hpp)

5.target_include_directories

该函数声明了编译目标时查找使用头文件的路径。

  • 其原型为:
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • eg:
target_include_directories(sample PUBLIC public/include/sample PRIVATE sample)

6.target_link_libraries

该函数声明了链接时需要参与的依赖库名称或target。其名称可包含完整路径。

  • 其原型为:
target_link_libraries(<target>
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • eg:
target_link_libraries(sample PUBLIC CURL::curl glib m)

注意:由于一个target中包含多个属性,一般情况下包含了头文件路径。

  • 所以使用target作为参数传入此函数时,无需调用 target_include_directories 再次声明添加头文件路径。

7.target_link_directories

该函数声明了链接时,查找依赖库的路径。

  • 其原型为:
target_link_directories(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • eg:
target_link_directories(sample PUBLIC third_party/libs/x86/rel)

8.target_link_options

该函数声明了添加额外的链接选项。

  • 其原型为:
target_link_options(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • eg:
target_link_options(sample PUBLIC /shared)

9.target_sources

该函数声明了向target添加源文件。

  • 其原型为:
target_sources(<target>
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • eg:
target_sources(sample PRIVATE decode.cxx)

注:不要认为这个函数完全无用,可以被 add_library / add_executable 替代。在某些情况下,此函数还是非常好用的。

  • eg:
    我需要提供一个仅包含源代码的库给下游使用,而不是编译好二进制提供给下游。此时,我们需要使用 add_library(sample INTERFACE) 并使用此函数添加源码文件来链接至 sample ,并通过cmake导出此target。如此一来,下游只需要使用 target 族函数便可以不通过其他额外代码使用我提供的源码文件。

10.target族函数注意事项

当需要使用cmake export关键字导出声明的target并附带其中的 PUBLIC 属性时,我们必须 将PUBLIC / PRIVATE / INTERFACE 关键字向这类 target 族函数补齐。且如果一个 target 族函数声明了这三个关键字其中之一,该 target 所属的其他 target 族函数均应当声明关键字。且对于包含路径的值,我们需要声明此值的使用范围:

  • 编译/链接时使用。必须使用绝对路径。
  • 导出以向下游提供。必须使用相对路径。

所以,我们通常情况下使用以下方式:

target_include_directories(sample PRIVATE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/header/include> PUBLIC $<INSTALL_INTERFACE:include>)

11.完整示例

cmake_minimum_required(VERSION 3.0)
project(sample CXX)
set(CMAKE_CXX_STANDARD 11)

add_library(sample sample.cpp)
target_include_directories(sample PRIVATE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/header/include> PUBLIC $<INSTALL_INTERFACE:include>)
target_compile_options(sample PUBLIC /Wall)
target_compile_definitions(sample PRIVATE BUILD_DLL INTERFACE USE_DLL)
target_link_libraries(sample PRIVATE thread m)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢打篮球的普通人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值