Skip to content

Commit b202e21

Browse files
committed
Don't depend on llvm-nm to detect archive indexes
There is an llvm but that mean that certain binary files get mistaken for COFF object which means llvm-nm will error out: https://bugs.llvm.org/show_bug.cgi?id=44683 Instead write out own trivial ar parser to detect the presence of that index. Fixes: #10195
1 parent 8689a54 commit b202e21

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

emcc.py

+26-11
Original file line numberDiff line numberDiff line change
@@ -471,21 +471,36 @@ def do_emscripten(infile, memfile):
471471
return outfile
472472

473473

474+
def is_ar_file_with_missing_index(archive_file):
475+
# We parse the archive header outselves because llvm-nm --print-armap is slower and less
476+
# reliable.
477+
# See: https://github.com/emscripten-core/emscripten/issues/10195
478+
archive_header = b'!<arch>\n'
479+
file_header_size = 60
480+
481+
with open(archive_file) as f:
482+
header = f.read(len(archive_header))
483+
if header != archive_header:
484+
# This is not even an ar file
485+
return False
486+
file_header = f.read(file_header_size)
487+
if len(file_header) != file_header_size:
488+
# We don't have any file entires at all so we don't consider the index missing
489+
return False
490+
491+
name = file_header[:16].strip()
492+
# If '/' is the name of the first file we have an index
493+
return name != '/'
494+
495+
474496
def ensure_archive_index(archive_file):
475497
# Fastcomp linking works without archive indexes.
476498
if not shared.Settings.WASM_BACKEND or not shared.Settings.AUTO_ARCHIVE_INDEXES:
477499
return
478-
# Ignore stderr since llvm-nm prints "no symbols" to stderr for each object that has no symbols
479-
stdout = run_process([shared.LLVM_NM, '--print-armap', archive_file], stdout=PIPE, stderr=PIPE).stdout
480-
stdout = stdout.strip()
481-
# Ignore empty archives
482-
if not stdout:
483-
return
484-
if stdout.startswith('Archive map\n') or stdout.startswith('Archive index\n'):
485-
return
486-
shared.warning('%s: archive is missing an index; Use emar when creating libraries to ensure an index is created', archive_file)
487-
shared.warning('%s: adding index', archive_file)
488-
run_process([shared.LLVM_RANLIB, archive_file])
500+
if is_ar_file_with_missing_index(archive_file):
501+
shared.warning('%s: archive is missing an index; Use emar when creating libraries to ensure an index is created', archive_file)
502+
shared.warning('%s: adding index', archive_file)
503+
run_process([shared.LLVM_RANLIB, archive_file])
489504

490505

491506
#

tests/test_other.py

+9
Original file line numberDiff line numberDiff line change
@@ -8727,6 +8727,15 @@ def test_archive_no_index(self):
87278727
self.assertContained('libfoo.a: archive has no index; run ranlib to add one', stderr)
87288728
# The default behavior is to add archive indexes automatically.
87298729
run_process([PYTHON, EMCC, 'libfoo.a', 'hello_world.o'])
8730+
run_process([PYTHON, EMCC, 'libfoo.a', 'hello_world.o'])
8731+
8732+
def test_archive_non_objects(self):
8733+
create_test_file('file.txt', 'test file')
8734+
create_test_file('zeros.bin', '\0\0\0\0')
8735+
run_process([PYTHON, EMCC, '-c', path_from_root('tests', 'hello_world.c')])
8736+
# No index added.
8737+
run_process([PYTHON, EMAR, 'crS', 'libfoo.a', 'file.txt', 'zeros.bin', 'hello_world.o'])
8738+
run_process([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), 'libfoo.a'])
87308739

87318740
def test_flag_aliases(self):
87328741
def assert_aliases_match(flag1, flag2, flagarg, extra_args):

0 commit comments

Comments
 (0)