You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

后台运行make是否可行?如何在C程序中屏蔽make编译日志?

问题

我想写一个C程序,通过同一个Makefile生成多个不同名称的可执行文件,但每次编译大型程序时,make会输出大量日志(包括-Wall产生的警告、gcc命令执行信息等),多次执行后终端界面杂乱。我有几个疑问:

  • 把make放后台运行来隐藏日志可行吗?这是好主意吗?或者后台运行和隐藏日志根本没关系?
  • 如果可行,该怎么操作?

我的C程序核心代码如下:

for (int j = 0; tmp2[j] != NULL; j++)
{
    printf("-> %s\n", tmp2[j]);
    char command[128] = "";
    sprintf(command, "make -C %s TARGET=%s all", "file/path/", tmp2[j]);
    system(command);
}

我试过在Linux命令末尾加&后台运行,但日志还是会显示,示例日志如下:

text.c:442:3: warning: blablabla
gcc -W -Wall -Wextra -c -g -Os -I. test1.c
gcc -W -Wall -Wextra -c -g -Os -I. test2.c
gcc -g -o STEM_ECS2_SERVICE_3 main.o json.o config.o debug.o -lnsl  -lm -ldl -lc -lmysqlclient  -lm
/bin/mv *.o ./object

附上团队成员编写的Makefile内容:

include ../../Make.cf
OBJ_DIR         = ./object

CFLAGS      = -g -Os $(INCDIR) $(MYSQLINC) -I./include -export-dynamic
LDFLAGS     = $(SYSNLIB) $(SYSLIB) $(MYSQLLIB) $(THREADLIB) -L$(LIBDIR) \
              -lmysqlclient  -lm 

C_OBJECTS   =   main.o              \
                json.o              \
                ecs_config.o        \
                ecs_debug.o         \

######### define target #########

all:    $(TARGET)

main.o: main.c
    $(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) main.c

json.o: json.c
    $(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) json.c

config.o: config.c
    $(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) config.c

debug.o: debug.c
    $(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) debug.c

$(TARGET):   $(C_OBJECTS)
    $(CC) $(CFLAGS) $(DEFINES) -std=gnu99 -o $(TARGET) $(C_OBJECTS) $(LDFLAGS)
    $(MV) *.o $(OBJ_DIR)

touch:
    $(TOUCH) *.c

clean:
    $(RM) $(OBJ_DIR)/*.o
    rm -f *.o core $(TARGET)

cp:
    cp -f $(TARGET) $(BINDIR)/$(TARGET)

解决方案

1. 后台运行和隐藏日志的关系

后台运行(加&)只是让进程脱离当前终端的前台控制,但进程的标准输出、标准错误仍会默认指向原终端,因此日志依然会打印出来。也就是说,后台运行本身不能直接隐藏日志,必须结合输出重定向才能实现。

2. 屏蔽make日志的具体方法

方法一:使用make的静默模式+输出重定向

make自带静默参数可以屏蔽自身打印的命令行:

  • -s/--silent/--quiet:禁止make打印执行的命令,但gcc的警告、错误仍会输出。
  • 若要彻底屏蔽所有输出(包括警告、错误),需结合输出重定向到空设备。

修改C程序中的命令生成代码:

// 仅屏蔽make打印的命令,保留gcc警告/错误
sprintf(command, "make -s -C %s TARGET=%s all", "file/path/", tmp2[j]);

// 彻底屏蔽所有输出(包括警告、错误)
sprintf(command, "make -s -C %s TARGET=%s all > /dev/null 2>&1", "file/path/", tmp2[j]);

解释:> /dev/null将标准输出丢弃,2>&1把标准错误(如gcc警告)也重定向到标准输出的位置,最终所有输出都会被丢弃。

方法二:直接重定向所有输出(无需make静默选项)

如果不需要保留任何日志,直接重定向所有输出即可:

sprintf(command, "make -C %s TARGET=%s all > /dev/null 2>&1", "file/path/", tmp2[j]);

这种方式无需依赖make的-s参数,同样能屏蔽所有输出。

方法三:修改Makefile(若允许)

如果可以修改团队的Makefile,给每个命令行加上@前缀,能让make不打印这条命令本身:

main.o: main.c
    @$(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) main.c

但这种方法只能屏蔽make打印的命令行,gcc的警告仍会输出。不建议通过修改CFLAGS去掉-Wall/-Wextra来屏蔽警告——这些提示能帮你发现代码潜在问题。

3. 关于后台运行的建议

如果C程序不需要等待make完成再执行下一步,可以结合后台运行和输出重定向,既不阻塞程序,也不会输出日志:

sprintf(command, "make -s -C %s TARGET=%s all > /dev/null 2>&1 &", "file/path/", tmp2[j]);

但要注意:同时后台运行多个make进程会占用更多系统资源,编译大型程序时需根据服务器性能评估是否合适。如果C程序需要按顺序处理每个编译结果,就不要加&,否则会导致逻辑混乱。

内容的提问来源于stack exchange,提问作者dibii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:25:22