Skip to content

Commit 655b473

Browse files
committed
Disable FAKE_DYLIBS by default
This means that `-shared` will now produce a dynamic library by default. If you want the old behaviour you now need `-sFAKE_DYLIBS`.
1 parent ffb1e90 commit 655b473

File tree

6 files changed

+41
-67
lines changed

6 files changed

+41
-67
lines changed

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ See docs/process.md for more on how version tagging works.
2020

2121
4.0.22 (in development)
2222
-----------------------
23+
- The FAKE_DYLIBS is now disabled by default. This means that `-shared` will
24+
now produce real dynamic libraries by default.
2325
- Emscripten will now cache the JS code that it generates and re-use when
2426
linking with the same settings at a later date. This should improve link
2527
times generally but should especially noticeable when linking lots of small

cmake/Modules/Platform/Emscripten.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ set(CMAKE_SYSTEM_NAME Emscripten)
1818
set(CMAKE_SYSTEM_VERSION 1)
1919

2020
set(CMAKE_CROSSCOMPILING TRUE)
21-
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
21+
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
2222

2323
# Advertise Emscripten as a 32-bit platform (as opposed to
2424
# CMAKE_SYSTEM_PROCESSOR=x86_64 for 64-bit platform), since some projects (e.g.

src/settings.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,9 +2241,8 @@ var WASM_JS_TYPES = false;
22412241
// indirectly using `importScripts`
22422242
var CROSS_ORIGIN = false;
22432243

2244-
// This setting changes the behaviour of the ``-shared`` flag. The default
2245-
// setting of ``true`` means the ``-shared`` flag actually produces a normal
2246-
// object file (i.e. ``ld -r``). Setting this to false will cause ``-shared``
2247-
// to behave like :ref:`SIDE_MODULE` and produce and dynamically linked
2248-
// library.
2249-
var FAKE_DYLIBS = true;
2244+
// This setting changes the behaviour of the ``-shared`` flag. When set to true
2245+
// you get the old emscripten behaivour where the ``-shared`` flag actually
2246+
// produces a normal object file (i.e. ``ld -r``). The default behaviour is that
2247+
// `-shared` is the as :ref:`SIDE_MODULE`.
2248+
var FAKE_DYLIBS = false;

test/test_other.py

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ def test_odd_suffixes(self):
12381238
for suffix in ('lo',):
12391239
self.clear()
12401240
print(suffix)
1241-
self.run_process([EMCC, test_file('hello_world.c'), '-shared', '-o', 'binary.' + suffix])
1241+
self.run_process([EMCC, test_file('hello_world.c'), '-sFAKE_DYLIBS', '-shared', '-o', 'binary.' + suffix])
12421242
self.run_process([EMCC, 'binary.' + suffix])
12431243
self.assertContained('hello, world!', self.run_js('a.out.js'))
12441244

@@ -1419,7 +1419,7 @@ def test_multiply_defined_libsymbols(self):
14191419
''')
14201420

14211421
self.cflags.remove('-Werror')
1422-
self.emcc('libA.c', ['-shared', '-o', 'libA.so'])
1422+
self.emcc('libA.c', ['-shared', '-sFAKE_DYLIBS', '-o', 'libA.so'])
14231423

14241424
self.emcc('a2.c', ['-r', '-L.', '-lA', '-o', 'a2.o'])
14251425
self.emcc('b2.c', ['-r', '-L.', '-lA', '-o', 'b2.o'])
@@ -1552,7 +1552,12 @@ def test_link_group_bitcode(self):
15521552
# We deliberately ignore duplicate input files in order to allow
15531553
# "libA.so" on the command line twice. This is not really .so support
15541554
# and the .so files are really object files.
1555-
def test_redundant_link(self):
1555+
@parameterized({
1556+
'': ([],),
1557+
'fake_dylibs': (['-sFAKE_DYLIBS'],),
1558+
})
1559+
def test_redundant_link(self, args):
1560+
self.cflags += args
15561561
create_file('libA.c', 'int mult() { return 1; }')
15571562
create_file('main.c', r'''
15581563
#include <stdio.h>
@@ -1564,7 +1569,7 @@ def test_redundant_link(self):
15641569
''')
15651570

15661571
self.cflags.remove('-Werror')
1567-
self.emcc('libA.c', ['-shared', '-o', 'libA.so'])
1572+
self.emcc('libA.c', ['-fPIC', '-shared', '-o', 'libA.so'])
15681573
self.emcc('main.c', ['libA.so', 'libA.so', '-o', 'a.out.js'])
15691574
self.assertContained('result: 1', self.run_js('a.out.js'))
15701575

@@ -2159,9 +2164,9 @@ def test_multidynamic_link(self, link_flags, lib_suffix):
21592164
''')
21602165

21612166
# Build libfile normally into an .so
2162-
self.run_process([EMCC, 'libdir/libfile.c', '-shared', '-o', 'libdir/libfile.so' + lib_suffix])
2167+
self.run_process([EMCC, 'libdir/libfile.c', '-sFAKE_DYLIBS', '-shared', '-fPIC', '-o', 'libdir/libfile.so' + lib_suffix])
21632168
# Build libother and dynamically link it to libfile
2164-
self.run_process([EMCC, '-Llibdir', 'libdir/libother.c'] + link_flags + ['-shared', '-o', 'libdir/libother.so'])
2169+
self.run_process([EMCC, '-Llibdir', 'libdir/libother.c'] + link_flags + ['-sFAKE_DYLIBS', '-shared', '-fPIC', '-o', 'libdir/libother.so'])
21652170
# Build the main file, linking in both the libs
21662171
self.run_process([EMCC, '-Llibdir', os.path.join('main.c')] + link_flags + ['-lother', '-c'])
21672172
print('...')
@@ -4896,20 +4901,6 @@ def test_valid_abspath_2(self):
48964901
self.run_process(cmd)
48974902
self.assertContained('hello, world!', self.run_js('a.out.js'))
48984903

4899-
def test_warn_dylibs(self):
4900-
shared_suffixes = ['.so', '.dylib', '.dll']
4901-
4902-
for suffix in ('.o', '.bc', '.so', '.dylib', '.js', '.html'):
4903-
print(suffix)
4904-
cmd = [EMCC, test_file('hello_world.c'), '-o', 'out' + suffix]
4905-
if suffix in ['.o', '.bc']:
4906-
cmd.append('-c')
4907-
if suffix in ['.dylib', '.so']:
4908-
cmd.append('-shared')
4909-
err = self.run_process(cmd, stderr=PIPE).stderr
4910-
warning = 'linking a library with `-shared` will emit a static object file'
4911-
self.assertContainedIf(warning, err, suffix in shared_suffixes)
4912-
49134904
@crossplatform
49144905
@parameterized({
49154906
'O2': [['-O2']],
@@ -8388,19 +8379,6 @@ def test_side_module_folder_deps(self):
83888379
self.run_process([EMCC, test_file('hello_world.c'), '-sSIDE_MODULE', '-o', 'subdir/libside2.so', '-L', 'subdir', '-lside1'])
83898380
self.run_process([EMCC, test_file('hello_world.c'), '-sMAIN_MODULE', '-o', 'main.js', '-L', 'subdir', '-lside2'])
83908381

8391-
@crossplatform
8392-
def test_side_module_ignore(self):
8393-
self.run_process([EMCC, test_file('hello_world.c'), '-sSIDE_MODULE', '-o', 'libside.so'])
8394-
8395-
# Attempting to link statically against a side module (libside.so) should fail.
8396-
self.assert_fail([EMCC, '-L.', '-lside'], 'wasm-ld: error: unable to find library -lside')
8397-
8398-
# But a static library in the same location (libside.a) should take precedence.
8399-
self.run_process([EMCC, test_file('hello_world.c'), '-c'])
8400-
self.run_process([EMAR, 'cr', 'libside.a', 'hello_world.o'])
8401-
self.run_process([EMCC, '-L.', '-lside'])
8402-
self.assertContained('hello, world!', self.run_js('a.out.js'))
8403-
84048382
@is_slow_test
84058383
@parameterized({
84068384
'': ([],),
@@ -11922,42 +11900,40 @@ def test_err(self):
1192211900
def test_euidaccess(self):
1192311901
self.do_other_test('test_euidaccess.c')
1192411902

11925-
def test_shared_flag(self):
11926-
create_file('side.c', 'int foo;')
11927-
self.run_process([EMCC, '-shared', 'side.c', '-o', 'libother.so'])
11903+
def test_fake_dylibs(self):
11904+
create_file('other.c', 'int foo = 10;')
11905+
self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-fPIC', 'other.c', '-o', 'libother.so'])
11906+
self.assertIsObjectFile('libother.so')
1192811907

11929-
# Test that `-shared` flag causes object file generation but gives a warning
11930-
err = self.run_process([EMCC, '-shared', test_file('hello_world.c'), '-o', 'out.foo', 'libother.so'], stderr=PIPE).stderr
11931-
self.assertContained('linking a library with `-shared` will emit a static object', err)
11908+
# Test that `-sFAKE_DYLIBS` flag causes object file generation and will generate a warning about
11909+
# dylink dependencies being ignored.
11910+
err = self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-fPIC', test_file('hello_world.c'), '-o', 'out.foo', 'libother.so'], stderr=PIPE).stderr
1193211911
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)
1193311912
self.assertIsObjectFile('out.foo')
1193411913

1193511914
# Test that adding `-sFAKE_DYIBS=0` build a real side module
1193611915
err = self.run_process([EMCC, '-shared', '-fPIC', '-sFAKE_DYLIBS=0', test_file('hello_world.c'), '-o', 'out.foo', 'libother.so'], stderr=PIPE).stderr
11937-
self.assertNotContained('linking a library with `-shared` will emit a static object', err)
1193811916
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)
1193911917
self.assertIsWasmDylib('out.foo')
1194011918

1194111919
# Test that using an executable output name overrides the `-shared` flag, but produces a warning.
11942-
err = self.run_process([EMCC, '-shared', test_file('hello_world.c'), '-o', 'out.js'],
11920+
err = self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-fPIC', test_file('hello_world.c'), '-o', 'out.js'],
1194311921
stderr=PIPE).stderr
1194411922
self.assertContained('warning: -shared/-r used with executable output suffix', err)
1194511923
self.run_js('out.js')
1194611924

1194711925
def test_shared_soname(self):
11948-
self.run_process([EMCC, '-shared', '-Wl,-soname', '-Wl,libfoo.so.13', test_file('hello_world.c'), '-lc', '-o', 'libfoo.so'])
11926+
self.run_process([EMCC, '-shared', '-sFAKE_DYLIBS', '-Wl,-soname', '-Wl,libfoo.so.13', test_file('hello_world.c'), '-lc', '-o', 'libfoo.so'])
1194911927
self.run_process([EMCC, '-sSTRICT', 'libfoo.so'])
1195011928
self.assertContained('hello, world!', self.run_js('a.out.js'))
1195111929

11952-
def test_shared_and_side_module_flag(self):
11953-
# Test that `-shared` and `-sSIDE_MODULE` flag causes wasm dylib generation without a warning.
11954-
err = self.run_process([EMCC, '-shared', '-sSIDE_MODULE', test_file('hello_world.c'), '-o', 'out.foo'], stderr=PIPE).stderr
11955-
self.assertNotContained('linking a library with `-shared` will emit a static object', err)
11930+
def test_shared_flag(self):
11931+
# Test that `-shared` flag causes wasm dylib generation
11932+
self.run_process([EMCC, '-shared', '-fPIC', test_file('hello_world.c'), '-o', 'out.foo'])
1195611933
self.assertIsWasmDylib('out.foo')
1195711934

11958-
# Test that `-shared` and `-sSIDE_MODULE` flag causes wasm dylib generation without a warning even if given executable output name.
11959-
err = self.run_process([EMCC, '-shared', '-sSIDE_MODULE', test_file('hello_world.c'), '-o', 'out.wasm'],
11960-
stderr=PIPE).stderr
11935+
# Test that `-shared` causes wasm dylib generation warning even if given executable output name.
11936+
err = self.run_process([EMCC, '-shared', '-fPIC', test_file('hello_world.c'), '-o', 'out.wasm'], stderr=PIPE).stderr
1196111937
self.assertNotContained('warning: -shared/-r used with executable output suffix', err)
1196211938
self.assertIsWasmDylib('out.wasm')
1196311939

tools/building.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ def lld_flags_for_executable(external_symbols):
170170
stub = create_stub_object(external_symbols)
171171
cmd.append(stub)
172172

173+
if not settings.FAKE_DYLIBS:
174+
cmd.append('-Bdynamic')
175+
173176
if not settings.ERROR_ON_UNDEFINED_SYMBOLS:
174177
cmd.append('--import-undefined')
175178

@@ -208,7 +211,6 @@ def lld_flags_for_executable(external_symbols):
208211
c_exports = [e for e in c_exports if e not in external_symbols]
209212
c_exports += settings.REQUIRED_EXPORTS
210213
if settings.MAIN_MODULE:
211-
cmd.append('-Bdynamic')
212214
c_exports += side_module_external_deps(external_symbols)
213215
for export in c_exports:
214216
if settings.ERROR_ON_UNDEFINED_SYMBOLS:

tools/link.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -807,9 +807,6 @@ def phase_linker_setup(options, linker_args): # noqa: C901, PLR0912, PLR0915
807807

808808
apply_library_settings(linker_args)
809809

810-
if settings.SIDE_MODULE or settings.MAIN_MODULE:
811-
default_setting('FAKE_DYLIBS', 0)
812-
813810
if options.shared and not settings.FAKE_DYLIBS:
814811
default_setting('SIDE_MODULE', 1)
815812
default_setting('RELOCATABLE', 1)
@@ -920,8 +917,6 @@ def phase_linker_setup(options, linker_args): # noqa: C901, PLR0912, PLR0915
920917
if final_suffix in EXECUTABLE_EXTENSIONS:
921918
diagnostics.warning('emcc', '-shared/-r used with executable output suffix. This behaviour is deprecated. Please remove -shared/-r to build an executable or avoid the executable suffix (%s) when building object files.' % final_suffix)
922919
else:
923-
if options.shared and 'FAKE_DYLIBS' not in user_settings:
924-
diagnostics.warning('emcc', 'linking a library with `-shared` will emit a static object file (FAKE_DYLIBS defaults to true). If you want to build a runtime shared library use the SIDE_MODULE or FAKE_DYLIBS=0.')
925920
options.oformat = OFormat.OBJECT
926921

927922
if not options.oformat:
@@ -2740,22 +2735,22 @@ def process_libraries(options, flags):
27402735
continue
27412736

27422737
static_lib = f'lib{lib}.a'
2743-
if not settings.RELOCATABLE and not settings.MAIN_MODULE and not find_library(static_lib, options.lib_dirs):
2738+
if not find_library(static_lib, options.lib_dirs):
27442739
# Normally we can rely on the native linker to expand `-l` args.
27452740
# However, emscripten also supports fake `.so` files that are actually
27462741
# just regular object files. This means we need to support `.so` files even
27472742
# when statically linking. The native linker (wasm-ld) will otherwise
27482743
# ignore .so files in this mode.
2749-
found_dylib = False
2744+
found_fake_dylib = False
27502745
for ext in DYLIB_EXTENSIONS:
27512746
name = 'lib' + lib + ext
27522747
path = find_library(name, options.lib_dirs)
27532748
if path and not building.is_wasm_dylib(path):
2754-
found_dylib = True
2749+
found_fake_dylib = True
27552750
new_flags.append(path)
27562751
break
27572752

2758-
if found_dylib:
2753+
if found_fake_dylib:
27592754
continue
27602755

27612756
new_flags.append(flag)
@@ -3059,7 +3054,7 @@ def phase_calculate_linker_inputs(options, linker_args):
30593054
else:
30603055
linker_args = filter_out_duplicate_fake_dynamic_libs(linker_args)
30613056

3062-
if settings.MAIN_MODULE:
3057+
if not settings.SIDE_MODULE and not settings.FAKE_DYLIBS:
30633058
process_dynamic_libs(options.dylibs, options.lib_dirs)
30643059

30653060
return linker_args

0 commit comments

Comments
 (0)