I have a reasonably large project (4272 .o files) and I can't get it to link with GNU Make. I run into make: /bin/sh: Argument list too long
. This is a Qt 5 project that uses qmake to generate the makefile.
I know there are lots of questions about this, but I don't know how to apply any of the solutions to my problem. I'm also not totally sure why I'm running into this at the linking step. The error I get is:
make: /bin/sh: Argument list too long
The makefile entry for linking my project looks like this:
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)
which expands to something like:
@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
This is pretty long. But here's where it gets weird: when I put the expanded command after the @echo linking build/debug/my_target/my_target &&
into a shell script, and it runs. The shell script is 202,420 characters (including the #!/bin/sh
line). Also, if I get rid of the @echo ... &&
part of the command I can run make
and linking works.
Another workaround: if I manually edit my makefile so that the linking command contains build/debug/my_target/*.o
instead of $(OBJECTS)
it works:
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)
I don't think I can get qmake to do this, though, so I'm stuck manually editing my makefile unless I can find another solution.
Answers to similar problems seem to focus on line breaks and how they're handled in makefiles. My shell script only has two lines (one after #!/bin/sh
and one after the actual command). Also, one solution that people have come up with (for example this one) uses a for loop to iteratively run a command on each argument. I'm not sure how I could apply this here, since (I think) I need all those object files in my linker command.
How does @echo
cause the max argument length to be exceeded?
Questions I originally asked that aren't really relevant:
(Note: as originally posted this question missed the @echo
at the beginning of the linking command. That seems to be the answer to "why is this happening" and as such I don't really need to know the answer to the second question, which is answered in the first comment in any case).
- Why is this happening? How is it that make is running into this error with a command that I can apparently run in a shell script?
- How can I get around this if there's no way to run my command as an iterative series of shorter commands?
Various details about my system that might be relevant:
- I'm running a fairly up-to-date Arch Linux system, kernel 5.8.10
- ARG_MAX value is 2097152, the output from
xargs --show-limits
is:
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
output: 8192 (I've tried setting this to much larger values, e.g.ulimit -s 65536
without success, which maybe isn't surprising since ARG_MAX appears to be much larger than the linker command).- GNU Make version is 4.3
- clang/clang++ version is 10.0.1
- Qt version is 5.15.1 (I'm fairly certain this isn't relevant, we've just switched our project over from 5.9.6 and I had the same problem then as well).
echo
in front of that$(LINK) ...
command? Do you get the same error? That might at least tell you whether it's the shell or the compiler complaining. – Beta@echo
. Getting rid of this solves it, but I don't understand why. I'll edit the question accordingly. – rainbowgoblinARG_MAX
applies to the sum of command-line and environment; variables set bymake
might be pushing you over the limit. It is possible to pass GCC arguments by file, e.g.echo arg1 arg2 ... >args; gcc @args
which would bypass environment limitations, but I have no idea how to get qmake to produce a Makefile using that. Can you just try to build in a directory with a shorter name? – ephemientsh -c
as a single argument, make's commands are much more limited than ARG_MAX, because Linux also imposes a much lower limit on the length of a single string from argv or envp (<128k IIRC). – user414777echo ...
from within Makefile, I agree that would be pointless. (Although I can see how what I wrote could be misconstrued.) I had forgotten aboutMAX_ARG_STRLEN
which is the single argument limit you talk about - it's 131072. Either way, the problem lies in figuring out how to get qmake to take care of that. – ephemient