我正在为分配编译一些 C 代码并运行“make codeFile”,其中“codeFile”是我的 C 程序的名称,即使我没有 makefile,也创建了一个可执行文件,它运行并工作正确。
有谁知道为什么这有效?为什么即使我没有makefile,make 也会编译一些东西?我能找到的唯一参考是: http ://daly.axiom-developer.org/TimothyDaly_files/class5/node5.html
我正在为分配编译一些 C 代码并运行“make codeFile”,其中“codeFile”是我的 C 程序的名称,即使我没有 makefile,也创建了一个可执行文件,它运行并工作正确。
有谁知道为什么这有效?为什么即使我没有makefile,make 也会编译一些东西?我能找到的唯一参考是: http ://daly.axiom-developer.org/TimothyDaly_files/class5/node5.html
Make 有一个带有隐式规则的内部数据库。您可以使用make -p
来列出它们。还会make -d
告诉您正在应用哪些规则,这样可以帮助您发现在这种情况下使用了哪些隐式规则。
Make 有几个预定义的隐式规则。特别是,在您的情况下,它在尝试确定要为目标做什么时使用两个这样的规则codeFile
:
%: %.o # Link object file
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
%.o: %.c # Compile C source code
$(CC) $(CPPFLAGS) $(CFLAGS) -c
在没有makefile的情况下使用make命令?
make
具有默认的隐含规则,除非您覆盖它们。
根据制作手册页:
make -p -f/dev/null
将列出所有隐式规则(和相关的环境变量),而不尝试实际重新制作文件。
为了演示用法,我make
在 Cygwin 中运行,它给了我一个exe
文件。请注意.c
传递给 make 的名称:
$ ls
hello.c
$ make hello
cc hello.c -o hello
$ ls
hello.c hello.exe
我也在 Ubuntu Linux 上运行了这个,结果和上面几乎一样,但是.exe
扩展不存在,而是我有一个普通的hello
可执行文件:
$ ls
hello.c hello
逐步推导
我认为 make 隐式规则的相关部分如下:
CC = cc
cc
别名为CC
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
创建了一种LINK
格式,其中标志为空,TARGET_ARCH
变量也为空(以允许用户为各种目标架构设置值。)然后我们有:
%: %.c
# recipe to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
^
变量是先决条件,hello.c
。其他变量为空。这些后面是-o
标志和目标名称。空变量解释命令 make run 中的额外空格:
cc hello.c -o hello
并且%: %.c
将给定的目标与以 结尾的相同目标名称的文件名相匹配.c
,这导致配方执行。