我有一个相当大的项目(4272个.o文件),但我无法通过GNU Make进行链接。我遇到了“make:/bin/sh:参数列表太长”的错误。 这是一个使用qmake生成makefile的Qt 5项目。
我知道有很多关于此问题的问题,但我不知道如何将任何解决方案应用到我的问题上。我也不完全确定为什么在链接步骤中遇到此错误。我收到的错误消息是:“make:/bin/sh:参数列表太长”。
用于连接我的项目的makefile条目如下:
这段话有点长,但是接下来的内容有些奇怪:当我把扩展命令放在
另一个解决方法:如果我手动编辑我的makefile文件,使链接命令包含
我不认为我能让qmake做到这一点,所以除非我能找到另一个解决方案,否则我就被困在手动编辑我的makefile中了。
类似问题的答案似乎侧重于换行符及其在makefile中的处理方式。我的shell脚本只有两行(一个在“#!/bin/sh”之后,一个在实际命令之后)。此外,人们提出的一个解决方案(例如这个)使用for循环来逐个运行每个参数上的命令。我不确定我如何在这里应用它,因为(我认为)我需要所有这些目标文件在我的链接器命令中。
@echo如何导致超过最大参数长度?
我最初提出的问题并不真正相关: (注意:最初发布该问题时,链接命令开头缺少@echo。那似乎是“发生这种情况”的答案,因此我实际上不需要知道第二个问题的答案,在任何情况下,第一个评论已经回答了这个问题。)
我的系统的各种细节可能与此相关: - 我正在运行一个相当新的Arch Linux系统,内核版本为5.8.10 - ARG_MAX值为2097152,
我知道有很多关于此问题的问题,但我不知道如何将任何解决方案应用到我的问题上。我也不完全确定为什么在链接步骤中遇到此错误。我收到的错误消息是:“make:/bin/sh:参数列表太长”。
用于连接我的项目的makefile条目如下:
build/debug/my_target/my_target: $(OBJECTS)
@test -d build/debug/my_target/ || mkdir -p build/debug/my_target/
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
它会扩展成类似于这样的内容:
@echo linking /build/debug/my_target/my_target && clang++ -ccc-gcc-name g++ -lc++ -L/path/to/licensing/lib -Wl,-rpath,/path/to/qt/lib -Wl,-rpath-link,/path/to/qt/lib -o build/debug/my_target/my_target build/debug/my_target/obj/object1.o build/debug/my_target/obj/object2.o ... build/debug/my_target/obj/object4272.o ... [ a bunch of moc_X.o ] ... [ a bunch of libs ] -lGL -lpthread -no-pie
这段话有点长,但是接下来的内容有些奇怪:当我把扩展命令放在
@echo linking build/debug/my_target/my_target &&
后面,并将其放入一个shell脚本中运行时,它可以正常工作。该shell脚本包含202,420个字符(包括#!/bin/sh
行)。此外,如果我去掉命令中的@echo ... &&
部分,我就可以运行make
并进行链接。另一个解决方法:如果我手动编辑我的makefile文件,使链接命令包含
build/debug/my_target/*.o
而不是$(OBJECTS)
,它就可以正常工作:build/debug/my_target/my_target: $(OBJECTS)
@test -d build/debug/my_target/ || mkdir -p build/debug/my_target/
$(LINK) $(LFLAGS) -o $(TARGET) build/debug/my_target/*.o $(OBJCOMP) $(LIBS)
我不认为我能让qmake做到这一点,所以除非我能找到另一个解决方案,否则我就被困在手动编辑我的makefile中了。
类似问题的答案似乎侧重于换行符及其在makefile中的处理方式。我的shell脚本只有两行(一个在“#!/bin/sh”之后,一个在实际命令之后)。此外,人们提出的一个解决方案(例如这个)使用for循环来逐个运行每个参数上的命令。我不确定我如何在这里应用它,因为(我认为)我需要所有这些目标文件在我的链接器命令中。
@echo如何导致超过最大参数长度?
我最初提出的问题并不真正相关: (注意:最初发布该问题时,链接命令开头缺少@echo。那似乎是“发生这种情况”的答案,因此我实际上不需要知道第二个问题的答案,在任何情况下,第一个评论已经回答了这个问题。)
我的系统的各种细节可能与此相关: - 我正在运行一个相当新的Arch Linux系统,内核版本为5.8.10 - ARG_MAX值为2097152,
xargs --show-limits
的输出为:Your environment variables take up 2343 bytes
POSIX upper limit on argument length (this system): 2092761
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2090418
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647
ulimit -s
输出:8192(我尝试将其设置为更大的值,例如ulimit -s 65536
,但没有成功,这也许并不奇怪,因为 ARG_MAX 似乎比链接器命令大得多)。- GNU Make 版本是4.3。
- clang/clang++ 版本是10.0.1。
- Qt 版本是5.15.1(我相当确定这与问题无关,我们刚刚将项目从5.9.6切换过来,那时我也有同样的问题)。
$(LINK) ...
命令前加上echo
会发生什么呢?你会得到相同的错误吗?这至少能告诉你是shell还是编译器在抱怨。 - Beta@echo
。去掉这个就解决了,但我不明白为什么会这样。我会相应地编辑问题。 - rainbowgoblinARG_MAX
适用于命令行和环境变量的总和;由make
设置的变量可能会超过限制。可以通过文件传递GCC参数,例如echo arg1 arg2 ... >args; gcc @args
,这将绕过环境限制,但我不知道如何让qmake使用它来生成Makefile。你可以尝试在一个名字较短的目录中构建吗? - ephemientsh -c
,所以make命令的限制要比ARG_MAX小得多,因为Linux还对来自argv或envp的单个字符串的长度施加了更低的限制(<128k IIRC)。 - user10678532echo ...
,我同意那样做是毫无意义的。(尽管我可以理解我的话可能会被误解。)我忘记了MAX_ARG_STRLEN
,它是你所说的单个参数限制,为 131072。无论如何,问题在于要找出如何让 qmake 处理这个限制。 - ephemientPAGE_SIZE
(我理解它决定了MAX_ARG_STRLEN
)在两种情况下都是相同的,都是4096。 - rainbowgoblin