cmake脚本的使用记录

本文介绍了作者在整合多套独立开源代码时遇到的问题,以及如何通过CMake解决构建系统的兼容性问题。作者详细记录了CMakeLists.txt文件的编写过程,包括设置工程、指定源码路径、链接库路径、头文件路径等,并分享了如何开启宏定义和构建带调试信息的固件。文章强调了CMake的高层抽象带来的便利性,同时也指出其可能带来的透明度降低和问题排查的挑战。
摘要由CSDN通过智能技术生成

今天在解决一个问题中,需要把几套独立的开源代码放在一起构建,总的代码量虽然也不是很多,但是每套开源代码都有自己的构建系统,彼此之间很难做到兼容。苦恼中有同事就建议我说不妨用cmake试试,说不定能解决我的问题。但是本人对cmake的了解仅仅限于使用而已,内部原理一窍不通,可能是处于程序员的强迫症,对没有掌握足够信息的事情有种本能的忧虑,所以一开始没有采纳,硬着头皮搞自己的makefile构建,可能是makefile太多细节要处理了,眼看到下工时间了,编译现场还是一片飘红惨不忍睹。不得不改变策略回到同事的建议用cmake. 于是就边百度边照猫画虎的编辑CMakeLists.txt文件,果然没有花费多少功夫,就搞定了整个构建系统,可执行程序和运行库构建成功,开心。

为了以后爬坑顺利一点,觉得有有必要 对用到的cmake命令做一个记录,包括如何定义工程,指定源码路径,指定连接运行库路径,头文件路径指定等等。用一个例子开始:

下面依次介绍每个文件,首先是CMakeLists.txt

 1: CMakeLists.txt ▶                                                                                                                                                                               ◀◀ buffers
  1 cmake_minimum_required(VERSION 2.8.3)
  2 project(helloworld)
  3
  4 add_compile_options(-std=c++11)
  5 FIND_PACKAGE(OpenMP REQUIRED)
  6 if(OPENMP_FOUND)
  7     message("OpenMP Found")
  8 endif()
  9
 10 #find_package(OpenCV REQUIRED)
 11 #if(OPENCV_FOUND)
 12 #   message("found opencv")
 13 #endif()
 14
 15 OPTION(USE_MACRO "Build the project using macro" OFF)
 16 IF(USE_MACRO)
 17     add_definitions("-DUSE_MACRO")
 18 endif(USE_MACRO)
 19
 20 LINK_DIRECTORIES("/home1/caozilong/WorkSpace/cmake-use/libs")
 21 LINK_LIBRARIES("/home1/caozilong/WorkSpace/cmake-use/libs/libfoo.a")
 22 include_directories(./)
 23 include_directories(./include/)
 24 add_executable(${PROJECT_NAME} src/main.cpp src/foobar.cpp src/bar.c)
 25 target_link_libraries(${PROJECT_NAME} libfoo.a)
 26 add_library(bar_add_static_lib STATIC src/bar.c)
 27 add_library(bar_add_shared_lib SHARED src/bar.c)

foobar.h是空头文件,目的仅仅是测试cmake的头文件引用路径命令是否生效

libfoo.a 里面包含一个fxx函数的实现,会在主程序的执行流中被调用,打印输出fxx函数名等信息,目的是验证cmake连接库的命令是否有生效。

然后剩下的是bar.c main.cpp和foobar.cpp文件,bar.c是C源码文件,目的是验证cmake是否支持C和CPP混合构建(验证结果是支持的).

bar.c

foobar.cpp,目的是验证多个文件编译。

 main.cpp 主程序,提供调用流和执行流,会调用foobar.cpp,bar.c以及libfoo.a中的实现,判断cmake是否都有照顾到。

接下来测试,在工程顶层目录执行如下命令序列

$mkdir build && cd build
$cmake ../
$make

再次配置,这次使用如下命令打开USE_MACRO宏,判断main主函数分支打印变化情况。

cmake .. -DUSE_MACRO=on

可以看到,打开了USE_MACRO宏之后,打印变化了,说明通过cmake产生的宏定义生效了。

CMAKE构建带DEBUG调试信息的输出文件

默认情况下,cmake构建出来的固件是不带debug信息的,通过在CMakeList.txt中增加两行,可以增加带Debug信息的固件:

  4 SET(CMAKE_BUILD_TYPE "Debug")
  5 SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
  6 SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

-B选项

通常情况下,为了保持源码目录树整洁,编译的时候一般在源码目录下新建一个build目录,并且进入到build目录进行配置和编译,这样,生成的编译构建文件和中间文件全部都会在build目录中,不会污染源码树。

还有另一种方式,不需要主动创建临时构建目录,也不需要进入目录去配置,而是直接执行如下命令:

$ cmake ./ -B ./build
$ make -C ./build

cmake 和make的区别和联系

总结

1.cmake的命令更加高层和抽象,使使用者不必去关心Makefile的细节,一开始我就是被困在makefile的细节中出不来。cmake完全没有这个问题,因为所有的细节处理都被cmake后台处理好了。

2.软件越抽象,用户体验越好,但是也越不透明,如果构建系统除了bug,更难排查。我们学习物理知道能量守恒,其实难度也是守恒的,软件无论怎么分层,只不过是拆东补西的事情,工作量那么多,总量是不变的,还是拿cmake为例,它的简单易用是以背后复杂的自动构建逻辑为代价的。

3.要勇于尝试新鲜的东西,担心是诅咒,祝福是保佑,恐惧感来源于未知,当经过互相了解之后,排除了彼此的陌生感,恐惧感会自动消除,当然,如何克服第一次,要看自己了。


结束

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

papaofdoudou

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

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

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

打赏作者

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

抵扣说明:

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

余额充值