我刚刚开始在我的大学学习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)
我做错了什么?我希望它编译一次然后显示最新的,如果我没有触及任务。
答案 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>
替换为实际制表符