简体   繁体   English

Windows上的GNU make 4.2(和4.2.1)截断配方中的行

[英]GNU make 4.2 (and 4.2.1) on windows truncates line in recipe

I want to move to make 4.2 so I can have the ability to do parallel jobs on Windows using --jobs=N . 我想移动到make 4.2以便可以使用--jobs=N在Windows上执行并行作业。

make 4.2 is not available in binary form from SourceForge, only 3.81 make 4.2无法从SourceForge以二进制形式获得,只有3.81

So I had to build it from source - they included a VS studio project - and I was up and running. 因此,我必须从源代码构建它-其中包括VS Studio项目 -并且我已经启动并运行了。

Problem is, it appears to have a bug though it could be a bug with my makefile. 问题是,它似乎有一个错误,尽管可能与我的makefile有关。

I ran make4.2 all --print-data-base --debug=vjm on my project and I got ERRORS. 我在项目上运行了make4.2 all --print-data-base --debug=vjm ,但出现错误。 What's unfortunate is that the error is NOT related to syntax of rules as this project builds without error on make 3.81 using the same options. 不幸的是,该错误与规则的语法无关,因为此项目使用相同的选项在make 3.81上构建时没有错误。

Here is the command it fails on. 这是失败的命令。

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"
  1. Creates a directory 创建目录
  2. Copies bunch of files from one directory to that new directory 将一堆文件从一个目录复制到该新目录

Used the same make call for both versions of make: make all --print-data-base --debug=vjm 对两个版本的make使用相同的make调用: make all --print-data-base --debug=vjm

However, I get the following error when using make4.2 : 但是,使用make4.2时出现以下错误:

Copying application data...
cp: target `C' is not a directory
makev42[3]: *** [Makefile:383: deploy_marketProperties] 

The command it tried running was: 它尝试运行的命令是:

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"

There's actually 264 .json files but I only show one for readability. 实际上有264个.json文件,但出于可读性考虑,我只显示一个。

Again, this runs fine on make v3.81 using exact same command-line options. 同样,使用完全相同的命令行选项在make v3.81上运行良好。

It appears make 4.2 has a problem parsing that huge list of files maybe?? 似乎make 4.2在解析庞大文件列表时可能会遇到问题??

The question 问题

Is there something I can change with my makefiles to make it run on make v4.2 ? 我可以通过makefile进行一些更改以使其在make v4.2上运行吗?

We are highly motivated to make it work with a 4.0+ version of make . 我们非常热衷于使其与4.0+更高版本的make Otherwise we have to use a build tool that will cost $$. 否则,我们必须使用将花费$$的构建工具。

UPDATE 1 更新1

Per the suggestion of @MadScientist, I have executed both versions of make and present the outputs. 根据@MadScientist的建议,我执行了两个版本的make并显示输出。

C:\\release>make381 deploy_marketProperties --debug=vjm > 381.err 2>&1 C:\\ release> make381 deploy_marketProperties --debug = vjm> 381.err 2>&1

C:\\release>make42 deploy_marketProperties --debug=vjm > 42.err 2>&1 C:\\ release> make42 deploy_marketProperties --debug = vjm> 42.err 2>&1

The target deploy_marketProperties has the following rule: 目标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"

The output of make v 3.81 . make v 3.81的输出。 NOTE: there's actually 264 .json files and total number of characters that make up the list of .json files, including ONE white space per file, is 18251 (in case that's relevant): 注:实际上有264 .json文件和字符组成的名单的总数.json文件,包括每个文件一个空白,为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'.

The output of make v 4.2 . make v 4.2的输出。 NOTE: there's actually 264 .json files and total number of characters that make up the list of .json files, including ONE white space per file, is 18251 (in case that's relevant): 注:实际上有264 .json文件和字符组成的名单的总数.json文件,包括每个文件一个空白,为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

Note that both make versions use the same shell: 注意,两个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.

NOTE THE msys @MadScientist; 注意msys @MadScientist; is that relevant? 有关系吗?

UPDATE 2 更新2

I re-ran make 4.2 but I deleted all but ONE .json file in the directory and - surprise! 我重新运行了make 4.2但删除了目录中除一个.json文件外的所有文件,而且-令人惊讶! - it works. - 有用。

This is the ENTIRE output from make42 deploy_marketProperties --debug=vjm : 这是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'.

UPDATE 3 更新3

I tried it with make 4.2.1 and I got the exact same behavior as on make 4.2 : fails when there are hundreds of .json files but succeeds if there less than some magic number of characters. 我用make 4.2.1尝试,并且得到了与make 4.2完全相同的行为:当有数百个.json文件时失败,但如果字符数少于某些魔术数,则成功。

I got this message during one of my trials: 在一次试用中,我收到了此消息:

cp: target `C:/Users/User1/Des' is not a directory

Obviously it's getting cut-off but why? 显然它已经被切断了,但是为什么呢? Same shell being used and only thing different is version of make . 使用相同的外壳,唯一不同的是make版本。

You should use 4.2.1, it has some important fixes (I doubt it will make a difference for this problem). 您应该使用4.2.1,它有一些重要的修复程序(我怀疑它将对这个问题有所帮助)。

As discussed in the comments, using POSIX tools on Windows requires a specialized environment. 如评论中所述,在Windows上使用POSIX工具需要特殊的环境。 The normal "shell" on Windows is command.com, which doesn't accept POSIX sh syntax, such as && . Windows上的常规“ shell”是command.com,它不接受POSIX sh语法,例如&& The normal mkdir command on Windows doesn't accept the -p flag; Windows上的普通mkdir命令不接受-p标志; that's a POSIX flag. 那是POSIX标志。 There is no cp command on Windows. Windows上没有cp命令。

So it's clear that your makefile is expecting to be run with some sort of POSIX environment. 因此很明显,您的makefile有望在某种POSIX环境中运行。

Based on what you've described above, it's not clear how the problem is related to GNU make directly. 根据上面的描述,尚不清楚该问题与GNU make直接相关。 GNU make is parsing the makefile and it's invoking the shell and passing along the command line properly: this can be inferred because the shell is running the echo command and running the mkdir command, and even running the cp command. GNU make正在解析makefile,它正在调用shell并正确地沿命令行传递:可以推断出这一点,因为shell运行的是echo命令,mkdir命令,甚至是cp命令。

It's the cp command which is printing the message, not make. 是cp命令在打印消息,而不是make。 I believe you that it works with 3.81, but I suspect a non-obvious difference between the way 3.81 was compiled and the way you're building 4.2. 我相信您可以在3.81上使用它,但是我怀疑3.81的编译方式与您构建4.2的方式之间没有明显的区别。 It's even possible that there have been custom patches applied to the 3.81 version you're using, although I don't know. 尽管我不知道,甚至有可能已将自定义补丁应用于您正在使用的3.81版本。

To debug further I recommend the following: 要进一步调试,我建议以下内容:

  • First remove the @ prefix from the recipe line: that's always the number one thing to do; 首先从配方行中删除@前缀:这始终是第一件事。 if you can't see how make is invoking the command how can you debug? 如果看不到make如何调用命令,如何调试?
  • Then run the same makefile with the two different versions of make, from the same shell/prompt (so the path to make is the only difference). 然后在相同的shell /提示符下使用两个不同版本的make运行相同的makefile(因此,make的路径是唯一的区别)。 Is there any difference in the printed output? 打印输出有什么区别吗? If so what is it? 如果是这样,那是什么?
  • If not, then clearly there's something more mysterious going on. 如果没有的话,那么显然还有一些更神秘的事情正在发生。 Try to see if maybe the QNX version of make is modifying the environment somehow: you can run the env command in your recipe to see it. 尝试查看make的QNX版本是否正在以某种方式修改环境:您可以在配方中运行env命令来查看它。

Maybe it's related to the length of the command line? 也许与命令行的长度有关? Try temporarily moving some of the json files out of that directory so the command line is shorter. 尝试将一些json文件暂时移出该目录,以缩短命令行。

I asked the make-w32@gnu.org mailing list and I have the answer. 我问了make-w32@gnu.org邮件列表,我得到了答案。

To fix it, I had to uncomment the macro BATCH_MODE_ONLY_SHELL in config.h of the make source code. 要解决此问题,我必须在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

Taking quote from reply from mailing list: 从邮件列表的回复中获取报价:

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. 该标志的含义(据我了解:我对Windows支持的这一方面并不熟悉)是,make绝不会尝试直接通过要在命令行上运行的配方来调用Shell。

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. 显然,您的Shell能够从文件读取并执行很长的命令行,即使这些命令行参数未超出Windows的限制,当作为参数传入时,它也无法成功处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM