Makefile 是什么导致GNU Make崩溃的

Makefile 是什么导致GNU Make崩溃的,makefile,Makefile,GNU如何决定是直接从规则运行一行,还是通过批处理文件运行一行?我在Windows Server 2008平台上使用GNU Make v3.80,所以我的shell是cmd.exe 打开debug-d并注意到,在我的例子中,规则中的某些行不是通过子shell批处理运行的,而是使用cmd.exe,但似乎是由make直接调用的 见下面的例子。请参见如何直接运行xcopy命令: CreateProcess(C:\Windows\system32\xcopy.exe,xcopy /?,...) 但是e

GNU如何决定是直接从规则运行一行,还是通过批处理文件运行一行?我在Windows Server 2008平台上使用GNU Make v3.80,所以我的shell是cmd.exe

打开debug-d并注意到,在我的例子中,规则中的某些行不是通过子shell批处理运行的,而是使用cmd.exe,但似乎是由make直接调用的

见下面的例子。请参见如何直接运行xcopy命令:

CreateProcess(C:\Windows\system32\xcopy.exe,xcopy /?,...)
但是echo命令是通过批处理文件运行的:

Creating temporary batch file C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat
示例生成文件:

stackoverflow :
    xcopy /?
    @echo Done
完整dDebug输出:

GNU Make 3.80 Tool Version v1.3  build for Linux on 20060503
Copyright (C) 2002  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.
find_and_set_shell path search set default_shell = C:/Windows/System32/cmd.exe
Reading makefiles...
Reading makefile `..\..\..\pi_scripts\make\make_shell.mak'...
Updating makefiles....
 Considering target file `..\..\..\pi_scripts\make\make_shell.mak'.
  Looking for an implicit rule for `..\..\..\pi_scripts\make\make_shell.mak'.
  No implicit rule found for `..\..\..\pi_scripts\make\make_shell.mak'.
  Finished prerequisites of target file `..\..\..\pi_scripts\make\make_shell.mak'.
 No need to remake target `..\..\..\pi_scripts\make\make_shell.mak'.
Updating goal targets....
Considering target file `stackoverflow'.
 File `stackoverflow' does not exist.
 Finished prerequisites of target file `stackoverflow'.
Must remake target `stackoverflow'.
xcopy /?
CreateProcess(C:\Windows\system32\xcopy.exe,xcopy /?,...)
Putting child 0x025dc670 (stackoverflow) PID 39739552 on the chain.
Live child 0x025dc670 (stackoverflow) PID 39739552 
Copies files and directory trees.

NOTE: Xcopy is now deprecated, please use Robocopy.

XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
                           [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
                           [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B]
                           [/EXCLUDE:file1[+file2][+file3]...]

  source       Specifies the file(s) to copy.
  destination  Specifies the location and/or name of new files.
<snip>
Reaping winning child 0x025dc670 PID 39739552 
Creating temporary batch file C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat
CreateProcess(C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat,C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat,...)
Live child 0x025dc670 (stackoverflow) PID 39739552 
Done
Reaping winning child 0x025dc670 PID 39739552 
Cleaning up temp batch file C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat
Removing child 0x025dc670 PID 39739552 from chain.
Successfully remade target file `stackoverflow'.

有趣的问题。虽然我没有机会验证我的答案,因为我没有设置环境来复制它,但我会在阅读源代码的基础上尝试一下。以下几行是从GNU make源文件复制的,仅供参考

首先,该代码指示何时直接执行命令以及何时通过shell执行命令

3470 /* Figure out the argument list necessary to run LINE as a command.  Try to
3471    avoid using a shell.  This routine handles only ' quoting, and " quoting
3472    when no backslash, $ or ' characters are seen in the quotes.  Starting
3473    quotes may be escaped with a backslash.  If any of the characters in
3474    sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[]
3475    is the first word of a line, the shell is used.
对于您的环境,这两个字符串数组似乎是:

2625   static char sh_chars_dos[] = "|&<>";
2626   static char *sh_cmds_dos[] = { "assoc", "break", "call", "cd", "chcp",
2627                                  "chdir", "cls", "color", "copy", "ctty",
2628                                  "date", "del", "dir", "echo", "echo.",
2629                                  "endlocal", "erase", "exit", "for", "ftype",
2630                                  "goto", "if", "if", "md", "mkdir", "move",
2631                                  "path", "pause", "prompt", "rd", "rem", "ren",
2632                                  "rename", "rmdir", "set", "setlocal",
2633                                  "shift", "time", "title", "type", "ver",
2634                                  "verify", "vol", ":", 0 };

这与make-run的输出一致。也许您可以尝试sh_cmds_dos列表中的一些命令,以检查这是否是一个正确的分析…

有趣的问题。虽然我没有机会验证我的答案,因为我没有设置环境来复制它,但我会在阅读源代码的基础上尝试一下。以下几行是从GNU make源文件复制的,仅供参考

首先,该代码指示何时直接执行命令以及何时通过shell执行命令

3470 /* Figure out the argument list necessary to run LINE as a command.  Try to
3471    avoid using a shell.  This routine handles only ' quoting, and " quoting
3472    when no backslash, $ or ' characters are seen in the quotes.  Starting
3473    quotes may be escaped with a backslash.  If any of the characters in
3474    sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[]
3475    is the first word of a line, the shell is used.
对于您的环境,这两个字符串数组似乎是:

2625   static char sh_chars_dos[] = "|&<>";
2626   static char *sh_cmds_dos[] = { "assoc", "break", "call", "cd", "chcp",
2627                                  "chdir", "cls", "color", "copy", "ctty",
2628                                  "date", "del", "dir", "echo", "echo.",
2629                                  "endlocal", "erase", "exit", "for", "ftype",
2630                                  "goto", "if", "if", "md", "mkdir", "move",
2631                                  "path", "pause", "prompt", "rd", "rem", "ren",
2632                                  "rename", "rmdir", "set", "setlocal",
2633                                  "shift", "time", "title", "type", "ver",
2634                                  "verify", "vol", ":", 0 };

这与make-run的输出一致。也许您可以尝试sh_cmds_dos列表中的一些命令,以检查这是否是正确的分析…

Windows没有单独的echo可执行文件,是吗?我的计算机上没有echo.exe,但这很重要吗?我只选择xcopy和echo作为例子,这样人们就会熟悉它们。我可以选择ar作为直接调用的示例,Perl.exe作为批处理文件。我的意思是,如果没有cmd,它就不能运行echo,因为没有这样的程序。但是无论如何,-makefile配方使用shell语法;如果完全确定可以避免在此处使用shell,则可以自由使用。Windows没有echo的单独可执行文件,是吗?我的计算机上没有echo.exe,但这很重要吗?我只选择xcopy和echo作为例子,这样人们就会熟悉它们。我可以选择ar作为直接调用的示例,Perl.exe作为批处理文件。我的意思是,如果没有cmd,它就不能运行echo,因为没有这样的程序。但是无论如何,-makefile配方使用shell语法;如果完全确定它可以避免在这里使用外壳,它可以自由地这样做。挖得好,+1。临时文件是纯粹的疯狂,虽然谢谢,cmd…非常好的答案,正是我所寻找的,所以谢谢你。自从发布我的问题以来,我注意到在程序路径(例如,c:\program files\perl\bin\perl.exe而不是c:\progra~1\perl\bin\perl.exe)周围加了引号,这总是会导致make批处理。另外,管道和重定向程序输出会导致make抛出,例如a | b或a>file.txt。所以我同意你的发现。我提出这个问题的原因是,只要将shell输出到cmd.exe,我就被它的8k字符限制所阻碍,所以了解如何避免输出shell是很重要的。@Chris很高兴它有帮助,开源万岁-@凯尔塔我也几乎不敢相信我的眼睛,这肯定是非常低效的。有趣的问题。。。。实际上,任何关于make和非unix平台之间可怕关系的问题都是自虐的。挖得好,+1。临时文件是纯粹的疯狂,虽然谢谢,cmd…非常好的答案,正是我所寻找的,所以谢谢你。自从发布我的问题以来,我注意到在程序路径(例如,c:\program files\perl\bin\perl.exe而不是c:\progra~1\perl\bin\perl.exe)周围加了引号,这总是会导致make批处理。另外,管道和重定向程序输出会导致make抛出,例如a | b或a>file.txt。所以我同意你的发现。我提出这个问题的原因是,只要将shell输出到cmd.exe,我就被它的8k字符限制所阻碍,所以了解如何避免输出shell是很重要的。@Chris很高兴它有帮助,开源万岁-@凯尔塔我也几乎不敢相信我的眼睛,这肯定是非常低效的。有趣的问题。。。。实际上,任何关于make和非unix平台之间可怕关系的问题都是自虐的。