Makefile每次编译

时间:2016-10-27 15:42:50

标签: c makefile

我刚刚开始在我的大学学习C编程语言。我们有一个任务是创建一个使用可执行程序的Makefile(在我的情况下是战斗),并且仅在必要时编译。我的问题是它每次使用make命令时都会编译它并且它没有显示"是最新的"我想要。我有两个要编译的对象(quest.o和thorgrim.o,只有quest.o必须创建,因为我们已经有thorgrim.o)进入" battle"。这是我的代码:

CC=gcc
EXE=battle
CFLAGS=-Wall

build: run
run: quest.o
     $(CC) $^ thorgrim.o -o $(EXE)
     ./$(EXE)
quest.o: quest.c
     $(CC) -c $^ -o $@
clean: rm -rf quest.o $(EXE)

我做错了什么?我希望它编译一次然后显示最新的,如果我没有触及任务。

4 个答案:

答案 0 :(得分:1)

运行目标依赖于文件,但构建规则不会生成名为“run”的文件。更好的想法是沿着这些方向做点什么:

run: $(EXE)
     ./$(EXE)

$(EXE): $(OBJ)
       $(CC) $(CFLAGS) -o $@ $+ 

答案 1 :(得分:1)

看到你是新手,我会引导你完成它,这样你就可以学会在第一时间做到这一点。有很多小细节,很多人最终都失踪了,所以希望这会给你一个很好的参考:

首先,让我们从定义对象开始

OBJS := quest.o thorgrim.o

您现在可以创建一个模式规则:

%.o: %.c
     $(CC) $(CFLAGS) -MD -MP $< -c -o $@

此规则的第一行%.o:%.c表示以.o结尾的任何内容都取决于以.c结尾的同名文件。这样做可以防止您为每个目标文件编写单独的规则。请注意,此效果有一个默认模式规则,但我们不会在此处进行说明。

接下来,您使用$(CC)致电$(CFALGS)。请注意,$@现在表示要生成的.o文件的名称,$<表示对象的第一个依赖项(在本例中为.c文件)。

-MD-MP用于自动生成依赖项文件 - 对于每个.c文件,它还将创建一个.d文件,其中列出了依赖项({您的源需要构建的{1}}个文件。您必须.h依赖项文件才能工作。 (有关这些内容的详细信息,请参阅https://gcc.gnu.org/onlinedocs/gcc-4.3.1/gcc/Preprocessor-Options.html)。这样,如果您修改头文件,它将自动重建必要的-include文件。话虽如此,您必须在makefile中包含这些.d文件:

.o

这将包含.d文件,就像有人将代码剪切并粘贴到您的makefile中一样。 -include $(OBJS:.o=.d) 只是告诉make获取变量$(OBJS:.o=.d)并将所有OBJS替换为.o。注意包含之前的.d。这告诉不要担心文件是否不存在(就像你第一次构建的情况一样......)。

好的,既然您已经构建了.o文件,那么您需要构建您的程序:

-

添加默认规则和评论,您就完成了。因此,总之,您的makefile将类似于:

$(EXE): $(OBJS)
    $(CC) $^ -o $@

编辑:忘了干净的规则 - 添加它。

答案 2 :(得分:0)

你没有正确地做到这一点 这是&#34; Makefile模板&#34;:

CC=gcc
none: prog  #`make` -> `make prog`

#make's default rules are fine here.
prog: foo.o bar.o

foo.o: foo.c head.h

bar.o: bar.c head.h

编辑:您需要使用whatever.o whatever作为目标文件,因此请知道传递-c

答案 3 :(得分:0)

编辑:将$(EXE)作为依赖添加到run目标

以下makefile显示了应该如何编写

生成任何宏时,生成的内容不会更改,始终使用:=而不是=,因此宏只会被评估一次

为可执行文件生成宏时,请始终包含可执行文件的完整路径,以便始终执行正确的可执行文件,而不管系统和/或环境“PATH”的其他更改

注意:但是,要在可执行文件中包含多个文件,为了能够在文件之间进行通信,每个源文件应该有一个头文件,这些内容需要公开(数据和函数以及数据类型)然后那些编译时需要在依赖项中列出头文件。

CC := /usr/lib/gcc
RM := /usr/lib/rm -f -r

EXE := battle
CFLAGS := -Wall -Wextra -Wconversion -std=gnu99 -c

# macro with all the source names
SRCS := thorgrim.c quest.c

# macro with all the object file names
OBJS := $(SRCS:.c=.o)

# always include a .PHONY statement for any targets
# that do not produce a file of the same name
.PHONY : all clean run

# 'all' is the typical first target
all: run

# implied compile rule/recipe
%.o:%.c
<tab>$(CC) $(CFLAGS) -o $@ $<

# the macro 'LFLAGS' is part of the default macros
# link the objects into an executable
$(EXE): $(OBJS)
<tab>$(CC) $^ -o $@ $(LFLAGS)

# execute the executable
run: $(EXE)
<tab>./$(EXE)


clean: 
<tab>$(RM) quest.o $(EXE)

注意:将<tab>替换为实际制表符