这些 Makefile 结构的含义是什么?
有人可以帮我找出以下 make 文件吗?
BINS=file1 file2 file3
all: $(BINS)
clean:
rm -f $(BINS) *~
$*: [email protected]
gcc -g -o $@ $?
这是我的问题:
- gcc 的 -g 选项是什么?
- $* 和 $@ 是什么?
- 它如何知道执行最后一个目标?
谢谢!
Can someone help me figure out the following make file?
BINS=file1 file2 file3
all: $(BINS)
clean:
rm -f $(BINS) *~
$*: [email protected]
gcc -g -o $@ $?
Here are my questions:
- What is the -g option of gcc?
- What are $* and $@
- How does it know to execute the last target?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
来自
gcc
和make
文档:“-g 以操作系统的本机格式生成调试信息”。
a. "$* 隐式规则匹配的词干(请参阅模式如何匹配)。如果目标是 dir/a.foo.b 并且目标模式是 a.%.b,则词干是 dir/foo。词干是对于构建相关文件的名称很有用。在静态模式规则中,词干是与目标模式中的“%”匹配的文件名的一部分。”
b. “$@ 规则目标的文件名。如果目标是归档成员,则 '$@' 是归档文件的名称。在具有多个目标的模式规则中(请参阅模式规则简介), “$@”是导致规则命令运行的目标的名称。”
c. “$?比目标更新的所有先决条件的名称,它们之间有空格。” (没有询问,但值得添加。)
“'all' 编译整个程序。这应该是默认目标。”
这个示例 makefile 有一点限制,因为它似乎只构建 C 程序。 GNU make 有几个更广泛的示例,可用于了解如何编写 makefile。
From the
gcc
andmake
documentation:"-g Produce debugging information in the operating system's native format".
a. "$* The stem with which an implicit rule matches (see How Patterns Match). If the target is dir/a.foo.b and the target pattern is a.%.b then the stem is dir/foo. The stem is useful for constructing names of related files. In a static pattern rule, the stem is part of the file name that matched the '%' in the target pattern."
b. "$@ The file name of the target of the rule. If the target is an archive member, then '$@' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), '$@' is the name of whichever target caused the rule's commands to be run."
c. "$? The names of all the prerequisites that are newer than the target, with spaces between them." (Not asked, but worth adding.)
"'all' Compile the entire program. This should be the default target."
This example makefile is a bit limited, since it seems to only build C programs. The GNU make has several more extensive examples that are useful for learning how to write makefiles.
生成调试信息
$*
是规则的主干。 当您制定类似 的规则,并且该规则尝试从
file.otherext
生成file.ext
时,则日志将转到file.log
< code>$@ 是目标文件名(在上述情况下为
file.ext
)。这是一个谜。
$*
用于中间文件:例如,当您尝试从%.c
中创建%.so
时,您需要一个既不是目标也不是源的中介%.o
。 换句话说,在
%.extension
规则中,$*
是除.extension
之外的所有内容。作为目标,
$*
没有任何意义。您确定这条规则实际上在某个地方执行了吗? 当我尝试使用您的 Makefile 重现它时,它应用默认规则 (
cc -o
) 而不是gcc -g -o
您需要的规则似乎是:
Generate debugging info
$*
is the stem of the rule. When you make rule like, and the rule tries to make
file.ext
fromfile.otherext
, then to log goes tofile.log
$@
is the target filename (file.ext
in the case above).This is a mystery.
$*
is used for intermediary files: like, when you try to make an%.so
out of%.c
, you'll need an intermediary%.o
which is neither target nor a source. You put:In other words, in a
%.extension
rule,$*
is everything but the.extension
.As a target,
$*
makes no sense.Are you sure this rule is actually executed somewhere? When I try to reproduce it using your Makefile, it applies default rules (
cc -o
) instead ofgcc -g -o
Rule you need seems to be:
GNU Make 手册
GCC 在线文档
The GNU Make Manual
GCC online documentation
第一行的作用正如您所期望的那样 — 它创建一个名称列表并将其分配给
BIN
。 接下来,定义一个名为all
的 make 目标,它依赖于$BIN
中列出的目标(all
无法构建,直到每个$BIN
中的目标已构建)。all
是一个特殊的构建目标; 如果您只是运行make
而不是例如make clean
,则会自动构建all
目标。 没有与 all 关联的实际命令 - 它只是确保构建其所有依赖项。 最后一个相当简单的命令定义了一个名为clean
的构建目标,它删除$BIN
中列出的每个文件(请注意,$BIN
正在使用作为构建目标列表和此 makefile 中的文件列表)和所有备份。接下来,我们看到一条基本上很神奇的线。
$*
是一个特殊的构建目标,意味着“任何未明确定义的内容”。 当make
尝试构建all
时,它会找到目标并开始处理其依赖项。 但是当它尝试构建file1
时,没有定义明确的目标。 相反,它使用$*
来构建file1
。 类似地,$@
被替换为构建目标的名称,$?
被替换为它的依赖项(某种程度上;您最好检查一下手册)。 当make
去构建file1
时,$*
规则会导致它的行为就像定义了以下规则一样:最后,< code>-g 选项仅允许编译调试信息。
The first line does just what you'd expect by looking at it — it creates a list of names and assigns it to
BIN
. Next, a make target calledall
is defined, which is dependent on the targets listed in$BIN
(all
can't be built until each target in$BIN
is built).all
is a special build target; if you just runmake
rather than, say,make clean
, theall
target is automatically built. There are no actual commands associated withall
— it simply ensures that all its dependencies are built. The last fairly straightforward command defines a build target calledclean
, which deletes each file listed in$BIN
(note that$BIN
is being used both as a list of build targets and a list of files in this makefile) and all backups.Next, we get to a line which is, basically, magic.
$*
is a special build target which means "anything not specifically defined". Whenmake
tries to buildall
, it finds the target and starts work on its dependencies. But when it tries to buildfile1
, there is no explicit target defined. Instead, it uses$*
to buildfile1
. Similarly,$@
gets replaced with the build target's name, and$?
with its dependencies (sort of; that one you're better off checking the manual for). Whenmake
goes to buildfile1
, then, the$*
rule causes it to behave as if the following rule were defined:Finally, the
-g
option simply enables debugging information to be compiled in.Q1 和 Q2 已经得到了广泛的回答,因此仅对 Q3 进行简要说明:
除非您指定了不同的目标,否则 Make 始终执行第一个目标。 这也称为默认目标。 通常默认目标称为“all”。
Q1 and Q2 have been answered extensively already, so a brief explanation for Q3 only:
Make always executes the first target unless you specified a different one. This is also called the default target. Usually the default target is called "all".