Я обнаружил разницу в поведении между GNU Make 4.1 и 3.81 и задался вопросом, не является ли мой код POSIX-совместимым, который 4 обеспечивает более строгое соблюдение, или происходит что-то еще.
Я вычеркнул случай сбояв этот Makefile
.POSIX:
all: test-b
test-a:
cat a.txt b.txt c.txt >results.txt
test-b:
cat {a,b,c}.txt >results.txt
Если эти файлы были созданы с помощью cat {a,b,c}.txt
, target test-a
всегда работает, но test-b
работает на Make 3.81, но не работает на 4.1.
выходные данные для 3.81:
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
$ make
cat {a,b,c}.txt >results.txt
$ echo $?
0
выходные данные для 4.1:
$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ make
cat {a,b,c}.txt >results.txt
cat: {a,b,c}.txt: No such file or directory
Makefile:9: recipe for target 'test-b' failed
make: *** [test-b] Error 1
$ echo $?
2
Возможно, команда cat
фактически не работает в 3.81 и просто не указывает на нее, так какв более поздних версиях GNU При упоминании команд назначения целевых команд необходимо указать флаг -e
, чтобы сделать его более совместимым с POSIX, но я не понимаю, как эта команда может давать сбой.
Я предполагаю, что подстановочные знакиобрабатываются исключительно оболочкой, поэтому я не вижу, как вызов оболочки с помощью команды make target должен быть каким-то другим.
Какое поведение является правильным?Если такие символы подстановки не работают в Makefiles, какие другие символы подстановки я могу использовать?
test-b
все еще не работает в 4.1, даже если .POSIX:
удален из файла.