我正在阅读一个大型Makefile,其中一部分我不明白:
$(IREJECTION): $(IREJECTION:%$(MACH64).o=%.cpp)
$(CPP) $(CPPDLIBOPTS) -c $(@:%$(MACH64).o=%.cpp) -o $@
在这个脚本中(注意我删除了不必要的变量以避免冗长),以下是什么意思
$(IREJECTION:%$(MACH64).o=%.cpp)
(在第一行)$(@:%$(MACH64).o=%.cpp)
? (在第二行)此外,这种形式A: B
是什么意思?如:
$(IREJECTION): $(IREJECTION:%$(MACH64).o=%.cpp) #on the first line
<---- A ----> <------------ B ---------------> #first instance of A: B
<--- A ----> <-------- B ------> #second instance of A: B
如您所见,A:B
形式有两个实例 - 第二个实例位于B
内部。我也在这里看到类似的东西:
$(@:%$(MACH64).o=%.cpp) #on the second line
<A> <---------B------->
请帮助我理解这一点。
答案 0 :(得分:4)
我认为你有一个非常复杂的例子。它有很多东西。
A: B
<command>
A
- 目标B
- 依赖<command>
- 要执行以构建A
(“食谱”)的命令 target: dependency
被称为“规则”。
总而言之,上面的例子是带有适当“配方”的“规则”。
(要A
,取决于B
,需要执行<command>
)
make
会比较B
和A
的修改日期。如果B
较新,则会执行<command>
$(IREJECTION)
是make
的变量(应该在文件之前的某处定义,例如IREJECTION:=somefile.o
)
在make
执行期间$(IREJECTION)
被替换为变量的实际值。
从以下链接:
$(var:a=b)
&lt; ..&gt;取变量var
的值,将单词末尾的每个'a'替换为该值中的'b',并替换生成的字符串。
和
例如:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
将bar
设置为a.c b.c c.c
。
在您的案例$(IREJECTION:%$(MACH64).o=%.cpp)
中,它采用名为IREJECTION
的变量,尝试在单词的末尾找到$(MACH64).o
(也引用变量MACH64
)并替换它与.cpp
。
$@
称为自动变量。
它是指'目标'。
答案 1 :(得分:2)
A: B
意味着你添加一个依赖于B的make目标A.这意味着当B被更改时,它必须在A完成之前运行。
您可以通过调用make A
来使用目标A.
答案 2 :(得分:1)
我一步一步走:
假设您有一些目标文件irejection.mach64.o
和源文件irejection.cpp
从源代码生成对象,通常会编写一个类似于
的规则irejection.mach64.o : irejection.cpp # means target : dependencies
$(CC) irejection.cpp -o $@ # $@ is a special variable - the target (output)
现在我们可以说$(MACH64)
为.mach64
而$(IREJECTION)
为irejection$(MACH64).o
,即irejection.mach64.o
$(IREJECTION:%$(MACH64).o=%.cpp)
将扩展为irejection.cpp
$(@:%$(MACH64).o=%.cpp)
将扩展为相同,因为$@
为$(IREJECTION)
实质上,给定具有体系结构扩展的目标文件目标,将文件名重写为其源文件副本。
似乎对我来说是不可思议的错综复杂的。更清洁的方式就像:
%$(MACH64).o : %.cpp
$(CC) -c $@ $<
%
是&#34;通配符&#34;,$<
是第一个依赖项,$@
是输出
请参阅:http://www.gnu.org/software/make/manual/make.html#Automatic-Variables
http://www.gnu.org/software/make/manual/make.html#Pattern-Rules