Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/tools/compile.py
4128 views
1
#!/usr/bin/env python3
2
# Copyright 2025 The Emscripten Authors. All rights reserved.
3
# Emscripten is available under two separate licenses, the MIT license and the
4
# University of Illinois/NCSA Open Source License. Both these licenses can be
5
# found in the LICENSE file.
6
7
"""The functions in this file define the compiler flags that emcc passes to clang.
8
9
There are three different levels of flags, each one a superset of the next:
10
11
get_target_flags(): Defines just `-target` flags and should always be
12
used when calling clang, or any other llvm tool.
13
14
get_clang_flags(): In addition to the target flags this function returns all the
15
required compiler flags.
16
17
get_cflags(): In addition to compiler flags this function also returns pre-processor
18
flags. For example, include paths and macro defintions.
19
"""
20
21
import os
22
23
from . cmdline import SIMD_INTEL_FEATURE_TOWER, SIMD_NEON_FLAGS
24
from . import shared, building, cache, ports
25
from . settings import settings
26
from . utils import memoize
27
28
29
def get_target_flags():
30
return ['-target', shared.get_llvm_target()]
31
32
33
def get_clang_flags(user_args):
34
flags = get_target_flags()
35
36
# if exception catching is disabled, we can prevent that code from being
37
# generated in the frontend
38
if settings.DISABLE_EXCEPTION_CATCHING and not settings.WASM_EXCEPTIONS:
39
flags.append('-fignore-exceptions')
40
41
if settings.INLINING_LIMIT:
42
flags.append('-fno-inline-functions')
43
44
if settings.PTHREADS:
45
if '-pthread' not in user_args:
46
flags.append('-pthread')
47
elif settings.SHARED_MEMORY:
48
if '-matomics' not in user_args:
49
flags.append('-matomics')
50
if '-mbulk-memory' not in user_args:
51
flags.append('-mbulk-memory')
52
53
if settings.RELOCATABLE and '-fPIC' not in user_args:
54
flags.append('-fPIC')
55
56
if settings.RELOCATABLE or settings.LINKABLE or '-fPIC' in user_args:
57
if not any(a.startswith('-fvisibility') for a in user_args):
58
# For relocatable code we default to visibility=default in emscripten even
59
# though the upstream backend defaults visibility=hidden. This matches the
60
# expectations of C/C++ code in the wild which expects undecorated symbols
61
# to be exported to other DSO's by default.
62
flags.append('-fvisibility=default')
63
64
if settings.LTO:
65
if not any(a.startswith('-flto') for a in user_args):
66
flags.append('-flto=' + settings.LTO)
67
# setjmp/longjmp handling using Wasm EH
68
# For non-LTO, '-mllvm -wasm-enable-eh' added in
69
# building.llvm_backend_args() sets this feature in clang. But in LTO, the
70
# argument is added to wasm-ld instead, so clang needs to know that EH is
71
# enabled so that it can be added to the attributes in LLVM IR.
72
if settings.SUPPORT_LONGJMP == 'wasm':
73
flags.append('-mexception-handling')
74
75
else:
76
# In LTO mode these args get passed instead at link time when the backend runs.
77
for a in building.llvm_backend_args():
78
flags += ['-mllvm', a]
79
80
return flags
81
82
83
@memoize
84
def get_cflags(user_args):
85
# Flags we pass to the compiler when building C/C++ code
86
# We add these to the user's flags (newargs), but not when building .s or .S assembly files
87
cflags = get_clang_flags(user_args)
88
cflags.append('--sysroot=' + cache.get_sysroot(absolute=True))
89
90
if settings.EMSCRIPTEN_TRACING:
91
cflags.append('-D__EMSCRIPTEN_TRACING__=1')
92
93
if settings.SHARED_MEMORY:
94
cflags.append('-D__EMSCRIPTEN_SHARED_MEMORY__=1')
95
96
if settings.WASM_WORKERS:
97
cflags.append('-D__EMSCRIPTEN_WASM_WORKERS__=1')
98
99
if not settings.STRICT:
100
# The preprocessor define EMSCRIPTEN is deprecated. Don't pass it to code
101
# in strict mode. Code should use the define __EMSCRIPTEN__ instead.
102
cflags.append('-DEMSCRIPTEN')
103
104
ports.add_cflags(cflags, settings)
105
106
def array_contains_any_of(hay, needles):
107
for n in needles:
108
if n in hay:
109
return True
110
111
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER) or array_contains_any_of(user_args, SIMD_NEON_FLAGS):
112
if '-msimd128' not in user_args and '-mrelaxed-simd' not in user_args:
113
shared.exit_with_error('passing any of ' + ', '.join(SIMD_INTEL_FEATURE_TOWER + SIMD_NEON_FLAGS) + ' flags also requires passing -msimd128 (or -mrelaxed-simd)!')
114
cflags += ['-D__SSE__=1']
115
116
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[1:]):
117
cflags += ['-D__SSE2__=1']
118
119
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[2:]):
120
cflags += ['-D__SSE3__=1']
121
122
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[3:]):
123
cflags += ['-D__SSSE3__=1']
124
125
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[4:]):
126
cflags += ['-D__SSE4_1__=1']
127
128
# Handle both -msse4.2 and its alias -msse4.
129
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[5:]):
130
cflags += ['-D__SSE4_2__=1']
131
132
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[7:]):
133
cflags += ['-D__AVX__=1']
134
135
if array_contains_any_of(user_args, SIMD_INTEL_FEATURE_TOWER[8:]):
136
cflags += ['-D__AVX2__=1']
137
138
if array_contains_any_of(user_args, SIMD_NEON_FLAGS):
139
cflags += ['-D__ARM_NEON__=1']
140
141
if '-nostdinc' not in user_args:
142
if not settings.USE_SDL:
143
cflags += ['-Xclang', '-iwithsysroot' + os.path.join('/include', 'fakesdl')]
144
cflags += ['-Xclang', '-iwithsysroot' + os.path.join('/include', 'compat')]
145
146
return cflags
147
148