为什么使用 shell 脚本目标调用 make 会创建可执行文件?

cal*_*ter 6 linux bash shell gnu-make

我编写了一个简单的 shell 脚本(称为test.sh)来使用两个不同的编译器(g++ 和 clang++)编译测试 C++ 文件,并放入一些echo语句来比较输出。在命令行上,我不小心输入了make test,即使该目录中没有 Makefile 。它没有抱怨没有 Makefile 或没有定义目标,而是执行了以下命令(我的系统正在运行带有 GNU Make 4.1 的 64 位 Debian Stretch 操作系统):

user@hostname test_dir$ make test
cat test.sh >test
chmod a+x test
user@hostname test_dir$
Run Code Online (Sandbox Code Playgroud)

对此感到好奇,我制作了另一个 shell 脚本 ( other.sh) 并做了同样的事情。

这是我的other.sh文件:

#!/bin/bash

echo ""
echo "This is another test script!"
echo ""
Run Code Online (Sandbox Code Playgroud)

命令行:

user@hostname test_dir$ make other
cat other.sh >other
chmod a+x other
user@hostname test_dir$
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么在终端中运行命令时会make自动创建可执行脚本(不带.sh扩展名) ?make这是正常/预期/标准行为吗?我可以在所有 Linux 机器上依赖这种行为吗?


附带问题/注意:是否有受支持的“隐式后缀”列表,make将自动为其创建可执行文件?

ric*_*ici 5

这是 Gnu make 中内置的许多“隐式规则”之一。(每个 make 实现都会有一些隐含规则,但不能保证它们是相同的。)

  1. 为什么 make 会自动创建一个不带 .sh 扩展名的可执行脚本?

有一个称为源代码控制系统(SCCS)的旧源存储库系统。尽管它不再有太多用处,但它曾经是维护源代码存储库的最常见方式。它有一个怪癖,即它不保留文件权限,因此如果您在 SCCS 中保留(可执行)shell 脚本并稍后将其检出,它将不再可执行。Gnu make 可以自动从 SCCS 存储库中提取文件;为了弥补可执行权限消失的问题,通常将.sh扩展与 shell 脚本一起使用;make然后可以进行两步提取,首先foo.sh从存储库中提取,然后将其复制到foo,添加可执行权限。

  1. 这是正常/预期/标准行为吗?我可以在所有 Linux 机器上依赖这种行为吗?

安装了开发工具集的 Linux 系统倾向于使用 Gnu make,因此您应该能够在用于开发的 Linux 系统上依靠这种行为。

BSD make 还带有默认规则.sh,但它只复制文件;它不会更改权限(至少在我机器上的 bsdmake 发行版上)。因此,这种行为并不具有普遍性。

  1. 是否有受支持的“隐式后缀”列表,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 
Run Code Online (Sandbox Code Playgroud)

make 选项摘要中所述。