CMake添加库

尝试给项目添加一个库,还是以上一篇的CalculateSqrt为例。

1、新建库

新建一个子目录,命名为MathFunctions。在该目录下新建MySqrt.h和MySqrt.cpp,MySqrt.h为函数声明,MySqrt.cpp为实现文件, 不调用math.h中的sqrt()函数,自己实现平方根的计算。当然为了检验方便,可以直接返回形参两倍值。
同样,MathFunctions目录下也需要构建CMakeLists.txt,将其设定为库,并添加源文件:

add_library(MathFunctions MySqrt.h MySqrt.cpp)

2、顶层调用

为了使用这个新库,我们将在顶级CMakeLists中使用add_subdirectory()添加库调用。

# 添加库
add_subdirectory(MathFunctions)

然后将新库添加到可执行文件中,并将MathFunctions库添加到包含目录中,以便能够找到MySgrt.h头文件。

target_link_libraries(CalculateSqrt PUBLIC MathFunctions)

#包含头文件
target_include_directories(
 	CalculateSqrt 
 	PUBLIC 
 	"${PROJECT_BINARY_DIR}"
 	"${PROJECT_SOURCE_DIR}/MathFunctions"
 	)

修改main.cpp文件,添加MySqrt.h文件的包含并调用该函数

#include "MySqrt.h"

这样就简单地添加了MathFunctions库

3、尝试使用开关项

对于我们设计的MySqrt()函数,功能比较简单,很容易就能检测出是否正确,但有些情况下可能会涉及与库函数比较;或者,当math.h头文件无法找到,只能使用MySqrt.h。此时,需要设计一个开关项,用户可以设置是否使用MySqrt()函数。
设置开关项:

# 设置开关项默认为ON
option(USE_MYMATH "Use MySqrt provided math implementation" ON)

设置开关项ON、OFF时相应的操作。如果为USE_MYMATH为ON,需要添加MathFunctions库;为OFF,则不用。后续的包含头文件也是类似的操作。使用list语句(相当于构建了一个类似与python中的list数据结构),

list(APPEND <list> [<element> ...])

创建一个变量名为的变量,并将添加append(附加)到list中。如已有,则只执行append操作。
整体语句如下:

# 设置开关项相应操作
if(USE_MYMATH)
	add_subdirectory(MathFunctions)
	list(APPEND EXTRA_LIBS MathFunctions)
	list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()

# 添加文件
add_executable(CalculateSqrt main.cpp)

target_link_libraries(CalculateSqrt PUBLIC ${EXTRA_LIBS})

#包含头文件
target_include_directories(
 	CalculateSqrt 
 	PUBLIC 
 	"${PROJECT_BINARY_DIR}"
 	"${EXTRA_INCLUDES}")

相应地,要将该变量传递到源文件中,CalculateSqrtConfig.h.in中定义USE_MYMATH:

#cmakedefine USE_MYMATH

在main.cpp中加入:

#ifdef USE_MYMATH
#include "MySqrt.h"
#endif

// 在调用处加入
#ifdef USE_MYMATH
		const int outputValue = MySqrt(inputValue);
#else
		const int outputValue = sqrt(inputValue);
#endif

定义了开关项之后,在命令行中设置开关项:

cmake .. -D USE_MYMATH=ON
cmake --build .
./CalculateSqrt 9

为了验证USE_MYMATH有没有起作用,可以将MySqrt()函数先设置为2倍值。

4、问题

尝试过程中出现报错,找不到MySqrt()函数,后续发现是由于main.cpp中将

#ifdef USE_MYMATH
#include "MySqrt.h"
#endif

放在

#include "CalculateSqrtConfig.h"

之前,还没定义就开始使用导致的。

5、拓展

(1)除了在config.h.in中定义开关项之外,也可以在CMakeLists.txt文件中用以下命令定义:

target_compile_definitions(CalculateSqrt PRIVATE USE_MYMATH)

(2)像这种标准库函数的开关项,其实也可以用cmake中的CheckSymbolExists检查库函数是否可以使用,如果不能使用再设置使用自定义函数。

6、补充Usage requirement

Usage requirement(使用需求)会让使用者在链接库添加库当前路径,而设计者不需要。个人理解(不知道对不对)相当于给库设计函数接口,生成执行文件的时候自动链接库路径,不需要手动包含。
在Mathfunctions路径下的CMakeLists.txt中添加

target_include_directories(
	MathFunctions
	INTERFACE
	${CMAKE_CURRENT_SOURCE_DIR}
)

在上级路径下的CMakeLists.txt中删除有关EXTRA_INCLUDES的内容。

相关代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值