我写了一个简单的shell脚本(称为test.sh
)来编译一个测试C++文件,并使用两个不同的编译器(g++和clang++)编译一个测试文件,并放入一些echo
语句来比较输出。在命令行上,我不小心输入了make test
,即使该目录中没有 Makefile。它没有抱怨没有 Makefile 或没有定义目标,而是执行了以下命令(我的系统正在运行带有 GNU Make 4.1 的 64 位 Debian stretch OS):
user@hostname test_dir$ make test
cat test.sh >test
chmod a+x test
user@hostname test_dir$
出于好奇,我制作了另一个 shell 脚本(other.sh
)并做了同样的事情。
这是我
other.sh
文件:
#!/bin/bash
echo ""
echo "This is another test script!"
echo ""
命令行:
user@hostname test_dir$ make other
cat other.sh >other
chmod a+x other
user@hostname test_dir$
我的问题是为什么在终端中运行make
命令时make
自动创建可执行脚本(没有.sh
扩展名)?这是正常/预期/标准行为吗?我可以在所有 Linux 计算机上依赖此行为吗?
附带问题/注意:是否有受支持的"隐式后缀"列表,make
会自动为其创建可执行文件?
这是内置在 Gnu make 中的许多"隐式规则"之一。(每个 make 实现都会有一些隐式规则,但不能保证它们是相同的。
- 为什么 make 会自动创建没有.sh扩展名的可执行脚本?
有一个旧的源代码存储库系统称为源代码控制系统(SCCS)。虽然它不再有太多用途,但它曾经是维护源代码存储库的最常见方式。它有一个怪癖,它不保留文件权限,所以如果你在SCCS中保留一个(可执行的)shell脚本,后来把它签出来,它将不再是可执行的。Gnu make可以自动从SCCS仓库中提取文件;为了弥补消失的可执行权限问题,通常将.sh
扩展与 shell 脚本一起使用; 然后,make
可以执行两步提取,首先从存储库中提取foo.sh
,然后将其复制到foo
,添加可执行权限。
- 这是正常/预期/标准行为吗?我可以在所有 Linux 计算机上依赖此行为吗?
安装了开发工具集的 Linux 系统倾向于使用 Gnu make,因此您应该能够在用于开发的 Linux 系统上依靠这种行为。
BSD make 还附带了.sh
的默认规则,但它只复制文件;它不会更改权限(至少在我的机器上的 bsdmake 发行版上)。所以这种行为并不普遍。
- 是否有受支持的"隐式后缀"列表,make 将自动为其创建可执行文件?
是的,有。您可以在制作手册中找到它:
默认后缀列表为:
.out
、.a
、.ln
、.o
、.c
、.cc
、.C
、.cpp
、.p
、.f
、.F
、.m
、.r
、.y
、.l
、.ym
、.lm
、.s
、.S
,.mod
,.sym
,.def
,.h
,.info
,.dvi
,.tex
,.texinfo
,.texi
,.txinfo
,.w
,.ch
,.web
、.sh
、.elc
、.el
。
要获得更准确的隐式规则列表,可以使用以下命令
make -p -f/dev/null
# or, if you like typing, make --print-data-base -f /dev/null
如创建选项摘要中所述。
从make
手册页:
make 实用程序的目的是自动确定 哪 大型程序的各个部分需要重新编译,并发出命令 以重新编译它们。 该手册
GNU
描述了 make,由理查德·斯托曼和罗兰·麦格拉思撰写,是 目前由保罗·史密斯维护。 我们的示例显示了C
程序, 因为它们是最常见的,但您可以在任何编程中使用 make 其编译器可以使用 shell 命令运行的语言。 事实上,使 不限于程序。 您可以使用它来描述任何任务,其中 每当其他文件发生更改时,某些文件必须从其他文件自动更新。
make
真的比大多数人想象的要多......