CMake基本用法与项目编译

1.简介
1.1 CMake编译项目主要是 通过编写CMakeList.txt文件项目的每个子文件夹下分别编写CMakeList.txt,通过CMake工具来根据CMakeList文件生成makefile,最后编译成可执行文件。

1.2 通过CMake可以编译不同版本的vs项目,方便在不同版本的vs之间进行项目的转移,CMake也可以在不同的平台编译项目。

2.基本语法

2.1 指定cmake的最小版本

cmake_minimum_required(VERSION 版本号)

2.2 设置项目的名称

project(项目名称)
//指定项目版本号
project(项目名称 VERSION 版本号)

//配置一个头文件,将版本号传递给源代码
configure_file(xx.h.in xx.h)

//xx.h.in 在源目录中创建一下内容,当 CMake 配置这个头文件时,@xx_VERSION_MAJOR@的值和 @xx_VERSION_MINOR@将被替换。
#define xx_VERSION_MAJOR @xx_VERSION_MAJOR@
#define xx_VERSION_MINOR @xx_VERSION_MINOR@

//在项目中包含上述xx.h配置头文件;

2.3 添加可执行程序

add_executable(可执行程序名称,可执行程序.cpp文件)

2.4 指定C++的标准:通过CMAKE_CXX_STANDARD 和 CMAKE_CXX_STANDARD_REQUIRED来指定;

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

2.5 在源代码的根目录下创建一个build文件夹,将编译的信息全部保存到bulid中,这样方便我们对源码的管理以及二次编译;

2.6 添加编译生成的动态链接库,将动态链接库源文件放在子目录Child下,Child下包含库的头文件childxx.h和childxx.cpp文件。

//添加子文件夹
add_subdirectory(Child)

//连接库文件
target_link_libraries(项目名称 PUBLIC Child)

//添加包含目录,以便找到库的头文件
target_include_directories(项目名称 PUBLIC "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/Child")

2.7 设置某个库位可选库,在编译大型项目中很常见,在cmake-gui中可以选择性的编译某些库。

option(USE_CHILD "使用Child库" ON)

2.8 设置可选项后,添加库的构建和连接条件。

//USE_CHILD是一个用户定义的变量,使用EXTRA_LIBS变量收集任何可选库,以便链接,EXTRA_INCLUDES 变量用于可选的头文件
if(USE_CHILD)
	add_subdirectory(Child)
	list(APPEND EXTRA_LIBS Child)
	list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/Child")
endif()

对源码的更改,在需要使用库的xx.cpp中,添加如下代码:

#ifdef USE_CHILD
#  include "childxx.h"
#endif

对引用系统库函数还是自定义库中的的函数,在源码中可以采用如下方式指定。

//指定使用自定义的sqrt函数,还是库sqrt函数
#ifdef USE_CHILD
  const double output = sqrt(input);
#else
  const double output = sqrt(input);
#endif

由于源码中需要使用USE_CHILD,因此需要在配置头文件xx.h.in文件中添加。

#cmakedefine USE_CHILD

2.9 库的使用要求
主要命令

  • target_compile_definitions()
  • target_compile_options()
  • target_include_directories()
  • target_link_libraries()

在Child子目录下的CMakeList.txt中添加

target_include_directories(CHILD INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

2.10 安装和测试
在Child/CMakeList.txt中添加库和头文件;

install(TARGETS Child DESTINATION lib)
install(FILES Childxx.h DESTINATION include)

在根目录下的CMakeList.txt中添加可执行文件和配置头文件

install(TARGETS 项目名 DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/xxConfig.h" DESTINATION include)

CMake变量 CMAKE_INSTALL_PREFIX用于确定将安装文件的根目录;

在根目录CMakeList.txt文件中,添加一些测试来验证程序是否正常。

enable_testing()
//测试程序是否正常,是否有段错误或其他方式的崩溃,并且返回值为0
add_test(NAME Runs COMMAND 项目名 25)
//PASS_REGULAR_EXPRESSION属性验证测试的输出是否包含某些字符串。在这种情况下,验证在提供的参数数量不正确时打印使用消息。
add_test(NAME Usage COMMAND 项目名)
set_tests_properties(Usage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")

//定义一个函数来测试
function(do_test target arg result)
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endfunction(do_test)

//测试
do_test(项目名 参数)

2.11 在不同平台下链接不同的库。
假如Child在相应的模块下,需要使用系统的log,exp函数,如平台没有,则从m库中选择相应的函数。

include(模块名)
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
if(NOT (HAVE_LOG AND HAVE_EXP))
  unset(HAVE_LOG CACHE)
  unset(HAVE_EXP CACHE)
  set(CMAKE_REQUIRED_LIBRARIES "m")
  check_symbol_exists(log "math.h" HAVE_LOG)
  check_symbol_exists(exp "math.h" HAVE_EXP)
  if(HAVE_LOG AND HAVE_EXP)
    target_link_libraries(Child PRIVATE m)
  endif()
endif()

如果可用,则使用下面的命令指定HAVE_LOG和HAVE_EXP作为PRIVATE编译定义。

if(HAVE_LOG AND HAVE_EXP)
  target_compile_definitions(Child PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()

在需要使用log和exp的源文件中添加如下代码。

#if defined(HAVE_LOG) && defined(HAVE_EXP)
	//使用exp,log函数
#else

#enif

2.12 静态库和共享库

通过 BUILD_SHARED_LIBS变量可以用于控制add_library(),允许没有显示类型( STATIC、SHARED、MODULE、OBJECT)的库的构建方式。

在根目录下使用options() 命令添加 BUILD_SHARED_LIBS,可以通过ON或OFF控制。

//添加版cmake本
cmake_minimum_required(VERSION 3.10)

//设置项目版本
project(Tutorial VERSION 1.0)

//添加C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

//控制生成共享库
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

//设置变量BUILD_SHARED_LIBS 
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

//配置头文件
configure_file(项目名Config.h.in 项目名Config.h)

//添加库目录
add_subdirectory(Child)

 //生成可执行程序
add_executable(项目名  项目名.cxx)
target_link_libraries(项目名 PUBLIC Child)

上面已经启用这个库,下面需要在子目录下进行设置Child/CMakeList.txt。

CMAKE案例参考:https://www.cnblogs.com/ph829/p/4759124.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秘境之眼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值