我购买了一台新的 Windows 10 PC 并使用(以管理员身份)安装了 WSL 2
wsl --install
这将安装 WSL 2 和 Ubuntu 20.04 LTS。然后,我从使用相同 Windows 10 pro 操作系统并使用 WSL2 和 Ubuntu 18.04.6 LTS 的旧 PC 复制了我的文件。
现在,在同一文件夹中使用完全相同的 Makefile 会出现错误
make[1]: execvp: /bin/bash: Argument list too long
›cd /mnt/g/public_html/
›cd my_notes/
›cd solving_ODE/
›cd current_version
›cd OUTPUT/
›make -I$HOME all
make: execvp: /bin/bash: Argument list too long
make: *** [common.mk:761: all] Error 127
在进行搜索时,这似乎与ARG_MAX
.在新电脑上
>getconf ARG_MAX
4611686018427387903
在旧电脑上
>getconf ARG_MAX
2097152
两台电脑运行相同的操作系统(Windows 10)并且都是 64 位。
ARG_MAX
我需要在新电脑上进行更正吗?上面的值在新电脑上看起来很奇怪。
仅供参考,在新电脑上,Ubuntu 说
>xargs --show-limits
Your environment variables take up 2463 bytes
POSIX upper limit on argument length (this system): 4611686018427383392
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 4611686018427380929
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647
Makefile 中现在失败的命令是
DIRS = $(wildcard */.)
它到达哪里文件夹列表在当前目录中。我也尝试过
DIRS = ${shell find . -type d -print}
同样的错误。
有8727
一些名称很长的文件夹。旧电脑中的文件夹数量完全相同,没有任何变化。 Ubuntu 20.04 中的 shell 似乎发现这个太大了。
make
新PC上的版本是GNU make 4.2.1,旧PC上的版本是GNU make 4.1。新 PC 上的 Bash 版本是 GNU bash 5.0.16,旧 PC 上的 Bash 版本是 4.4.20。
为什么同样的 Makefile 现在在 Windows 10 WSL2 下的 Ubuntu 20.04 上会失败?是否可以修改ARG_MAX
使用某些配置设置的值?或者有什么方法可以改变DIRS = $(wildcard */.)
其他东西来首先避免这个问题?
仅供参考,有一个非常相似的问题makefile 参数列表太长但仅适用于某些配置 与我完全相同的设置。但这里的问题是,为什么相同的 makefile 在 Ubuntu 18 的 WSL2 上工作,而不是在 Ubuntu 20 的较新 WSL2 上工作?全部运行在同一操作系统(Windows 10 Pro)上。
我现在将在 Windows 10 上安装 Virtual Box 并在那里安装最新的 Ubuntu,看看是否出现相同的错误。如果不是,那么微软一定是如何为其 WSL 构建 Linux Ubuntu 的?
更新
我找到了一个解决方法。我重写了 Makefile 以避免这种长参数处理。因此,现在它不再传递一长串目录名称来处理(我使用递归 make),而是在循环中一个接一个地执行一个目录名称。这使它发挥作用。
但奇怪的是,在较新的 WSL2 Ubuntu 上它会失败,但在较旧的 WSL2 Ubuntu 上却不会。我用这个 Makefile 已经很多年了,从来没有遇到过问题。
我现在一切都准备好了。但这可能是 Microsoft 如何为 Ubuntu 20.04 构建 Linux 内核的问题。我不知道。但ARG_MAX
除了从源代码重新编译 Linux 本身之外,似乎没有其他方法可以改变。
答案1
这make
经过修补,能够处理更长的参数。查看补丁文件make-dfsg_4.1-9.1ubuntu1.diff.gz在https://packages.ubuntu.com/en/source/bionic/make-dfsg:
+ if (unixy_shell && line_len > MAX_ARG_STRLEN)
+ {
+ unsigned j;
+ memcpy (ap, eval_line, sizeof (eval_line) - 1);
+ ap += sizeof (eval_line) - 1;
+ for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++)
+ ap += sprintf (ap, "\\$\\{%u\\}", j);
+ *ap++ = '\\';
+ *ap++ = '"';
+ *ap++ = ' ';
+ /* Copy only the first word of SHELL to $0. */
+ for (p = shell; *p != '\0'; ++p)
+ {
+ if (isspace ((unsigned char)*p))
+ break;
+ *ap++ = *p;
+ }
+ *ap++ = ' ';
+ }
在Ubuntu 20中,make
升级到v4.2.1,这个补丁已经没有了。您必须优化您的 Makefile 以避免长参数。