【问题标题】:Why does calling make with a shell script target create an executable file?为什么用 shell 脚本目标调用 make 会创建一个可执行文件?
【发布时间】:2017-09-02 01:05:06
【问题描述】:

我编写了一个简单的 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$

对此感到好奇,我制作了另一个 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 -d other 来查看它会尝试的所有后缀的详细列表。
  • 来自我的信息页面:The default suffix list is: .out'、.a', .ln'、.o', .c'、.cc', .C'、.cpp', .p'、@987654339 @.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'。`
  • 谁认为反引号是一个可以放入文档的好字符!?

标签: linux bash shell gnu-make


【解决方案1】:

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

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

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

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

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

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

  1. 是否有受支持的“隐式后缀”列表,make 会为其自动创建可执行文件?

是的,有。您可以在make manual

中找到它

默认后缀列表为:.out,.a,.ln,.o,.c,.cc,.C,.cpp,.p,@987654 987654339@, .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 options summary 中所述。

【讨论】:

    【解决方案2】:

    来自 make 手册页:

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

    make 确实比大多数人制作它是...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 1970-01-01
      • 2017-10-18
      • 1970-01-01
      • 2013-06-06
      相关资源
      最近更新 更多