Skip to content

Commit ed19179

Browse files
authored
Merge pull request #2033 from aaronfranke/arcom-command-length
Use a temp file for ARCOM to fix command line too long errors
2 parents 272e7f4 + 01da61e commit ed19179

5 files changed

Lines changed: 52 additions & 13 deletions

File tree

‎tools/android.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33

4+
import ar_tempfile
45
import common_compiler_flags
56
import my_spawn
67

@@ -112,6 +113,9 @@ def generate(env):
112113
env["RANLIB"] = toolchain + "/bin/llvm-ranlib"
113114
env["SHLIBSUFFIX"] = ".so"
114115

116+
# Configure ARCOM response file in case the command line call to AR is too long.
117+
ar_tempfile.configure(env)
118+
115119
env.Append(
116120
CCFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"], "-fPIC"]
117121
)

‎tools/ar_tempfile.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import os
2+
import re
3+
4+
# Backslashes that aren't escaping a quote or another backslash.
5+
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
6+
7+
8+
def tempfile_arg_esc_func(arg):
9+
from SCons.Subst import quote_spaces
10+
11+
arg = quote_spaces(arg)
12+
# GCC requires double Windows slashes, let's use UNIX separator
13+
return WINPATHSEP_RE.sub(r"/\1", arg)
14+
15+
16+
# The generated bindings can produce enough object files to exceed the command
17+
# line length limit when creating the static library. This works around that by
18+
# writing the command to a response file. Refer to the engine equivalent in
19+
# https://github.com/godotengine/godot/blob/master/platform/windows/detect.py
20+
def configure(env):
21+
if "ARCOM_ORIG" in env:
22+
return # Already configured, don't wrap ARCOM in TEMPFILE twice.
23+
24+
env["ARCOM_ORIG"] = env["ARCOM"]
25+
# This is SCons lazy evaluation syntax, only switching to a file when the command is actually too long.
26+
env["ARCOM"] = "${TEMPFILE('$ARCOM_ORIG', '$ARCOMSTR')}"
27+
env["TEMPFILESUFFIX"] = ".rsp"
28+
if os.name == "nt":
29+
env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func

‎tools/linux.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ar_tempfile
12
import common_compiler_flags
23
from SCons.Tool import clang, clangxx
34
from SCons.Variables import BoolVariable
@@ -52,4 +53,7 @@ def generate(env):
5253
if env["lto"] == "auto":
5354
env["lto"] = "full"
5455

56+
# Configure ARCOM response file in case the command line call to AR is too long.
57+
ar_tempfile.configure(env)
58+
5559
common_compiler_flags.generate(env)

‎tools/my_spawn.py‎

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,15 @@ def mySubProcess(cmdline, env):
3333
return rv
3434

3535
def mySpawn(sh, escape, cmd, args, env):
36+
# Used by TEMPFILE, which spawns a "del" command to clean up the response file.
37+
# See the equivalent code in the engine in `methods.py`.
38+
if cmd == "del":
39+
os.remove(args[1])
40+
return 0
41+
3642
newargs = " ".join(args[1:])
3743
cmdline = cmd + " " + newargs
3844

39-
rv = 0
40-
if len(cmdline) > 32000 and cmd.endswith("ar"):
41-
cmdline = cmd + " " + args[1] + " " + args[2] + " "
42-
for i in range(3, len(args)):
43-
rv = mySubProcess(cmdline + args[i], env)
44-
if rv:
45-
break
46-
else:
47-
rv = mySubProcess(cmdline, env)
48-
49-
return rv
45+
return mySubProcess(cmdline, env)
5046

5147
env["SPAWN"] = mySpawn
52-
env.Replace(ARFLAGS=["q"])

‎tools/windows.py‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33

4+
import ar_tempfile
45
import common_compiler_flags
56
import my_spawn
67
from SCons.Tool import mingw, msvc
@@ -150,9 +151,12 @@ def generate(env):
150151
]
151152
)
152153

153-
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
154+
# Long line hack. Use custom spawn to work around the command line length limit.
154155
my_spawn.configure(env)
155156

157+
# Configure ARCOM response file in case the command line call to AR is too long.
158+
ar_tempfile.configure(env)
159+
156160
else:
157161
env["use_mingw"] = True
158162
# Cross-compilation using MinGW
@@ -201,6 +205,9 @@ def generate(env):
201205
if sys.platform == "win32" or sys.platform == "msys":
202206
my_spawn.configure(env)
203207

208+
# Configure ARCOM response file in case the command line call to AR is too long.
209+
ar_tempfile.configure(env)
210+
204211
env.Append(CPPDEFINES=["WINDOWS_ENABLED"])
205212

206213
# Refer to https://github.com/godotengine/godot/blob/master/platform/windows/detect.py

0 commit comments

Comments
 (0)