Во-первых, я использую GNU Make 4.3 на Windows 10. Ранее я пробовал GNU Make 4.2.1, которая дала мне те же результаты, что и 4.3.
В любом случае, у меня очень простой make-файл, который делает (или, по крайней мере, намеревается сделать) не что иное, как простую команду и выводит вывод этой команды (как stderr, так и stdout) на терминал и в текстовый файл.
$(info $$(MAKECMDGOALS) is "$(MAKECMDGOALS)". $$(SHELL) is \
"$(SHELL)". $$(MAKESHELL) is "$(MAKESHELL)". $$(COMSPEC) is "$(COMSPEC)". $$(OS) is "$(OS)".)
TEE := C:\tools\UnixTools\usr\local\wbin\tee.exe
LOG_FILE := C:\Temp\loggy__.txt
.PHONY : meep
all : meep
meep :
$(info Making meep.)
$(info Running command {dir 2>&1 | $(TEE) $(LOG_FILE)}.)
$(shell dir 2>&1 | $(TEE) $(LOG_FILE))
Последняя строка - та, которая доставляет мне неприятности. Происходят две вещи, которые противоречат моим ожиданиям:
В то время как вызов $(shell ...)
выводит вывод команды dir
как в мой текстовый файл, так и на терминал, вывод на терминале странно отформатирован. Там, где обычно dir
печатает один элемент на строку, здесь я получаю весь вывод в одну строку, поэтому кажется, что GNU Make (или что-то еще) каким-то образом удаляет символы новой строки из вывода, прежде чем он будет показан в терминале окно.
Кроме того, я получаю сообщение об ошибке The system cannot find the file specified.
(и, как обычно, Windows не достаточно хорош, чтобы сказать мне, какой файл он не может найти ). Запуск echo %errorlevel%
в той же оболочке CMD, в которой я запускал GNU Make, подтверждает, что вызов Make ошибся (состояние выхода равно 2).
Довольно странно, если я запускаю команду dir 2>&1 | C:\tools\UnixTools\usr\local\wbin\tee.exe C:\Temp\loggy__.txt
прямо в окне CMD, все работает точно так, как и следовало ожидать, без каких-либо ошибок, поэтому я думаю, что с функцией GNU Make $(shell ...)
что-то не так, или я использую ее неправильно. Кто-нибудь замечает что-то глупое в том, как я пытаюсь использовать функцию $(shell ...)
?
Я просто добавил --debug = a в мой вызов make, чтобы получить дополнительные выходные данные отладки, и я нашел следующее в output:
Creating temporary batch file C:\Users\mkemp\AppData\Local\Temp\make23400-1.bat
Batch file contents:
@echo off
dir 2>&1 | C:\tools\UnixTools\usr\local\wbin\tee.exe C:\Temp\loggy__.txt
CreateProcess(C:\Users\mkemp\AppData\Local\Temp\make23400-1.bat,C:\Users\mkemp\AppData\Local\Temp\make23400-1.bat,...)
Main thread handle = 00000000000000B4
Cleaning up temporary batch file C:\Users\mkemp\AppData\Local\Temp\make23400-1.bat
Creating temporary batch file C:\Users\mkemp\AppData\Local\Temp\make23400-2.bat
Batch file contents:
@echo off
Volume in drive C is Windows Volume Serial Number is 045A-E422 Directory of C:\tools\UnixTools\usr\local\wbin (... the rest of the output)
CreateProcess(C:\Users\mkemp\AppData\Local\Temp\make23400-2.bat,C:\Users\mkemp\AppData\Local\Temp\make23400-2.bat,...)
Таким образом, похоже, что функция $(shell ...)
GNU Make каким-то образом интерпретирует вывод, произведенный вызовом dir
, как дополнительную команду, которую нужно выполнить, что, конечно, бессмысленно.