在Linux Makefile中使用tee保存编译输出失败的问题
在Makefile中保存编译输出到文件的正确方法
我尝试在Makefile里将编译输出保存到文件,但多种写法均未成功。测试过的写法包括:
>> tee compile.log 1> tee compile.log 2> tee compile.log &> tee compile.log >> $(tee compile.log) 1>&> tee compile.log 2>&1 tee compile.log | (tee compile.log) | $(tee compile.log) | tee compile.log
上述写法大多无报错,程序能正常编译,但文件始终没有内容。我原本认为可行的写法同样无效:
$(CC) -o $@ $(OBJS) $(CFLAGS) | tee compile.log
问题根源
- 编译输出流向问题:编译器的警告、错误等关键信息默认输出到标准错误(stderr),而非标准输出(stdout),单纯用管道
| tee只能捕获stdout,自然无法获取内容。 - 语法错误:部分写法存在语法问题,比如
2>&1 tee compile.log缺少管道符,正确格式应为2>&1 | tee compile.log。 - Make的输出抑制:Make默认会抑制命令的标准输出,仅在命令执行失败时才打印内容,这也会导致常规重定向无法捕获正常编译的输出。
正确写法
1. 终端显示+文件保存(常用)
合并stderr到stdout,再通过tee同时输出到终端和文件:
$(CC) -o $@ $(OBJS) $(CFLAGS) 2>&1 | tee compile.log
如果需要更详细的编译过程(方便验证文件内容),可以给编译器加-v参数:
$(CC) -v -o $@ $(OBJS) $(CFLAGS) 2>&1 | tee compile.log
2. 仅保存到文件,不显示在终端
直接将stdout和stderr重定向到文件:
$(CC) -o $@ $(OBJS) $(CFLAGS) &> compile.log
完整示例Makefile
OBJS = main.o utils.o CC = gcc CFLAGS = -Wall all: myapp myapp: $(OBJS) $(CC) -v -o $@ $(OBJS) $(CFLAGS) 2>&1 | tee compile.log clean: rm -f myapp $(OBJS) compile.log
执行make后,终端会显示编译细节,compile.log文件也会同步保存所有输出。
内容的提问来源于stack exchange,提问作者user3859005
相关产品推荐
相关产品推荐

