【问题标题】:Could someone explain this make file?有人可以解释这个make文件吗?
【发布时间】:2011-02-23 23:48:33
【问题描述】:

我在 site 上找到了这个 makefile。他们没有解释这个例子,所以我想知道是否有人知道发生了什么。

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

【问题讨论】:

  • 克里斯指出的第一行是定义速记,其余的是“依赖图”。当您更改源文件时,make 系统将开始自下而上执行规则以获得最终结果,最终创建一个最新的可执行文件hello 编译。

标签: makefile


【解决方案1】:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp

将四个变量设置为常量字符串。对于 makefile 的其余部分,无论出现在哪里(例如)$(CC),它将被 g++ 替换

OBJECTS=$(SOURCES:.cpp=.o)

将变量 OBJECTS 设置为与 SOURCES 相同,除非模式 .cpp 出现在 SOURCES 的单词中,它被 .o 替换

EXECUTABLE=hello

设置另一个常量字符串 var

all: $(SOURCES) $(EXECUTABLE)

makefile 中的第一条实际规则,它告诉 make 要构建 all,它必须首先构建 $(SOURCES)$(EXECUTABLE) 中的所有内容,然后什么都不做。既然是第一个,就成为默认目标,所以运行make就相当于make all

$(EXECUTABLE): $(OBJECTS) 
        $(CC) $(LDFLAGS) $(OBJECTS) -o $@

另一个规则:要创建$(EXECUTABLE)(扩展为hello),它必须首先在$(OBJECTS)(相当于main.o hello.o factorial.o)中构建所有内容,然后运行命令$(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
        $(CC) $(CFLAGS) -o $@ $<

模式规则:为了构建以.o结尾的文件,首先重建/创建/找到对应的以.cpp结尾的文件,然后运行命令$(CC) $(CFLAGS) -o $@ $&lt;

最后两个规则包含特殊变量$@$&lt;,它们仅在规则操作中有效,并分别扩展到目标和第一个依赖项

因此,当您运行make 时,它会读取所有这些内容,然后尝试构建默认目标(全部)。 由于它不存在,它会尝试构建文件 main.cpp、hello.cpp、factorial.cpp 和 hello。由于前 3 个(大概)存在,它会为它们寻找规则/依赖关系,但没有找到,因此决定对它们无事可做。如果它们不存在,make 会给出错误提示“no rule to make target 'main.cpp'”

在“hello”的情况下,它依赖于 main.o、hello.o 和 factorial.o,所以它会查看它们。对于 main.o,模式规则说它依赖于 main.cpp,所以如果 main.o 不存在或者如果 main.cpp 更新,它将运行命令g++ -c -Wall -o main.o main.cpp。 hello.o 和 factorial.o 也是如此。

一旦完成,如果hello 不存在或比任何这些 .o 文件都旧(可能刚刚更改,因此可能很新),它将运行该命令以重新链接它。最后,它将运行空命令(什么都不做)来“重建”所有。

【讨论】:

  • 我唯一不明白的是为什么在模式规则中必须再次调用-o $@。你能给我解释一下吗?谢谢
  • @Kyrol: -o 指定要写入的文件的名称。在某些编译器上,默认输出文件可能已经与目标相同,但重新指定并没有什么坏处。
  • .cpp.o: 不是后缀规则而不是模式规则吗?
  • @jdknight:技术上是的,但后缀规则和模式规则实际上只是同一事物的两种略有不同的语法——一个基于文件名模式匹配目标并基于文件名模式计算依赖关系的规则关于那个。
  • @MarcusJ:你会使用像$(OBJDIR)/%.o: %.c; $(CC) $(CFLAGS) -c -o $@ $&lt; 这样的规则,这就是为什么要添加模式规则的部分原因——它们比后缀规则更灵活。
猜你喜欢
  • 1970-01-01
  • 2013-01-09
  • 2012-04-19
  • 2021-01-06
  • 1970-01-01
  • 2011-01-16
  • 2011-03-17
  • 2013-07-13
  • 1970-01-01
相关资源
最近更新 更多