Skip to content

Commit 28ec96d

Browse files
committed
Enable real dynamic linking by default
This change essentially disables `FAKE_DYLIBS` by default, which in turn means `-shared` will now produce dynamic libraries by default. If you want the old behaviour you now need `-sFAKE_DYLIBS`.
1 parent c873744 commit 28ec96d

9 files changed

Lines changed: 94 additions & 91 deletions

File tree

ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ See docs/process.md for more on how version tagging works.
4343
notified of all IDBFS sync start and end events. (#26895)
4444
- google-closure-compiler was updated to 20260429.0.0. (#26869)
4545
Closure compiler now provides a native macOS arm64 binary for Apple Silicon.
46+
- The `FAKE_DYLIBS` setting is now disabled by default. This means that
47+
`-shared` will produce real dynamic libraries by default (`-sSIDE_MODULE` is
48+
implied). Also, if you include real dynamic libraries in your link comment
49+
emscirpten will now automatically produce a dynamically linker program
50+
(`-sMAIN_MODULE=2` is implied). (#25930)
4651

4752
5.0.7 - 04/30/26
4853
----------------

site/source/docs/tools_reference/settings_reference.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3354,13 +3354,13 @@ Default value: false
33543354
FAKE_DYLIBS
33553355
===========
33563356

3357-
This setting changes the behaviour of the ``-shared`` flag. The default
3358-
setting of ``true`` means the ``-shared`` flag actually produces a normal
3359-
object file (i.e. ``ld -r``). Setting this to false will cause ``-shared``
3360-
to behave like :ref:`SIDE_MODULE` and produce a dynamically linked
3361-
library.
3357+
This setting changes the behaviour of the ``-shared`` flag. When set to true
3358+
you get the old emscripten behaviour where the ``-shared`` flag actually
3359+
produces a normal object file (i.e. ``ld -r``). When set to true (the
3360+
default) the ``-shared`` flag is equivelent to :ref:`SIDE_MODULE` and will
3361+
produce a Wasn dynamic library.
33623362

3363-
Default value: true
3363+
Default value: false
33643364

33653365
.. _executable:
33663366

src/settings.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,12 +2199,12 @@ var GROWABLE_ARRAYBUFFERS = false;
21992199
// indirectly using `importScripts`
22002200
var CROSS_ORIGIN = false;
22012201

2202-
// This setting changes the behaviour of the ``-shared`` flag. The default
2203-
// setting of ``true`` means the ``-shared`` flag actually produces a normal
2204-
// object file (i.e. ``ld -r``). Setting this to false will cause ``-shared``
2205-
// to behave like :ref:`SIDE_MODULE` and produce a dynamically linked
2206-
// library.
2207-
var FAKE_DYLIBS = true;
2202+
// This setting changes the behaviour of the ``-shared`` flag. When set to true
2203+
// you get the old emscripten behaviour where the ``-shared`` flag actually
2204+
// produces a normal object file (i.e. ``ld -r``). When set to true (the
2205+
// default) the ``-shared`` flag is equivelent to :ref:`SIDE_MODULE` and will
2206+
// produce a Wasn dynamic library.
2207+
var FAKE_DYLIBS = false;
22082208

22092209
// Add a #! line to generated JS file and make it executable. This is useful
22102210
// for building command line tools that run under node.

test/common.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ def get_poppler_library(self, env_init=None):
15151515

15161516
return poppler + freetype
15171517

1518-
def get_zlib_library(self, cmake, cflags=None):
1518+
def get_zlib_library(self, cmake, cflags=None, target='libz.a'):
15191519
assert cmake or not WINDOWS, 'on windows, get_zlib_library only supports cmake'
15201520

15211521
old_args = self.cflags.copy()
@@ -1529,12 +1529,12 @@ def get_zlib_library(self, cmake, cflags=None):
15291529
# https://github.com/emscripten-core/emscripten/issues/16908 is fixed
15301530
self.cflags.append('-Wno-pointer-sign')
15311531
if cmake:
1532-
rtn = self.get_library(os.path.join('third_party', 'zlib'), os.path.join('libz.a'),
1532+
rtn = self.get_library(os.path.join('third_party', 'zlib'), target,
15331533
configure=['cmake', '.'],
15341534
make=['cmake', '--build', '.', '--'],
15351535
make_args=[])
15361536
else:
1537-
rtn = self.get_library(os.path.join('third_party', 'zlib'), os.path.join('libz.a'), make_args=['libz.a'])
1537+
rtn = self.get_library(os.path.join('third_party', 'zlib'), target, make_args=['libz.a', target])
15381538
self.cflags = old_args
15391539
return rtn
15401540

test/test_core.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4063,8 +4063,8 @@ def dylink_testf(self, main, side=None, expected=None, force_c=False, main_cflag
40634063

40644064
shutil.move(so_file, so_file + '.orig')
40654065

4066-
# Verify that building with -sSIDE_MODULE is essentially the same as building with `-shared -fPIC -sFAKE_DYLIBS=0`.
4067-
flags = ['-shared', '-fPIC', '-sFAKE_DYLIBS=0']
4066+
# Verify that building with -sSIDE_MODULE is essentially the same as building with `-shared -fPIC`
4067+
flags = ['-shared', '-fPIC']
40684068
if isinstance(side, list):
40694069
# side is just a library
40704070
self.run_process([EMCC] + side + self.get_cflags() + flags + ['-o', so_file])
@@ -5091,7 +5091,8 @@ def do_run(src, expected_output, cflags=None):
50915091

50925092
@with_dylink_reversed
50935093
def test_dylink_dot_a(self):
5094-
# .a linking must force all .o files inside it, when in a shared module
5094+
# Tests that its possible to link a .a archive into a dynamic library using
5095+
# `-Wl,--whole-archive`
50955096
create_file('third.c', 'int sidef() { return 36; }')
50965097
create_file('fourth.c', 'int sideg() { return 17; }')
50975098

@@ -5109,7 +5110,7 @@ def test_dylink_dot_a(self):
51095110
}
51105111
''',
51115112
# contents of libfourth.a must be included, even if they aren't referred to!
5112-
side=['libfourth.a', 'third.o'],
5113+
side=['-Wl,--whole-archive', 'libfourth.a', '-Wl,--no-whole-archive', 'third.o'],
51135114
expected=['sidef: 36, sideg: 17.\n'], force_c=True)
51145115

51155116
@with_dylink_reversed
@@ -5153,16 +5154,25 @@ def test_dylink_spaghetti(self):
51535154
'''])
51545155

51555156
@needs_make('mingw32-make')
5156-
@with_dylink_reversed
5157-
def test_dylink_zlib(self):
5158-
zlib_archive = self.get_zlib_library(cmake=WINDOWS, cflags=['-fPIC'])
5157+
@needs_dylink
5158+
@parameterized({
5159+
# Cmake support for dyanamic libraries is currently broken.
5160+
# We set `TARGET_SUPPORTS_SHARED_LIBS` in cmake/Modules/Platform/Emscripten.cmake which
5161+
# means we don't/can't build shared libraries yet.
5162+
# https://gitlab.kitware.com/cmake/cmake/-/work_items/27240
5163+
# 'cmake': (True,),
5164+
'configure': (False,),
5165+
})
5166+
def test_dylink_zlib(self, cmake):
5167+
zlib_archive = self.get_zlib_library(cmake=cmake, target='libz.so.1.2.5', cflags=['-fPIC'])[0]
5168+
zlib_basename = os.path.basename(zlib_archive)
5169+
shutil.copyfile(zlib_archive, zlib_basename)
51595170
# example.c uses K&R style function declarations
51605171
self.cflags.append('-Wno-deprecated-non-prototype')
51615172
self.cflags.append('-I' + test_file('third_party/zlib'))
5162-
self.dylink_test(main=read_file(test_file('third_party/zlib/example.c')),
5163-
side=zlib_archive,
5164-
expected=read_file(test_file('core/test_zlib.out')),
5165-
force_c=True)
5173+
self.do_runf(test_file('third_party/zlib/example.c'),
5174+
read_file(test_file('core/test_zlib.out')),
5175+
cflags=['-L.', zlib_archive])
51665176

51675177
# @with_dylink_reversed
51685178
# def test_dylink_bullet(self):

test/test_other.py

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,8 @@ def test_cmake_explicit_generator(self):
930930
# use -Wno-dev to suppress an irrelevant warning about the test files only.
931931
cmd = [EMCMAKE, 'cmake', '-GNinja', '-Wno-dev', test_file('cmake/cpp_lib')]
932932
self.run_process(cmd)
933-
self.assertExists(self.get_dir() + '/build.ninja')
933+
self.assertExists('build.ninja')
934+
self.run_process(['ninja', '-v'])
934935

935936
# Tests that it's possible to pass C++17 or GNU++17 build modes to CMake by building code that
936937
# needs C++17 (embind)
@@ -1173,7 +1174,7 @@ def test_odd_suffixes(self):
11731174
for suffix in ('lo',):
11741175
self.clear()
11751176
print(suffix)
1176-
self.run_process([EMCC, test_file('hello_world.c'), '-shared', '-o', 'binary.' + suffix])
1177+
self.run_process([EMCC, test_file('hello_world.c'), '-shared', '-fPIC', '-o', 'binary.' + suffix])
11771178
self.run_process([EMCC, 'binary.' + suffix])
11781179
self.assertContained('Hello, world!', self.run_js('a.out.js'))
11791180

@@ -1358,11 +1359,11 @@ def test_multiply_defined_libsymbols(self):
13581359
# we model shared libraries using regular object files. Without special handling
13591360
# fake `libA.so` could get linked multiple times.
13601361
self.cflags.remove('-Werror')
1361-
self.emcc('libA.c', ['-shared', '-o', 'libA.so'])
1362+
self.emcc('libA.c', ['-sFAKE_DYLIBS', '-shared', '-fPIC', '-o', 'libA.so'])
13621363

1363-
err = self.emcc('a2.c', ['-shared', '-L.', '-lA', '-o', 'liba2.so'], stderr=PIPE).stderr
1364+
err = self.emcc('a2.c', ['-sFAKE_DYLIBS', '-shared', '-fPIC', '-L.', '-lA', '-o', 'liba2.so'], stderr=PIPE).stderr
13641365
self.assertContained('emcc: warning: ignoring dynamic library libA.so when generating an object file', err)
1365-
err = self.emcc('b2.c', ['-shared', '-L.', '-lA', '-o', 'libb2.so'], stderr=PIPE).stderr
1366+
err = self.emcc('b2.c', ['-sFAKE_DYLIBS', '-shared', '-fPIC', '-L.', '-lA', '-o', 'libb2.so'], stderr=PIPE).stderr
13661367
self.assertContained('emcc: warning: ignoring dynamic library libA.so when generating an object file', err)
13671368

13681369
self.do_runf('main.c', 'result: 1', cflags=['-L.', '-lA', 'liba2.so', 'libb2.so'])
@@ -1493,7 +1494,12 @@ def test_link_group_bitcode(self):
14931494
# We deliberately ignore duplicate input files in order to allow
14941495
# "libA.so" on the command line twice. This is not really .so support
14951496
# and the .so files are really object files.
1496-
def test_redundant_link(self):
1497+
@parameterized({
1498+
'': ([],),
1499+
'fake_dylibs': (['-sFAKE_DYLIBS'],),
1500+
})
1501+
def test_redundant_link(self, args):
1502+
self.cflags += args
14971503
create_file('libA.c', 'int mult() { return 1; }')
14981504
create_file('main.c', r'''
14991505
#include <stdio.h>
@@ -1505,7 +1511,7 @@ def test_redundant_link(self):
15051511
''')
15061512

15071513
self.cflags.remove('-Werror')
1508-
self.emcc('libA.c', ['-shared', '-o', 'libA.so'])
1514+
self.emcc('libA.c', ['-fPIC', '-shared', '-o', 'libA.so'])
15091515
self.emcc('main.c', ['libA.so', 'libA.so', '-o', 'a.out.js'])
15101516
self.assertContained('result: 1', self.run_js('a.out.js'))
15111517

@@ -2153,9 +2159,9 @@ def test_multidynamic_link(self, link_flags, lib_suffix):
21532159
''')
21542160

21552161
# Build libfile normally into an .so
2156-
self.run_process([EMCC, 'libdir/libfile.c', '-shared', '-o', 'libdir/libfile.so' + lib_suffix])
2162+
self.run_process([EMCC, 'libdir/libfile.c', '-sFAKE_DYLIBS', '-shared', '-fPIC', '-o', 'libdir/libfile.so' + lib_suffix])
21572163
# Build libother and dynamically link it to libfile
2158-
self.run_process([EMCC, '-Llibdir', 'libdir/libother.c'] + link_flags + ['-shared', '-o', 'libdir/libother.so'])
2164+
self.run_process([EMCC, '-Llibdir', 'libdir/libother.c'] + link_flags + ['-sFAKE_DYLIBS', '-shared', '-fPIC', '-o', 'libdir/libother.so'])
21592165
# Build the main file, linking in both the libs
21602166
self.run_process([EMCC, '-Llibdir', os.path.join('main.c')] + link_flags + ['-lother', '-c'])
21612167
print('...')
@@ -2460,17 +2466,17 @@ def test_dylink_library_search(self):
24602466
}
24612467
''')
24622468

2463-
# By deafult we use static linking and prefer libside.a
2464-
self.do_runf('main.c', 'static linking used\n', cflags=['-L.', '-lside'])
2469+
# By default we use dynamic linking
2470+
self.do_runf('main.c', 'dynamic linking used\n', cflags=['-L.', '-lside'])
24652471

2466-
# When using -sMAIN_MODULE we choose the dyanmic library
2467-
self.do_runf('main.c', 'dynamic linking used\n', cflags=['-sMAIN_MODULE=2', '-L.', '-lside'])
2472+
# When using -sMAIN_MODULE=0 we explictly opt out of dynammic linking
2473+
self.do_runf('main.c', 'static linking used\n', cflags=['-sMAIN_MODULE=0', '-L.', '-lside'])
24682474

2469-
# Same for `-sFAKE_DYLIBS=0
2470-
self.do_runf('main.c', 'dynamic linking used\n', cflags=['-sFAKE_DYLIBS=0', '-L.', '-lside'])
2475+
# Same for `-sFAKE_DYLIBS
2476+
self.do_runf('main.c', 'static linking used\n', cflags=['-sFAKE_DYLIBS', '-L.', '-lside'])
24712477

24722478
# With can also force static linking using `-Bstatic` linker falgs
2473-
self.do_runf('main.c', 'static linking used\n', cflags=['-sMAIN_MODULE=2', '-L.', '-Bstatic', '-lside'])
2479+
self.do_runf('main.c', 'static linking used\n', cflags=['-L.', '-Bstatic', '-lside'])
24742480

24752481
def test_js_link(self):
24762482
create_file('before.js', '''
@@ -4953,20 +4959,6 @@ def test_valid_abspath_2(self):
49534959
self.run_process(cmd)
49544960
self.assertContained('Hello, world!', self.run_js('a.out.js'))
49554961

4956-
def test_warn_dylibs(self):
4957-
shared_suffixes = ['.so', '.dylib', '.dll']
4958-
4959-
for suffix in ('.o', '.bc', '.so', '.dylib', '.js', '.html'):
4960-
print(suffix)
4961-
cmd = [EMCC, test_file('hello_world.c'), '-o', 'out' + suffix]
4962-
if suffix in {'.o', '.bc'}:
4963-
cmd.append('-c')
4964-
if suffix in {'.dylib', '.so'}:
4965-
cmd.append('-shared')
4966-
err = self.run_process(cmd, stderr=PIPE).stderr
4967-
warning = 'linking a library with `-shared` will emit a static object file'
4968-
self.assertContainedIf(warning, err, suffix in shared_suffixes)
4969-
49704962
@crossplatform
49714963
@parameterized({
49724964
'O2': [['-O2']],
@@ -8462,12 +8454,12 @@ def test_side_module_ignore(self):
84628454
self.run_process([EMCC, test_file('hello_world.c'), '-sSIDE_MODULE', '-o', 'libside.so'])
84638455

84648456
# Attempting to link statically against a side module (libside.so) should fail.
8465-
self.assert_fail([EMCC, '-L.', '-lside'], 'wasm-ld: error: unable to find library -lside')
8457+
self.assert_fail([EMCC, '-L.', '-Bstatic', '-lside'], 'wasm-ld: error: unable to find library -lside')
84668458

84678459
# But a static library in the same location (libside.a) should take precedence.
84688460
self.run_process([EMCC, test_file('hello_world.c'), '-c'])
84698461
self.run_process([EMAR, 'cr', 'libside.a', 'hello_world.o'])
8470-
self.run_process([EMCC, '-L.', '-lside'])
8462+
self.run_process([EMCC, '-L.', '-Bstatic', '-lside'])
84718463
self.assertContained('Hello, world!', self.run_js('a.out.js'))
84728464

84738465
@is_slow_test
@@ -12129,42 +12121,40 @@ def test_err(self):
1212912121
def test_euidaccess(self):
1213012122
self.do_other_test('test_euidaccess.c')
1213112123

12132-
def test_shared_flag(self):
12133-
create_file('side.c', 'int foo;')
12134-
self.run_process([EMCC, '-shared', 'side.c', '-o', 'libother.so'])
12124+
def test_fake_dylibs(self):
12125+
create_file('other.c', 'int foo = 10;')
12126+
self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-fPIC', 'other.c', '-o', 'libother.so'])
12127+
self.assertIsObjectFile('libother.so')
1213512128

12136-
# Test that `-shared` flag causes object file generation but gives a warning
12137-
err = self.run_process([EMCC, '-shared', test_file('hello_world.c'), '-o', 'out.foo', 'libother.so'], stderr=PIPE).stderr
12138-
self.assertContained('linking a library with `-shared` will emit a static object', err)
12129+
# Test that `-sFAKE_DYLIBS` flag causes object file generation and will generate a warning about
12130+
# dylink dependencies being ignored.
12131+
err = self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-fPIC', test_file('hello_world.c'), '-o', 'out.foo', 'libother.so'], stderr=PIPE).stderr
1213912132
self.assertContained('emcc: warning: ignoring dynamic library libother.so when generating an object file, this will need to be included explicitly in the final link', err)
1214012133
self.assertIsObjectFile('out.foo')
1214112134

1214212135
# Test that adding `-sFAKE_DYLIBS=0` build a real side module
1214312136
err = self.run_process([EMCC, '-shared', '-fPIC', '-sFAKE_DYLIBS=0', test_file('hello_world.c'), '-o', 'out.foo', 'libother.so'], stderr=PIPE).stderr
12144-
self.assertNotContained('linking a library with `-shared` will emit a static object', err)
1214512137
self.assertNotContained('emcc: warning: ignoring dynamic library libother.so when generating an object file, this will need to be included explicitly in the final link', err)
1214612138
self.assertIsWasmDylib('out.foo')
1214712139

1214812140
# Test that using an executable output name overrides the `-shared` flag, but produces a warning.
12149-
err = self.run_process([EMCC, '-shared', test_file('hello_world.c'), '-o', 'out.js'],
12141+
err = self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-fPIC', test_file('hello_world.c'), '-o', 'out.js'],
1215012142
stderr=PIPE).stderr
1215112143
self.assertContained('warning: -shared/-r used with executable output suffix', err)
1215212144
self.run_js('out.js')
1215312145

1215412146
def test_shared_soname(self):
12155-
self.run_process([EMCC, '-shared', '-Wl,-soname', '-Wl,libfoo.so.13', test_file('hello_world.c'), '-lc', '-o', 'libfoo.so'])
12147+
self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-Wl,-soname', '-Wl,libfoo.so.13', test_file('hello_world.c'), '-lc', '-o', 'libfoo.so'])
1215612148
self.run_process([EMCC, '-sSTRICT', 'libfoo.so'])
1215712149
self.assertContained('Hello, world!', self.run_js('a.out.js'))
1215812150

12159-
def test_shared_and_side_module_flag(self):
12160-
# Test that `-shared` and `-sSIDE_MODULE` flag causes wasm dylib generation without a warning.
12161-
err = self.run_process([EMCC, '-shared', '-sSIDE_MODULE', test_file('hello_world.c'), '-o', 'out.foo'], stderr=PIPE).stderr
12162-
self.assertNotContained('linking a library with `-shared` will emit a static object', err)
12151+
def test_shared_flag(self):
12152+
# Test that `-shared` flag causes wasm dylib generation
12153+
self.run_process([EMCC, '-shared', '-fPIC', test_file('hello_world.c'), '-o', 'out.foo'])
1216312154
self.assertIsWasmDylib('out.foo')
1216412155

12165-
# Test that `-shared` and `-sSIDE_MODULE` flag causes wasm dylib generation without a warning even if given executable output name.
12166-
err = self.run_process([EMCC, '-shared', '-sSIDE_MODULE', test_file('hello_world.c'), '-o', 'out.wasm'],
12167-
stderr=PIPE).stderr
12156+
# Test that `-shared` causes wasm dylib generation warning even if given executable output name.
12157+
err = self.run_process([EMCC, '-shared', '-fPIC', test_file('hello_world.c'), '-o', 'out.wasm'], stderr=PIPE).stderr
1216812158
self.assertNotContained('warning: -shared/-r used with executable output suffix', err)
1216912159
self.assertIsWasmDylib('out.wasm')
1217012160

tools/building.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def get_building_env():
7272
env['AR'] = EMAR
7373
env['LD'] = EMCC
7474
env['NM'] = LLVM_NM
75-
env['LDSHARED'] = EMCC
75+
env['LDSHARED'] = f'{EMCC} -shared'
7676
env['RANLIB'] = EMRANLIB
7777
env['EMSCRIPTEN_TOOLS'] = path_from_root('tools')
7878
env['HOST_CC'] = CLANG_CC
@@ -165,6 +165,12 @@ def lld_flags_for_executable(external_symbols):
165165
stub = create_stub_object(external_symbols)
166166
cmd.append(stub)
167167

168+
if settings.FAKE_DYLIBS or (not settings.MAIN_MODULE and not settings.SIDE_MODULE):
169+
cmd.append('-Bstatic')
170+
else:
171+
# wasm-ld still defaults to static linking by default. If that ever changes, we can remove this line.
172+
cmd.append('-Bdynamic')
173+
168174
if not settings.ERROR_ON_UNDEFINED_SYMBOLS:
169175
cmd.append('--import-undefined')
170176

@@ -184,9 +190,6 @@ def lld_flags_for_executable(external_symbols):
184190
not settings.ASYNCIFY):
185191
cmd.append('--strip-debug')
186192

187-
if settings.LINKABLE:
188-
cmd.append('--export-dynamic')
189-
190193
if settings.LTO and not settings.EXIT_RUNTIME:
191194
# The WebAssembly backend can generate new references to `__cxa_atexit` at
192195
# LTO time. This `-u` flag forces the `__cxa_atexit` symbol to be
@@ -203,7 +206,6 @@ def lld_flags_for_executable(external_symbols):
203206
c_exports = [e for e in c_exports if e not in external_symbols]
204207
c_exports += settings.REQUIRED_EXPORTS
205208
if settings.MAIN_MODULE:
206-
cmd.append('-Bdynamic')
207209
c_exports += side_module_external_deps(external_symbols)
208210
for export in c_exports:
209211
if settings.ERROR_ON_UNDEFINED_SYMBOLS:
@@ -227,6 +229,8 @@ def lld_flags_for_executable(external_symbols):
227229
if not settings.LINKABLE:
228230
cmd.append('--no-export-dynamic')
229231
else:
232+
if settings.LINKABLE:
233+
cmd.append('--export-dynamic')
230234
cmd.append('--export-table')
231235
if settings.ALLOW_TABLE_GROWTH:
232236
cmd.append('--growable-table')
@@ -281,7 +285,7 @@ def lld_flags(args):
281285

282286
# Emscripten currently expects linkable output (SIDE_MODULE/MAIN_MODULE) to
283287
# include all archive contents.
284-
if settings.LINKABLE:
288+
if settings.LINKABLE and (settings.FAKE_DYLIBS or not settings.SIDE_MODULE):
285289
args.insert(0, '--whole-archive')
286290
args.append('--no-whole-archive')
287291

tools/cmdline.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@
5454

5555
@unique
5656
class OFormat(Enum):
57-
# Output a relocatable object file. We use this
58-
# today for `-r` and `-shared`.
57+
# Output a relocatable object file. i.e. `-r` linker flag
5958
OBJECT = auto()
6059
WASM = auto()
6160
JS = auto()

0 commit comments

Comments
 (0)