今天在解决一个问题中,需要把几套独立的开源代码放在一起构建,总的代码量虽然也不是很多,但是每套开源代码都有自己的构建系统,彼此之间很难做到兼容。苦恼中有同事就建议我说不妨用cmake试试,说不定能解决我的问题。但是本人对cmake的了解仅仅限于使用而已,内部原理一窍不通,可能是处于程序员的强迫症,对没有掌握足够信息的事情有种本能的忧虑,所以一开始没有采纳,硬着头皮搞自己的makefile构建,可能是makefile太多细节要处理了,眼看到下工时间了,编译现场还是一片飘红惨不忍睹。不得不改变策略回到同事的建议用cmake. 于是就边百度边照猫画虎的编辑CMakeLists.txt文件,果然没有花费多少功夫,就搞定了整个构建系统,可执行程序和运行库构建成功,开心。
为了以后爬坑顺利一点,觉得有有必要 对用到的cmake命令做一个记录,包括如何定义工程,指定源码路径,指定连接运行库路径,头文件路径指定等等。用一个例子开始:
下面依次介绍每个文件,首先是CMakeLists.txt
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是否都有照顾到。
接下来测试,在工程顶层目录执行如下命令序列
再次配置,这次使用如下命令打开USE_MACRO宏,判断main主函数分支打印变化情况。
可以看到,打开了USE_MACRO宏之后,打印变化了,说明通过cmake产生的宏定义生效了。
CMAKE构建带DEBUG调试信息的输出文件
默认情况下,cmake构建出来的固件是不带debug信息的,通过在CMakeList.txt中增加两行,可以增加带Debug信息的固件:
总结
1.cmake的命令更加高层和抽象,使使用者不必去关心Makefile的细节,一开始我就是被困在makefile的细节中出不来。cmake完全没有这个问题,因为所有的细节处理都被cmake后台处理好了。
2.软件越抽象,用户体验越好,但是也越不透明,如果构建系统除了bug,更难排查。我们学习物理知道能量守恒,其实难度也是守恒的,软件无论怎么分层,只不过是拆东补西的事情,工作量那么多,总量是不变的,还是拿cmake为例,它的简单易用是以背后复杂的自动构建逻辑为代价的。
3.要勇于尝试新鲜的东西,担心是诅咒,祝福是保佑,恐惧感来源于未知,当经过互相了解之后,排除了彼此的陌生感,恐惧感会自动消除,当然,如何克服第一次,要看自己了。