Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2460,7 +2460,7 @@ def get_full_import_name(name):
@ToolchainProfiler.profile_block('compile inputs')
def phase_compile_inputs(options, state, newargs, input_files):
def is_link_flag(flag):
if flag.startswith('-nostdlib'):
if flag in ('-nostdlib', '-nostartfiles', '-nolibc', '-nodefaultlibs'):
return True
return flag.startswith(('-l', '-L', '-Wl,'))

Expand Down Expand Up @@ -2626,8 +2626,8 @@ def phase_calculate_system_libraries(state, linker_arguments, linker_inputs, new
if not settings.SIDE_MODULE:
# Ports are always linked into the main module, never the size module.
extra_files_to_link += ports.get_libs(settings)
if '-nostdlib' not in newargs and '-nodefaultlibs' not in newargs:
extra_files_to_link += system_libs.calculate([f for _, f in sorted(linker_inputs)] + extra_files_to_link, forced=state.forced_stdlibs)
all_linker_inputs = [f for _, f in sorted(linker_inputs)] + extra_files_to_link
extra_files_to_link += system_libs.calculate(all_linker_inputs, newargs, forced=state.forced_stdlibs)
linker_arguments.extend(extra_files_to_link)


Expand Down
2 changes: 2 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -10131,6 +10131,8 @@ def test_nostdlib(self):
libs = ['-lc', '-lcompiler_rt', '-lc_rt']
self.run_process([EMCC, test_file('unistd/close.c'), '-nostdlib'] + libs)
self.run_process([EMCC, test_file('unistd/close.c'), '-nodefaultlibs'] + libs)
self.run_process([EMCC, test_file('unistd/close.c'), '-nolibc', '-lc'])
self.run_process([EMCC, test_file('unistd/close.c'), '-nostartfiles'])

def test_argument_match(self):
# Verify that emcc arguments match precisely. We had a bug where only the prefix
Expand Down
156 changes: 86 additions & 70 deletions tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1651,22 +1651,12 @@ def add_reverse_deps(need):
add_reverse_deps(symbols)


def calculate(input_files, forced):
# Setting this will only use the forced libs in EMCC_FORCE_STDLIBS. This avoids spending time checking
# for unresolved symbols in your project files, which can speed up linking, but if you do not have
# the proper list of actually needed libraries, errors can occur. See below for how we must
# export all the symbols in deps_info when using this option.
only_forced = os.environ.get('EMCC_ONLY_FORCED_STDLIBS')
if only_forced:
# One of the purposes EMCC_ONLY_FORCED_STDLIBS was to skip the scanning
# of the input files for reverse dependencies.
diagnostics.warning('deprecated', 'EMCC_ONLY_FORCED_STDLIBS is deprecated. Use `-nostdlib` and/or `-s REVERSE_DEPS=none` depending on the desired result')
settings.REVERSE_DEPS = 'all'
def get_libs_to_link(args, forced, only_forced):
libs_to_link = []

handle_reverse_deps(input_files)
if '-nostdlib' in args:
return libs_to_link

force_include = []
libs_to_link = []
already_included = set()
system_libs_map = Library.get_usable_variations()

Expand All @@ -1675,6 +1665,7 @@ def calculate(input_files, forced):
# it can be the name of a lib (libc++, etc.).
# You can provide 1 to include everything, or a comma-separated list with the
# ones you want
force_include = []
force = os.environ.get('EMCC_FORCE_STDLIBS')
if force == '1':
force_include = [name for name, lib in system_libs_map.items() if not lib.never_force]
Expand All @@ -1695,93 +1686,118 @@ def add_library(libname):
need_whole_archive = lib.name in force_include and lib.get_ext() == '.a'
libs_to_link.append((lib.get_link_flag(), need_whole_archive))

if settings.USE_PTHREADS:
add_library('crtbegin')
if '-nostartfiles' not in args:
if settings.USE_PTHREADS:
add_library('crtbegin')

if settings.SIDE_MODULE:
return [l[0] for l in libs_to_link]
if settings.STANDALONE_WASM:
if settings.EXPECT_MAIN:
add_library('crt1')
else:
add_library('crt1_reactor')

if settings.STANDALONE_WASM:
if settings.EXPECT_MAIN:
add_library('crt1')
else:
add_library('crt1_reactor')
if settings.SIDE_MODULE:
return libs_to_link

for forced in force_include:
if forced not in system_libs_map:
shared.exit_with_error('invalid forced library: %s', forced)
add_library(forced)

if '-nodefaultlibs' in args:
return libs_to_link

if only_forced:
add_library('libc_rt')
add_library('libcompiler_rt')
else:
if settings.AUTO_NATIVE_LIBRARIES:
add_library('libGL')
add_library('libal')
add_library('libhtml5')
return libs_to_link

sanitize = settings.USE_LSAN or settings.USE_ASAN or settings.UBSAN_RUNTIME
if settings.AUTO_NATIVE_LIBRARIES:
add_library('libGL')
add_library('libal')
add_library('libhtml5')

# JS math must come before anything else, so that it overrides the normal
# libc math.
if settings.JS_MATH:
add_library('libjsmath')
sanitize = settings.USE_LSAN or settings.USE_ASAN or settings.UBSAN_RUNTIME

# to override the normal libc printf, we must come before it
if settings.PRINTF_LONG_DOUBLE:
add_library('libprintf_long_double')
# JS math must come before anything else, so that it overrides the normal
# libc math.
if settings.JS_MATH:
add_library('libjsmath')

if settings.ALLOW_UNIMPLEMENTED_SYSCALLS:
add_library('libstubs')
# to override the normal libc printf, we must come before it
if settings.PRINTF_LONG_DOUBLE:
add_library('libprintf_long_double')

if settings.ALLOW_UNIMPLEMENTED_SYSCALLS:
add_library('libstubs')
if '-nolibc' not in args:
if not settings.EXIT_RUNTIME:
add_library('libnoexit')
add_library('libc')
add_library('libcompiler_rt')
if settings.LINK_AS_CXX:
add_library('libc++')
if settings.LINK_AS_CXX or sanitize:
add_library('libc++abi')
if settings.EXCEPTION_HANDLING:
add_library('libunwind')
if settings.MALLOC != 'none':
add_library('libmalloc')
if settings.STANDALONE_WASM:
add_library('libstandalonewasm')
add_library('libc_rt')
add_library('libcompiler_rt')
if settings.LINK_AS_CXX:
add_library('libc++')
if settings.LINK_AS_CXX or sanitize:
add_library('libc++abi')
if settings.EXCEPTION_HANDLING:
add_library('libunwind')
if settings.STANDALONE_WASM:
add_library('libstandalonewasm')
add_library('libc_rt')

if settings.USE_LSAN:
force_include.append('liblsan_rt')
add_library('liblsan_rt')
if settings.USE_LSAN:
force_include.append('liblsan_rt')
add_library('liblsan_rt')

if settings.USE_ASAN:
force_include.append('libasan_rt')
add_library('libasan_rt')
add_library('libasan_js')
if settings.USE_ASAN:
force_include.append('libasan_rt')
add_library('libasan_rt')
add_library('libasan_js')

if settings.UBSAN_RUNTIME == 1:
add_library('libubsan_minimal_rt')
elif settings.UBSAN_RUNTIME == 2:
add_library('libubsan_rt')
if settings.UBSAN_RUNTIME == 1:
add_library('libubsan_minimal_rt')
elif settings.UBSAN_RUNTIME == 2:
add_library('libubsan_rt')

if settings.USE_LSAN or settings.USE_ASAN:
add_library('liblsan_common_rt')
if settings.USE_LSAN or settings.USE_ASAN:
add_library('liblsan_common_rt')

if sanitize:
add_library('libsanitizer_common_rt')
if sanitize:
add_library('libsanitizer_common_rt')

if settings.PROXY_POSIX_SOCKETS:
add_library('libsockets_proxy')
else:
add_library('libsockets')
if settings.PROXY_POSIX_SOCKETS:
add_library('libsockets_proxy')
else:
add_library('libsockets')

if settings.USE_WEBGPU:
add_library('libwebgpu_cpp')

return libs_to_link


def calculate(input_files, args, forced):
# Setting this will only use the forced libs in EMCC_FORCE_STDLIBS. This avoids spending time checking
# for unresolved symbols in your project files, which can speed up linking, but if you do not have
# the proper list of actually needed libraries, errors can occur. See below for how we must
# export all the symbols in deps_info when using this option.
only_forced = os.environ.get('EMCC_ONLY_FORCED_STDLIBS')
if only_forced:
# One of the purposes EMCC_ONLY_FORCED_STDLIBS was to skip the scanning
# of the input files for reverse dependencies.
diagnostics.warning('deprecated', 'EMCC_ONLY_FORCED_STDLIBS is deprecated. Use `-nostdlib` and/or `-s REVERSE_DEPS=none` depending on the desired result')
settings.REVERSE_DEPS = 'all'

handle_reverse_deps(input_files)

if settings.USE_WEBGPU:
add_library('libwebgpu_cpp')
libs_to_link = get_libs_to_link(args, forced, only_forced)

# When LINKABLE is set the entire link command line is wrapped in --whole-archive by
# building.link_ldd. And since --whole-archive/--no-whole-archive processing does not nest we
# shouldn't add any extra `--no-whole-archive` or we will undo the intent of building.link_ldd.
if settings.LINKABLE:
if settings.LINKABLE or settings.SIDE_MODULE:
return [l[0] for l in libs_to_link]

# Wrap libraries in --whole-archive, as needed. We need to do this last
Expand Down