C语言 在后台运行make

lyfkaqu1  于 2022-12-17  发布在  其他
关注(0)|答案(3)|浏览(310)

我想创建一个C程序,用同一个Makefile创建几个不同的可执行二进制文件,但名称不同。
但是每次我运行一个相当大的程序的“make”时,他们都会有一堆日志输出...如果我做了几个这样的终端就会很“脏”
所以问题是,在后台运行“make”真的可以吗,这样我就不必看到那些日志了?这是个好主意吗?或者这实际上与把它放在后台无关吗?
若然,我如何能这样做?
对于这个程序来说,它或多或少像下面这样,其中tmp 2是二进制文件名的数组

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

日志与上面类似,是简化版本,只是-Wall中的所有内容和gcc等实际命令
那么,有没有办法不看到“make”日志呢?

编辑

对于make文件

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)

因此,这个make文件实际上是由组中的其他人创建的,我无法真正显示这些内容的确切路径,但希望这能有所帮助

polhcujo

polhcujo1#

首先,与make的不同示例并行运行相同的make/makefile可能会导致争用条件--因此,这不是一个好主意。(例如,如果make的示例1试图访问示例2正在更新的依赖项,则可能导致数据损坏)
也就是说,您可以通过使用make as so的单个示例来解决这个问题:

make -j targ1 targ2 targ3

这将构建targ1targ2targ3,将为所有目标仅构建一次依赖关系,并且将以正确的顺序构建所有内容,等等。
我不清楚为什么要从c文件调用它而不是直接使用命令行,但是如果有原因的话,您会希望它看起来像这样:

char command[1024] = "";
char *eo_command =  command + sizeof(command);
char *ptr = command;

ptr += snprintf(command, sizeof(command) "make -C %s", "file/path/");
// add some checks to ptr here...

for (int j = 0; tmp2[j] != NULL; j++) {
        ptr += snprintf(ptr, eo_command-ptr, " %s", tmp2[j]);
        // add some checks to ptr here...
}
system(command);

如果你不想看到输出,你可以将输出通过管道传输到/dev/null,同样,如果你想让它构建得更快,你可以将一个-j标志传递到make命令行,这将允许它并行构建多个目标。

xjreopfe

xjreopfe2#

我将结束这个问题,因为@Someprogrammerdude给出的解决方案是我认为最适合我的问题。
所以我通过稍微修改代码来修复我的问题

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

不过,既然Bodo提到了,我也会学习shell脚本。谢谢所有的帮助

fwzugrvs

fwzugrvs3#

可以调用make命令,并在命令末尾添加&,这样进程就在后台生成,您就可以获得PID。
大概是这样:make -SOME_FLAGS &

相关问题