我对Makefiles很新;因此,我遇到了一个问题,我无法想出一个好的谷歌搜索来帮助回答。
我正在运行一个虚拟操作系统,其中包含其他人设置的fedora发行版。如果我在一个目录中构建自己的Makefile,我可以设置我的.c
文件来编译,但我喜欢。但是,如果我只是运行make test
,我的目录中存在test.c
,我将获得以下内容:clang -ggdb3 -std=c99 -Wall -Werror test.c -lcs50 -lm -o test
。
根据这一观察结果,我的问题是这种看似普遍的,make
行为的默认行为来自哪里?换句话说,这个Makefile在哪里,如果它是一个,就坐在我的文件系统上?
答案 0 :(得分:4)
make
有several predefined implicit rules。其中两个是:
编译C程序 n.o是从n.c自动生成的,其形式为'$(CC)$(CPPFLAGS)$(CFLAGS)-c'。
关联单个目标文件 n是通过C编译器运行链接器(通常称为ld)从n.o自动生成的。使用的精确配方是'$(CC)$(LDFLAGS)n.o $(LOADLIBES)$(LDLIBS)'。
注意,make
足够智能,可以在上述两个规则有效时将其有效地连接成一个规则:
...可以通过使用'.o'对象文件作为中间体来完成,但是在一步中进行编译和链接会更快,因此它是如何进行的。完成。
您可以使用make -pn
转储预定义规则。 e.g:
$ make -pn -f /dev/null | grep -A3 '^%: %.c$' make: *** No targets. Stop. %: %.c # commands to execute (built-in): $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@ $
答案 1 :(得分:2)
这适用于GNU make,它通常是linux上的默认make
实现。
文件系统上没有包含默认规则的默认Makefile。
然而,make中内置的隐式规则是否有效,无论您是否提供makefile,以及make
在调用时所执行的操作
记录here。
这些规则知道,例如如何从.c源文件构建可执行文件。您可以了解这些隐式规则here,
例如make在构建可执行文件时有此默认规则:
n通过运行链接器(通常称为n)从n.o自动生成 ld)通过C编译器。使用的精确配方是'$(CC)$(LDFLAGS) n.o $(LOADLIBES)$(LDLIBS)'
如果您运行make test
,则意味着它将尝试从文件test.o创建可执行文件test
,您可以设置相应的CC / LDFLAGS /等。链接时将使用的变量。
作为另一个隐式规则,它可以从.c文件构建.o文件,因此上面将查找test.o
,并尝试使用规则重建该文件:
n.o是从n.c自动生成的,其形式为'$(CC) $(CPPFLAGS)$(CFLAGS)-c'。
即。运行make test
时的隐式规则将首先编译test.c,然后使用您使用CC envirnment变量(或默认编译器cc
)指定的编译器和各种编译器/链接器标志链接test.o如果你将那时设置为环境变量。