为什么在shell脚本中调用make命令会创建一个可执行文件?

6
我写了一个简单的shell脚本(名为test.sh),使用两个不同的编译器(g++和clang++)编译一个测试C ++文件,并添加一些echo语句来比较输出。在命令行上,我意外地输入了make test,尽管该目录中没有Makefile。它执行了以下命令而不是抱怨没有Makefile或没有定义目标(我的系统运行64位Debian stretch OS与GNU Make 4.1)。
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会自动创建可执行文件?

1
如果你正在使用GNU Make(很可能是这样),你可以运行make -d other来查看它将尝试的所有后缀的详细列表。 - William Pursell
1
从我的信息页面:默认后缀列表为:.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'. - William Pursell
3
谁决定在文档中加入反引号是个好主意?! - William Pursell
2个回答

5
这是 Gnu make 内置的“隐式规则”之一。(每个 make 实现都会有一些隐式规则,但不能保证它们相同。)
  1. 为什么 make 会自动创建没有 .sh 扩展名的可执行脚本?
有一个叫做 Source Code Control System (SCCS) 的旧源代码存储系统。虽然它已经不怎么使用了,但它曾经是维护源代码存储库的最常见方式。它有一个怪癖,即不保留文件权限,因此如果你在 SCCS 中保留了(可执行的)shell 脚本,并稍后检出它,那么它将不再是可执行的。Gnu make 可以自动从 SCCS 存储库中提取文件;为了弥补消失的可执行权限问题,通常使用 .sh 扩展名来表示 shell 脚本;然后 make 可以进行两步提取,首先从存储库中提取 foo.sh,然后将其复制到 foo,并添加可执行权限。
  1. 这是正常/预期/标准行为吗?我能在所有Linux机器上依赖这个行为吗?

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

BSD make也带有一个默认规则用于 .sh,但它只会复制文件;它不会更改权限(至少在我的机器上的bsdmake分发版上如此)。因此,这种行为不是普遍存在的。

  1. 是否有一个支持的“隐含后缀名”列表,对于这些后缀名,make将自动创建可执行文件?

是的,有的。您可以在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 

制作选项摘要所述。


1

来自make命令的手册:

make实用程序的目的是自动确定需要重新编译大型程序的哪些部分,并发出重新编译它们的命令。该手册描述了Richard Stallman和Roland McGrath编写的GNU实现,目前由Paul Smith维护。我们的示例显示C程序,因为它们最常见,但您可以使用任何编程语言的编译器以shell命令运行make。事实上,make不限于程序。每当其他文件更改时,您可以使用它来描述需要自动更新某些文件的任何任务。

make确实比大多数人想象的更强大...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接