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