假设我在一个空目录中。如果我现在创建一个 Makefile,只包含all: randomFilename
一个名为 的空文件randomFilename.sh
,那么 GNU Make 将在调用cat randomFilename.sh >randomFilename; chmod a+x randomFilename
时执行。make
$ echo 'all: randomFilename' > Makefile
$ make
make: *** No rule to make target 'randomFilename', needed by 'all'. Stop.
$ touch randomFilename.sh
$ make
cat randomFilename.sh >randomFilename
chmod a+x randomFilename
$ make -v | head -n2
GNU Make 4.0
Built for x86_64-pc-linux-gnu
更糟糕的是,Make 会覆盖名为 的文件randomFilename
(如果该文件已存在)。
$ echo "My content" > randomFilename
$ echo "My content, all gone" > randomFilename.sh
$ make -B
cat randomFilename.sh >randomFilename
chmod a+x randomFilename
$ cat randomFilename
My content, all gone
我想找到 Make 这样做的原因以及防止这种行为的方法。
答案1
此行为是 Make 的内置后缀规则的结果(在本例中为源代码控制系统的旧版本 [1])。可以通过指定空.SUFFIXES
伪目标 [来禁用内置后缀规则2]:
$ echo '.SUFFIXES:' > Makefile
$ echo 'all: randomFilename' >> Makefile
$ make
make: *** No rule to make target 'randomFilename', needed by 'all'. Stop.
$ touch randomFilename.sh
$ make
make: *** No rule to make target 'randomFilename', needed by 'all'. Stop.
答案2
您描述的行为不取决于 make 程序,而是取决于 shell。
如果您有 POSIX shell 并且让 makefile 中的每个命令行都以以下内容开头:
set -o noclobber;
现有文件将不再被>
操作符覆盖。
请注意,这仍然不会影响可能被调用和创建文件的其他程序。