让cmake显示gcc/g++的编译信息

本文从一个简单的“Hello World”项目入手,介绍了CMake的基础用法,包括项目配置、编译命令及调试信息输出等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目目录结构

第一个项目,肯定是大家都懂的“hello world”了。那就先来看一下这个“庞大”的项目结构吧。

哈哈,其实就只有一个代码文件 main.c。源码内容嘛,程序员都知道。

至于CMakeLists.txt嘛,那当然就是今天的主角了。换句话说,以前的Makefile(makefile)已经被CMakeLists.txt取代了。稍后再重点介绍。

还有一个空文件夹build,干嘛用的呢。它就相当于一个垃圾桶,我们实用cmake的外部构建的方式的时候,编译过程中产生的一些中间文件,比如.o文件,cmake本身的中间文件等等都会放到build里面。而我们的源码目录干干净净,是不是很适合有代码洁癖的你呢。

 

   撸起袖子写cmake

按照以前,我就得去找其他项目的Makefile过来改,然后凑合的用了。可现在,我可以“骄傲”的说,我可以白手起家搞定CMakeLists.txt。一起见证奇迹!

哈哈,就是这么简单。就3行cmake语法。其实前面2行可以不写,你只写一行就可以了。既然写了,就稍微解释一下语法吧(太深入,我也不懂)。

     PROJECT(projectname [CXX] [C] [JAVA])

用于指定工程名字,[]为可选内容,默认表示支持所有语言。注意这条指令还隐式定义了另外两个变量<projectName>_BINARY_DIR 和<projectName>_SOURCE_DIR。我们这里的project定义为了hello,所以这两个变量就是${hello_BINARY_DIR} 和 ${hello_SOURCE_DIR}。什么意思呢,可以用message命令打印出来看看他的值。

${hello_BINARY_DIR} :就是cmake要(构建)编译我们的项目(main.c)的具体路径。这里当然就是build。

${hello_SOURCE_DIR} :就是我们项目的源码的具体路径,这里当然是项目的根目录。

如果采用的是内部构建的方式,即直接在项目根目录下运行cmake,那这两个变量的值是一样的。不过一般很少使用这两个变量。大家都比较喜欢用 ${CMAKE_SOURCE_DIR} 和 ${CMAKE_BINARY_DIR}.

    cmake_minimum_required

这个就比较好理解了,就是这个项目要求的cmake版本不能低于2.8版本。当使用新版本的cmake才有的特性的时候,就需要加上这个了。

 

   add_executable

顾名思义,就是要生成一个可执行程序hello呗。注意这里的hello和project里面的hello是没有关系的。这里的hello,是说最终编译出来的二进制文件名字叫hello。你可以改成你喜欢的名字。那hello当然是通过main.c来编译的了。如果有多个.c文件,一并在后面加入就行。但是如果你深入学习了cmake,其实是不用一个一个手工写.c文件的。这里只有一个main.c就无所谓了。

 

加上message打印cmake调试信息后的cmake如下:

 

 愉快的编译项目吧

运行cmake的方式就是 :

cmake CMakeLists.txt所在的路径

 

我们采用外部构建的方式。到build文件夹里面(cd build)

哈哈,太好了。cmake帮我生成了Makefile。而代码外面还是非常干净的,就一个mian.c。通过message打印出来的信息看,果然验证了上面的解释。

那接下来就可以开心的make了

 

    让make更透明些

make顺利的执行成功了,也得到了我们期待的“hello world”。但是make的信息太简单了,感觉空落落的。以前的Makefile可都是打印出gcc 等详细编译过程的哦。

不要担心,make的时候加个参数就行了。

make VERBOSE=1

这样你就可以在编译信息里面看到你想要的详细的gcc/g++的编译参数了。比如:

[100%] Building C object CMakeFiles/hello.dir/main.c.o
/usr/bin/cc -o CMakeFiles/hello.dir/main.c.o -c /home/study/program/cmake/hello/main.c
Linking C executable hello

 

什么,要在make的时候写参数。太不友好了。cmake知道你懒,所以也帮你搞定了。在CMakeLists.txt里面加上这句指令就可以了。

set(CMAKE_VERBOSE_MAKEFILE ON)

 

真爽,睡觉~~

<think>我们正在讨论的是如何在make编译时使用静默模式来避免打印编译信息。根据引用内容,静默编译是通过在make命令中添加`-s`选项来实现的,这个选项会作为`MAKEFLAGS`传递给Makefile,进而影响Makefile中的变量(如`XECHO`)来抑制输出。用户之前的问题是关于Jenkins取消日志限制的,但当前问题独立于Jenkins,是关于make的静默编译。因此,我们直接回答如何在使用make编译时启用静默模式。###静默编译的实现方法在make编译过程中,默认会打印出执行的命令以及一些状态信息。如果希望隐藏这些信息,可以使用以下方法:####1.**使用`make-s`命令**在命令行中直接使用`-s`选项,这是最直接的方法:```bashmake-s```这会将`-s`标志添加到`MAKEFLAGS`变量中,Makefile中通常会有相应的处理逻辑来抑制输出。####2.**在Makefile中设置静默模式**如果希望默认静默,可以在Makefile中设置静默编译的逻辑。通常在Makefile中会有类似以下代码:```makefile#静默编译设置ifneq(,$(findstrings,$(MAKEFLAGS)))XECHO=:elseXECHO=echoendif```当检测到`MAKEFLAGS`中包含`s`时,将`XECHO`设置为空命令(`:`),否则设置为`echo`。这样,在Makefile中原本使用`$(XECHO)`的地方就会根据是否静默来决定是否输出。####3.**通过环境变量设置**也可以设置环境变量`MAKEFLAGS`来传递`-s`选项:```bashexportMAKEFLAGS=smake```或者:```bashMAKEFLAGS=smake```###静默编译原理-`-s`选项是make的一个标准选项,用于禁止打印命令(等同于`--silent`或`--quiet`)[^3][^4]。-在Makefile中,可以通过检查`MAKEFLAGS`变量中是否包含字母`s`来判断是否处于静默模式[^3][^5]。-然后,将原本用于输出信息的命令(如`echo`)替换为空命令(`:`),从而实现静默编译。###示例假设有一个简单的Makefile:```makefile#检查静默标志ifeq(,$(findstrings,$(MAKEFLAGS)))XECHO=echoelseXECHO=:endifall:@$(XECHO)"开始编译..."gcc-otesttest.c@$(XECHO)"编译完成"```-当执行`make`时,会输出:```开始编译...编译完成```-当执行`make-s`时,没有任何输出(静默模式)。###注意事项1.**静默模式可能隐藏错误信息**:在静默模式下,错误信息也会被隐藏,可能给调试带来困难。2.**部分输出无法静默**:某些由编译器直接产生的输出(如gcc的警告和错误)可能无法通过`-s`完全隐藏,需要编译器选项(如`-s`或`-q`)配合。3.**Makefile的兼容性**:不是所有Makefile都支持静默编译,需要Makefile中有相应的处理逻辑(如使用`@`前缀或检查`MAKEFLAGS`)。###在Jenkins中的应用如果用户之前在Jenkins中遇到日志限制问题,并且现在需要在Jenkins中使用静默编译,可以结合之前取消日志限制的方法:1.在Jenkins的构建步骤中使用`make-s`。2.同时确保Jenkins的日志限制已被取消(参考之前的解决方案),以避免静默编译产生的大日志被截断。---###相关问题1.如何在Makefile中同时支持静默编译和详细编译模式?2.如何将make的静默编译与Jenkins的日志轮转策略结合?3.静默编译下如何捕获和记录编译错误?</think>### Make 编译静默模式实现方法 在 Make 编译中使用静默模式可以有效隐藏编译信息,以下是三种实现方法: #### 1. **使用 `-s` 选项(推荐方法)** 在命令行中添加 `-s` 选项: ```bash make -s ``` - **原理**:`-s` 会作为 `MAKEFLAGS` 传递给 Makefile[^3][^4] - 在 Makefile 中通常有类似逻辑: ```makefile # 静默编译检测 ifeq (,$(findstring s,$(MAKEFLAGS))) XECHO = echo # 非静默模式显示输出 else XECHO = : # 静默模式禁用输出 endif ``` 当检测到 `-s` 时,`XECHO` 被设为空命令 (`:`),抑制编译信息输出[^3] #### 2. **修改 Makefile 实现永久静默** 在 Makefile 开头添加: ```makefile # 强制启用静默模式 XECHO = : ``` 或修改命令前缀: ```makefile # 在所有命令前添加 @ 符号 target: @gcc -c file.c # @ 前缀抑制命令回显 ``` #### 3. **通过环境变量控制** ```bash # 设置静默环境变量 export MAKEFLAGS=s make ``` 或临时设置: ```bash MAKEFLAGS=s make ``` ### 静默编译原理详解 1. **`findstring` 函数**:检测 `MAKEFLAGS` 中是否包含 `s` ```makefile $(findstring s,$(MAKEFLAGS)) # 找到返回 "s",否则返回空 ``` 2. **条件判断**:根据结果设置 `XECHO` ```makefile ifeq (,$(...)) # 若为空(找到s) XECHO = : # 设为空命令 endif ``` 3. **输出控制**:原输出命令被替换 ```makefile $(XECHO) "Compiling..." # 静默模式下变为 : "Compiling..." ``` ### 在 Jenkins 中的应用 结合之前取消日志限制的方案: ```groovy pipeline { agent any options { disableLogSizeLimit() // 取消日志限制 } stages { stage('Build') { steps { sh 'make -s' // 静默编译 } } } } ``` ### ⚠️ 注意事项 1. **错误信息可见性**:静默模式仍会显示错误信息 2. **调试建议**:调试时移除 `-s` 以便查看完整编译过程 3. **兼容性**:确保 Makefile 包含静默检测逻辑(常见于 U-Boot/Linux 等项目的 Makefile) > 示例:U-Boot 主 Makefile 中的静默编译实现[^3][^5]: > ```makefile > # Allow for silent builds > ifeq (,$(findstring s,$(MAKEFLAGS))) > XECHO = echo > else > XECHO = : > endif > ``` --- ### 相关问题 1. 如何在 Makefile 中区分静默模式与非静默模式的操作? 2. 静默编译模式下如何确保关键警告信息不被隐藏? 3. 如何将 Make 的编译输出重定向到日志文件? 4. 在不同版本的 Make 中静默模式实现有何差异? 5. 在持续集成系统中如何平衡日志详细度与存储限制?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值