2009-05-24 105 views
14

这个问题可能不是描述我的问题的最好的问题,但我想不出一个更好的问题。我的生成文件是这样的:如何正确地让我的makefile编译并运行?

PROGRAM_NAME = prog 

OBJECT_FILES = $(PROGRAM_NAME).o 
CFLAGS = -O2 -Wall -g 

$(PROGRAM_NAME) : $(OBJECT_FILES) 
    gcc $(CFLAGS) -o [email protected] $(OBJECT_FILES) 

$(PROGRAM_NAME).o : $(PROGRAM_NAME).c data.h 
    gcc $(CFLAGS) -c $< 

clean : 
    $(RM) $(PROGRAM_NAME) 
    $(RM) $(OBJECT_FILES) 
    $(RM) *~ *.bak 

run : 
    @$(MAKE) && ./$(PROGRAM_NAME) $(ARGS) 

当我想编译和运行我只是做“运行”。问题在于我的程序处理Ctrl + Z产生的信号,如果我用“make run”启动程序,信号将被发送到“make run”,而不是我的程序本身。

基本上,调用“make run”与直接调用“make & & ./prog”不同,因为在第一种情况下,“make run”不会终止,除非“prog”先终止。

有没有办法解决?

回答

12

从makefile运行有点不寻常。您是否可能试图复制某些IDE提供的“编译和运行”菜单项? Make没有很好的装备来做到这一点。

目标命令中发生的所有事情都发生在没有直接连接到终端的子流程中,这就是为什么接收您的关键笔划。

另一件需要注意的事情是:通常对象文件到可执行阶段(链接)使用一组不同的标志(LDFLAGSLIBS),然后是编译阶段。在这个简单的例子中,你可以避开它,但是如果你复制这个makefile以用于更复杂的情况,你会遇到麻烦。

+0

我最好不要使用这种方式,然后... :) – 2009-05-24 15:43:01

3

正如dmckee的回答所说,make(1)正在做一些事情,而不是为了编译和运行。

当然,没有什么可以阻止你创建别名化妆运行这确实预期“使& & ./prog ARGS”。

13

你可以有它取决于你的程序是否是最新的,简化您的“运行”目标,然后只需运行该程序:

run: ${PROGRAM_NAME} 
     ./${PROGRAM} ${ARGS} 

当你没有太多的点运行make已经在运行make - 至少,不是在这方面。可能用于递归操作(在不同的目录中),但请参见'Recursive Make Considered Harmful'。

另外,你的makefile通常应该提供一个目标'all',它通常应该是第一个,因此是默认目标。

4

如果你要建立和运行一遍又一遍,你可以使用history命令,以帮助这一点:

# Run this once 
make && ./foo 

# Repeat last command 
!! 
+2

更妙,在Bash中你可以使用`!make`重复最后一个以“make”开始的命令,即使你在其间运行其他命令。该工作流对我来说效果很好。 – 2015-09-21 02:53:11