Skip to content

Commit 59379eb

Browse files
authored
Add support for passing a response file to file_packager (#24107)
Because calls to `file_packager` go through the shell wrapper, this can on Windows due to a "command line is too long" error (e.g. with a long list of `--preload-file`), even if a response file was provided to `emcc` in order avoid the issue. Fix it by supporting response files in `file_packager`, and changing `link` so that it uses a response file where needed.
1 parent 91c86f2 commit 59379eb

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

test/test_other.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3746,6 +3746,22 @@ def clean(txt):
37463746

37473747
self.assertTextDataIdentical(clean(proc.stdout), clean(proc2.stdout))
37483748

3749+
def test_file_packager_response_file(self):
3750+
filenames = [f'foo.{i:032}' for i in range(4096)]
3751+
3752+
create_file('src.c', 'int main() { return 0; }\n')
3753+
create_file('data.txt', '')
3754+
3755+
response_data = '\n'.join(f'--preload-file data.txt@{f}' for f in filenames)
3756+
self.assertGreater(len(response_data), (1 << 16))
3757+
create_file('data.rsp', response_data)
3758+
3759+
self.run_process([EMCC, 'src.c', '@data.rsp'])
3760+
data = read_file('a.out.js')
3761+
3762+
for f in filenames:
3763+
self.assertTrue(f'"/{f}"' in data)
3764+
37493765
def test_file_packager_separate_metadata(self):
37503766
# verify '--separate-metadata' option produces separate metadata file
37513767
ensure_dir('subdir')

tools/file_packager.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
sys.path.insert(0, __rootdir__)
8585

8686
from tools import shared, utils, js_manipulation
87+
from tools.response_file import substitute_response_files
8788

8889

8990
DEBUG = os.environ.get('EMCC_DEBUG')
@@ -368,12 +369,18 @@ def main(): # noqa: C901, PLR0912, PLR0915
368369
See the source for more details.''')
369370
return 1
370371

371-
data_target = sys.argv[1]
372+
# read response files very early on
373+
try:
374+
args = substitute_response_files(sys.argv[1:])
375+
except IOError as e:
376+
shared.exit_with_error(e)
377+
378+
data_target = args[0]
372379
data_files = []
373380
plugins = []
374381
leading = ''
375382

376-
for arg in sys.argv[2:]:
383+
for arg in args[1:]:
377384
if arg == '--preload':
378385
leading = 'preload'
379386
elif arg == '--embed':

tools/link.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,8 @@ def package_files(options, target):
30673067
file_args += ['--obj-output=' + object_file]
30683068
rtn.append(object_file)
30693069

3070-
cmd = [shared.FILE_PACKAGER, shared.replace_suffix(target, '.data')] + file_args
3070+
cmd = building.get_command_with_possible_response_file(
3071+
[shared.FILE_PACKAGER, shared.replace_suffix(target, '.data')] + file_args)
30713072
if options.preload_files:
30723073
# Preloading files uses --pre-js code that runs before the module is loaded.
30733074
file_code = shared.check_call(cmd, stdout=PIPE).stdout

0 commit comments

Comments
 (0)