前言
从上一篇的文章中,相信大家也了解了CMake
这个东西,但是呢它不是只是看一下就能会的,这种东西还是要实践才能学会,那么如果你已经实践过了,就会体会到上一篇文章在实际中使用到底是多么的难搞,比如:
- 生成很多垃圾文件,这是我的第一个体会….
- 需要手动去指定编译的文件
- 无法指定编译器,编译选项等等很多东西….
- 如果有子目录也不能完全适用….
- 以及一些其他的问题….
总的来说就是在真正项目中压根就没法适用的工程,那为什么我要写呢,因为那是我学习的过程,总不能一口吞下一个大胖子是不是,接下来的一系列文章我就会让CMake
变得能在实际中使用,越来越自动化,更方便构建。。。
外部构建
第一个问题,在运行cmake .
后会产生很多垃圾文件,那么我们可以让它在一个build目录下去编译,生成的垃圾文件放在这个目录下就好了,不需要的时候直接清除即可。
可能有人会问,它不能像Makefile一样直接make clean
或者make distclean
清除编译的垃圾文件吗,我当时学的时候也谷歌过,但是,很遗憾没有,使用我才让它产生的垃圾文件放在build目录下,其实不能说是垃圾文件,只不过是一些中间文件,记录某些东西的,我用不上它,所以认为是垃圾…仅此而已。
对此官方的解释是:
CMakeLists.txt 可以执行脚本并通过脚本生成一些临时文件,但是却没有办法来跟踪这些临时文件到底是哪些,因此,没有办法提供一个可靠的 clean 方案。
那怎么办呢?很简单,从CMake
的语法我们就知道,它在构建的时候指定了PATH
,也就是顶层CMakeLists.txt
入口的路径。
cmake PATH
那么很显然,它可以是相对路径而不是绝对路径,毕竟点‘.’
表示当前路径, 点点‘..’
表示上一级路径,那么我们可以新建一个build目录,然后在build目录下去运行:
cmake ..
这在CMake
中称之为外部构建(out-of-source build),而 CMake
强烈推荐的就是外部构建!
我自己也写了个build的脚本,内容非常简单,主要做两件事:
- 创建一个build目录(存在就不会重新创建的)
- 进入build目录
- 然后外部构建cmake
- 生成Makefile文件后运行make命令编译
#!/bin/bash
mkdir -p build
cd build
cmake ..
make
因此在编译的时候直接运行这个脚本即可,生成的内容全部都在build目录下。
- 这是原始目录
.
├── build.sh
├── CMakeLists.txt
└── main.c
0 directories, 3 files
编译后在build目录下生成很多文件,包括 Makefile、section2(可执行程序)
等
CMakeCache.txt CMakeFiles cmake_install.cmake Makefile section2
补充一点,如果你想看到cmake生成的垃圾文件比你源码还多的时候,你就会爱死外部构建这种骚操作了~
自动查找源码
不得不说,cmake是个很好的自动化构建工具,既然是自动化,那么很的东西都是自动的,比如查找源码,cmake就提供查找源码的命令:
aux_source_directory(<dir> <variable>)
它的主要作用就是: 查找在某个路径下的所有源文件 ,注意,是所有源码文件,当你的目录下有很多个源码文件的时候,他就主动去查找了,哦,当然,它也只会查找源码文件,比如*.c 、 *.cpp 、*.cc
啦,反正只要是源码就可以了,但是什么txt 、 *.h
文件这些它是不会记录下来的。
dir
:指定的目录(可以是绝对路径也可以是相对路径)variable
:将输出结果列表储存在指定的
变量中。
反正这个命令就很方便,我在某个目录下有啥源码文件,我都会被记录到
变量,然后在CMake
直接使用即可。当然后续也有其他的命令去找源码文件,一口吃不了一个大胖子,先了解这个先,后续慢慢学习~
变量
在CMake
中,变量是十分常见的,我正在就简单讲解下基本的语法吧:
定义变量常用的函数是:
set(VARIABLE_NAME VARIABLE)
取消定义变量是
unset(VARIABLE_NAME )
VARIABLE_NAME
:变量名字VARIABLE
:变量的值
变量的的值始终是string(字符串)
类型,变量名字是区分大小写的,一般变量命名还是正常点比较好,别搞太多乱七八糟的特殊符号,只要数字、字母,下划线"_"
、横线"-"
就差不多了,变量的作用域也是有全局与局部之分,与C语言、Java都差不多,我也不多说了。我的例程中全局变量是全部大写,局部变量是全小写
的,也是比较好区分。
变量引用的形式为${variable_name}
,变量引用被变量的值替换,或者如果变量没有被设置,则由空字符串替换。变量引用可以嵌套,例如${outer_${inner_variable}veriable}
;环境变量引用的形式为$ENV{VARIABLE}
,并在相同的上下文中作为正常变量引用。
打印日志
在CMake构建的时候,你可能不知道某些变量是啥内容,那么就在终端打印出来看看就好了,这根我们写代码中的printf函数差不多,给直接打一串字符串出来瞧瞧….
message([] "message to display" ...)
首先呢,
是指定消息的类型:
(无)
= 重要消息;STATUS
= 非重要消息;WARNING
= CMake 警告, 会继续执行;AUTHOR_WARNING
= CMake 警告 (dev), 会继续执行;SEND_ERROR
= CMake 错误, 继续执行,但是会跳过生成的步骤;FATAL_ERROR
= CMake 错误, 终止所有处理过程;
正常情况下我都是输出一些状态信息——STATUS
,打印个变量啦,打印下代码的执行顺序啦等等….
后面就是有些字符串信息了,变量在这里直接引用就好,毕竟变量本身就是字符串….
section3
给出个实例代码:
当前目录存在2个c文件,分别是main.c
、power.c
就是简单计算x的y次方,纯粹是个demo,我自己也懒得写,并不是因为代码有多高深,所以这代码我是从网上找的,来自@潘伟洲大神的cmake测试代码:https://github.com/wzpan/cmake-demo。
- main.c
#include
#include
#include "power.h"
int main(int argc, char *argv[])
{
if (argc < 3){
printf("Usage: %s base exponent \\n", argv[0]);
return 1;
}
double base = atof(argv[1]);
int exponent = atoi(argv[2]);
double result = power(base, exponent);
printf("%g ^ %d is %g\\n", base, exponent, result);
return 0;
}
- power.c
double power(double base, int exponent)
{
int result = base;
int i;
if (exponent == 0) {
return 1;
}
for(i = 1; i < exponent; ++i){
result = result * base;
}
return result;
}
然后就是CMakeLists.txt
文件:
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (section3)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(section3 ${DIR_SRCS})
相比于上一篇文章,我这个CMakeLists.txt
文件只是添加了aux_source_directory
命令去自动扫描当前目录下的源码文件,并且保存到DIR_SRCS
变量中,仅此而已!!
然后在add_executable
命令中,用${DIR_SRCS}
变量代替指定的源码文件source1 source2 ... sourceN
,当然你也可以打印一下${DIR_SRCS}
变量到底保存了什么,如果不出意外的话,它保存的就是./main.c; ./power.c
,表示的是当前目录下的main.c
、power.c
这两个文件,而分号代表它是一个list,后续会讲解怎么去提取list的内容….
message(STATUS "${DIR_SRCS}")
然后用外部构建的方式去编译代码:
jie@pc:~/github/cmake/section3$ ./build.sh
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jie/github/cmake/section3/build
Scanning dependencies of target section3
[ 33%] Building C object CMakeFiles/section3.dir/main.c.o
[ 66%] Building C object CMakeFiles/section3.dir/power.c.o
[100%] Linking C executable section3
[100%] Built target section3
很明显生成了正确可执行文件~
代码下载
https://github.com/jiejieTop/cmake
-
文件
+关注
关注
1文章
561浏览量
24699 -
Build
+关注
关注
0文章
26浏览量
12040 -
CMake
+关注
关注
0文章
28浏览量
1262
发布评论请先 登录
相关推荐
评论