windows 上的 GNU make 4.2(和 4.2.1)截断了配方中的行
GNU make 4.2 (and 4.2.1) on windows truncates line in recipe
我想搬到 make 4.2
,这样我就可以使用 --jobs=N
.
在 Windows 上执行并行作业
make 4.2
无法以二进制形式从 SourceForge, only 3.81
获得
所以我不得不从源代码构建它 - 他们包括一个 VS studio project - 我起床 运行ning.
问题是,它似乎有一个错误,尽管它可能是我的 makefile 的一个错误。
我 运行 make4.2 all --print-data-base --debug=vjm
在我的项目上出现了错误。
不幸的是,该错误与规则语法无关,因为该项目使用相同的选项在 make 3.81
上构建时没有错误。
这是它失败的命令。
COPY_DIR = cp -f -R
MKDIR = mkdir -p
deploy_marketProperties: deploy_themeMappingConfig
@echo Copying application data... && $(MKDIR) "C:/Users/User1/Desktop/TargetDir" && $(COPY_DIR) $(wildcard C:/Users/User1/Desktop/Source/*) "C:/Users/User1/Desktop/TargetDir"
- 创建目录
- 将一堆文件从一个目录复制到那个新目录
对两个版本的 make 使用相同的 make
调用:
make all --print-data-base --debug=vjm
但是,我在使用 make4.2
时遇到以下错误:
Copying application data...
cp: target `C' is not a directory
makev42[3]: *** [Makefile:383: deploy_marketProperties]
它尝试的命令 运行ning 是:
echo Copying application data... && mkdir -p "C:/Users/User1/Desktop/TargetDir" && cp -f -R C:/Users/User1/Desktop/Source/im.json "C:/Users/User1/Desktop/TargetDir"
实际上有 264 个 .json
个文件,但为了便于阅读,我只显示了一个。
同样,使用完全相同的命令行选项,运行在 make v3.81
上没问题。
似乎 make 4.2
在解析那么大的文件列表时遇到了问题??
问题
有什么我可以用我的 makefile 更改的,以在 make v4.2
上实现 运行?
我们非常有动力让它与 make
的 4.0+
版本一起使用。否则我们必须使用成本为 $$ 的构建工具。
更新 1
根据@MadScientist 的建议,我已经执行了两个版本的 make
并展示了输出。
C:\release>make381 deploy_marketProperties --debug=vjm > 381.err 2>&1
C:\release>make42 deploy_marketProperties
--debug=vjm > 42.err 2>&1
目标 deploy_marketProperties
具有以下规则:
deploy_marketProperties:
echo Copying application data... && $(MKDIR) "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && $(COPY_DIR) $(wildcard C:/Users/User1/Desktop/A/Project/src/dir1/marketProperties/*) "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
make v 3.81
的输出。
注意:实际上有 264 个 .json
个文件,构成 .json
个文件列表的字符总数,包括每个文件一个白色 space,是 18251
(以防万一相关):
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 Windows32
find_and_set_shell path search set default_shell = C:/QNX650/host/win32/x86/usr/bin/sh.exe
Reading makefiles...
Reading makefile `Makefile'...
Updating goal targets....
Considering target file `deploy_marketProperties'.
File `deploy_marketProperties' does not exist.
Finished prerequisites of target file `deploy_marketProperties'.
Must remake target `deploy_marketProperties'.
echo Copying application data... && mkdir -p "C:/Users/User/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && cp -f -R C:/Users/User/Desktop/A/Project/src/fordhmi/marketProperties/2blank.json C:/Users/User/Desktop/A/Project/src/fordhmi/marketProperties/3blank.json "C:/Users/User/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
Main thread handle = 0x000000ac
Copying application data...
Successfully remade target file `deploy_marketProperties'.
make v 4.2
的输出。
注意:实际上有 264 个 .json
个文件,构成 .json
个文件列表的字符总数,包括每个文件一个白色 space,是 18251
(以防万一相关):
GNU Make 4.2
Built for Windows32
Copyright (C) 1988-2016 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.
find_and_set_shell() path search set default_shell = C:/QNX650/host/win32/x86/usr/bin/sh.exe
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Updating goal targets....
Considering target file 'deploy_marketProperties'.
File 'deploy_marketProperties' does not exist.
Finished prerequisites of target file 'deploy_marketProperties'.
Must remake target 'deploy_marketProperties'.
echo Copying application data... && mkdir -p "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && cp -f -R C:/Users/User1/Desktop/A/Project/src/SubProj/marketProperties/im.json C:/Users/User1/Desktop/A/Project/src/SubProj/marketProperties/da.json "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
Main thread handle = 00000088
Copying application data...
cp: target `C' is not a directory
make_msvc.net2003: *** [Makefile:384: deploy_marketProperties] Error 1
请注意,两个 make
版本使用相同的 shell:
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>where sh
C:\QNX650\host\win32\x86\usr\bin\sh.exe
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>sh --help
GNU bash, version 3.1.17(1)-release-(i686-pc-msys)
Usage: sh [GNU long option] [option] ...
sh [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--restricted
--verbose
--version
--wordexp
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
Type `sh -c "help set"' for more information about shell options.
Type `sh -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.
注意msys
@MadScientist;这相关吗?
更新 2
我重新 运行 make 4.2
但我删除了目录中除了一个 .json
文件以外的所有文件,而且 - 惊喜! - 有效。
这是 make42 deploy_marketProperties --debug=vjm
的完整输出:
GNU Make 4.2
Built for Windows32
Copyright (C) 1988-2016 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.
find_and_set_shell() path search set default_shell = C:/QNX650/host/win32/x86/usr/bin/sh.exe
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Updating goal targets....
Considering target file 'deploy_marketProperties'.
File 'deploy_marketProperties' does not exist.
Finished prerequisites of target file 'deploy_marketProperties'.
Must remake target 'deploy_marketProperties'.
echo Copying application data... && mkdir -p "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && cp -f -R C:/Users/User1/Desktop/A/Project/src/subProject/marketProperties/2blank.json "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
Main thread handle = 000000B4
Copying application data...
Successfully remade target file 'deploy_marketProperties'.
更新 3
我用 make 4.2.1
试过了,我得到了与 make 4.2
完全相同的行为:当有数百个 .json
文件时失败,但如果少于某个幻数则成功字符数。
我在一次试用中收到了这条消息:
cp: target `C:/Users/User1/Des' is not a directory
显然它正在被切断,但为什么呢?
使用的 shell 相同,唯一不同的是 make
.
的版本
你应该使用 4.2.1,它有一些重要的修复(我怀疑它会对这个问题产生影响)。
如评论中所述,在 Windows 上使用 POSIX 工具需要专门的环境。 Windows 上的正常 "shell" 是 command.com,它不接受 POSIX sh 语法,例如 &&
。 Windows 上的普通 mkdir
命令不接受 -p
标志;那是一个 POSIX 标志。 Windows 上没有 cp
命令。
很明显,您的 makefile 需要 运行 某种 POSIX 环境。
根据您上面的描述,目前尚不清楚该问题与 GNU make 有何直接关系。 GNU make 正在解析 makefile 并调用 shell 并正确地沿命令行传递:这可以推断出来,因为 shell 是 运行 回显命令和 运行使用 mkdir 命令,甚至 运行使用 cp 命令。
打印消息的是 cp 命令,而不是 make。我相信你它适用于 3.81,但我怀疑 3.81 的编译方式与你构建 4.2 的方式之间存在不明显的差异。甚至有可能你正在使用的 3.81 版本应用了自定义补丁,虽然我不知道。
为了进一步调试,我推荐以下内容:
- 首先从食谱行中删除
@
前缀:这始终是第一要务;如果您看不到 make 如何调用命令,您如何调试?
- 然后 运行 相同的 makefile 与两个不同版本的 make,来自相同的 shell/prompt(所以 make 的路径是唯一的区别)。打印输出有什么不同吗?如果有,那是什么?
- 如果不是,那么显然有更神秘的事情正在发生。尝试查看 QNX 版本的 make 是否以某种方式修改了环境:您可以 运行 配方中的
env
命令来查看它。
可能跟命令行的长度有关?尝试暂时将一些 json 文件移出该目录,以便命令行更短。
我问了 make-w32@gnu.org
邮件列表,我得到了答案。
要修复它,我必须取消注释 make
源代码的 config.h
中的宏 BATCH_MODE_ONLY_SHELL
。
/*
* If you have a shell that does not grok 'sh -c quoted-command-line'
* correctly, you need this setting. Please see below for specific
* shell support.
*/
#define BATCH_MODE_ONLY_SHELL 1
引用邮件列表的回复:
What that flag means (as I understand it: I'm not that familiar with
this aspect of Windows support) is that make will never try to invoke
the shell directly passing the recipe to be run on the command line.
Instead it is being forced to always write the recipe to a temporary
file ("batch file") on your disk and invoke the shell such that it
runs the recipe in the temporary file.
Apparently your shell is able to read and execute very long command
lines from a file, which it cannot successfully process when passed in
as arguments, even though these command line arguments are not
exceeding Windows limits.
我想搬到 make 4.2
,这样我就可以使用 --jobs=N
.
make 4.2
无法以二进制形式从 SourceForge, only 3.81
所以我不得不从源代码构建它 - 他们包括一个 VS studio project - 我起床 运行ning.
问题是,它似乎有一个错误,尽管它可能是我的 makefile 的一个错误。
我 运行 make4.2 all --print-data-base --debug=vjm
在我的项目上出现了错误。
不幸的是,该错误与规则语法无关,因为该项目使用相同的选项在 make 3.81
上构建时没有错误。
这是它失败的命令。
COPY_DIR = cp -f -R
MKDIR = mkdir -p
deploy_marketProperties: deploy_themeMappingConfig
@echo Copying application data... && $(MKDIR) "C:/Users/User1/Desktop/TargetDir" && $(COPY_DIR) $(wildcard C:/Users/User1/Desktop/Source/*) "C:/Users/User1/Desktop/TargetDir"
- 创建目录
- 将一堆文件从一个目录复制到那个新目录
对两个版本的 make 使用相同的 make
调用:
make all --print-data-base --debug=vjm
但是,我在使用 make4.2
时遇到以下错误:
Copying application data...
cp: target `C' is not a directory
makev42[3]: *** [Makefile:383: deploy_marketProperties]
它尝试的命令 运行ning 是:
echo Copying application data... && mkdir -p "C:/Users/User1/Desktop/TargetDir" && cp -f -R C:/Users/User1/Desktop/Source/im.json "C:/Users/User1/Desktop/TargetDir"
实际上有 264 个 .json
个文件,但为了便于阅读,我只显示了一个。
同样,使用完全相同的命令行选项,运行在 make v3.81
上没问题。
似乎 make 4.2
在解析那么大的文件列表时遇到了问题??
问题
有什么我可以用我的 makefile 更改的,以在 make v4.2
上实现 运行?
我们非常有动力让它与 make
的 4.0+
版本一起使用。否则我们必须使用成本为 $$ 的构建工具。
更新 1
根据@MadScientist 的建议,我已经执行了两个版本的 make
并展示了输出。
C:\release>make381 deploy_marketProperties --debug=vjm > 381.err 2>&1
C:\release>make42 deploy_marketProperties --debug=vjm > 42.err 2>&1
目标 deploy_marketProperties
具有以下规则:
deploy_marketProperties:
echo Copying application data... && $(MKDIR) "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && $(COPY_DIR) $(wildcard C:/Users/User1/Desktop/A/Project/src/dir1/marketProperties/*) "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
make v 3.81
的输出。
注意:实际上有 264 个 .json
个文件,构成 .json
个文件列表的字符总数,包括每个文件一个白色 space,是 18251
(以防万一相关):
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 Windows32
find_and_set_shell path search set default_shell = C:/QNX650/host/win32/x86/usr/bin/sh.exe
Reading makefiles...
Reading makefile `Makefile'...
Updating goal targets....
Considering target file `deploy_marketProperties'.
File `deploy_marketProperties' does not exist.
Finished prerequisites of target file `deploy_marketProperties'.
Must remake target `deploy_marketProperties'.
echo Copying application data... && mkdir -p "C:/Users/User/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && cp -f -R C:/Users/User/Desktop/A/Project/src/fordhmi/marketProperties/2blank.json C:/Users/User/Desktop/A/Project/src/fordhmi/marketProperties/3blank.json "C:/Users/User/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
Main thread handle = 0x000000ac
Copying application data...
Successfully remade target file `deploy_marketProperties'.
make v 4.2
的输出。
注意:实际上有 264 个 .json
个文件,构成 .json
个文件列表的字符总数,包括每个文件一个白色 space,是 18251
(以防万一相关):
GNU Make 4.2
Built for Windows32
Copyright (C) 1988-2016 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.
find_and_set_shell() path search set default_shell = C:/QNX650/host/win32/x86/usr/bin/sh.exe
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Updating goal targets....
Considering target file 'deploy_marketProperties'.
File 'deploy_marketProperties' does not exist.
Finished prerequisites of target file 'deploy_marketProperties'.
Must remake target 'deploy_marketProperties'.
echo Copying application data... && mkdir -p "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && cp -f -R C:/Users/User1/Desktop/A/Project/src/SubProj/marketProperties/im.json C:/Users/User1/Desktop/A/Project/src/SubProj/marketProperties/da.json "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
Main thread handle = 00000088
Copying application data...
cp: target `C' is not a directory
make_msvc.net2003: *** [Makefile:384: deploy_marketProperties] Error 1
请注意,两个 make
版本使用相同的 shell:
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>where sh
C:\QNX650\host\win32\x86\usr\bin\sh.exe
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>sh --help
GNU bash, version 3.1.17(1)-release-(i686-pc-msys)
Usage: sh [GNU long option] [option] ...
sh [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--restricted
--verbose
--version
--wordexp
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
Type `sh -c "help set"' for more information about shell options.
Type `sh -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.
注意msys
@MadScientist;这相关吗?
更新 2
我重新 运行 make 4.2
但我删除了目录中除了一个 .json
文件以外的所有文件,而且 - 惊喜! - 有效。
这是 make42 deploy_marketProperties --debug=vjm
的完整输出:
GNU Make 4.2
Built for Windows32
Copyright (C) 1988-2016 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.
find_and_set_shell() path search set default_shell = C:/QNX650/host/win32/x86/usr/bin/sh.exe
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Updating goal targets....
Considering target file 'deploy_marketProperties'.
File 'deploy_marketProperties' does not exist.
Finished prerequisites of target file 'deploy_marketProperties'.
Must remake target 'deploy_marketProperties'.
echo Copying application data... && mkdir -p "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties" && cp -f -R C:/Users/User1/Desktop/A/Project/src/subProject/marketProperties/2blank.json "C:/Users/User1/Desktop/A/Project/src/../lib/armle-v7/release/marketProperties"
Main thread handle = 000000B4
Copying application data...
Successfully remade target file 'deploy_marketProperties'.
更新 3
我用 make 4.2.1
试过了,我得到了与 make 4.2
完全相同的行为:当有数百个 .json
文件时失败,但如果少于某个幻数则成功字符数。
我在一次试用中收到了这条消息:
cp: target `C:/Users/User1/Des' is not a directory
显然它正在被切断,但为什么呢?
使用的 shell 相同,唯一不同的是 make
.
你应该使用 4.2.1,它有一些重要的修复(我怀疑它会对这个问题产生影响)。
如评论中所述,在 Windows 上使用 POSIX 工具需要专门的环境。 Windows 上的正常 "shell" 是 command.com,它不接受 POSIX sh 语法,例如 &&
。 Windows 上的普通 mkdir
命令不接受 -p
标志;那是一个 POSIX 标志。 Windows 上没有 cp
命令。
很明显,您的 makefile 需要 运行 某种 POSIX 环境。
根据您上面的描述,目前尚不清楚该问题与 GNU make 有何直接关系。 GNU make 正在解析 makefile 并调用 shell 并正确地沿命令行传递:这可以推断出来,因为 shell 是 运行 回显命令和 运行使用 mkdir 命令,甚至 运行使用 cp 命令。
打印消息的是 cp 命令,而不是 make。我相信你它适用于 3.81,但我怀疑 3.81 的编译方式与你构建 4.2 的方式之间存在不明显的差异。甚至有可能你正在使用的 3.81 版本应用了自定义补丁,虽然我不知道。
为了进一步调试,我推荐以下内容:
- 首先从食谱行中删除
@
前缀:这始终是第一要务;如果您看不到 make 如何调用命令,您如何调试? - 然后 运行 相同的 makefile 与两个不同版本的 make,来自相同的 shell/prompt(所以 make 的路径是唯一的区别)。打印输出有什么不同吗?如果有,那是什么?
- 如果不是,那么显然有更神秘的事情正在发生。尝试查看 QNX 版本的 make 是否以某种方式修改了环境:您可以 运行 配方中的
env
命令来查看它。
可能跟命令行的长度有关?尝试暂时将一些 json 文件移出该目录,以便命令行更短。
我问了 make-w32@gnu.org
邮件列表,我得到了答案。
要修复它,我必须取消注释 make
源代码的 config.h
中的宏 BATCH_MODE_ONLY_SHELL
。
/*
* If you have a shell that does not grok 'sh -c quoted-command-line'
* correctly, you need this setting. Please see below for specific
* shell support.
*/
#define BATCH_MODE_ONLY_SHELL 1
引用邮件列表的回复:
What that flag means (as I understand it: I'm not that familiar with this aspect of Windows support) is that make will never try to invoke the shell directly passing the recipe to be run on the command line.
Instead it is being forced to always write the recipe to a temporary file ("batch file") on your disk and invoke the shell such that it runs the recipe in the temporary file.
Apparently your shell is able to read and execute very long command lines from a file, which it cannot successfully process when passed in as arguments, even though these command line arguments are not exceeding Windows limits.