-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathemscripten.jam
More file actions
192 lines (163 loc) · 8.5 KB
/
emscripten.jam
File metadata and controls
192 lines (163 loc) · 8.5 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# Copyright Nikita Kniazev
# Copyright Rene Rivera 2016
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt
# or copy at https://www.bfgroup.xyz/b2/LICENSE.txt)
#| tag::doc[]
[[b2.reference.tools.compiler.emscripten]]
= Emscripten
The `emscripten` module supports https://emscripten.org[Emscripten toolchain]
and has the same options as link:#b2.reference.tools.compiler.clang-linux[`clang-linux`]
toolset.
WARNING: Emscripten toolset defaults to static linkage because it is what
generally expected and limitations of the toolchain itself
(`wasm-ld` does not support `rpath`; js launcher does not respect
`LD_LIBRARY_PATH`/`PATH` when looking for shared objects).
Additional link:#b2.overview.invocation.properties[features]
supported by Emscripten toolset exclusively:
`debug-symbols-source-map`::
Setting to `on` will enable source map generation, more info could be found in
https://emscripten.org/docs/tools_reference/emcc.html#emcc-gsource-map[Emscripten documentation].
`exception-handling-method`::
Setting to `js` will result in using Emscripten’s JavaScript-based exception
support instead of native WebAssembly exception handling.
|# # end::doc[]
import feature ;
import os ;
import toolset ;
import common ;
import type ;
import version ;
import args ;
feature.extend toolset : emscripten ;
feature.feature embind : off on : propagated ;
feature.feature closure : off on full : propagated ;
feature.feature link-optimization : off on full : propagated ;
feature.subfeature debug-symbols : source-map : on : optional propagated ;
feature.subfeature exception-handling : demangle-support : on : optional propagated ;
feature.subfeature exception-handling : method : js : optional propagated link-incompatible ;
if [ args.get-arg debug-configuration ]
{
local rule .debug-configuration ( messages * )
{
ECHO "notice: [emscripten-cfg]" $(messages) ;
}
}
else
{
local rule .debug-configuration ( messages * ) { }
}
rule init ( version ? : command * : options * )
{
# On Windows 'emcc' calls emcc.bat but B2 will trip in CreateProcess if we
# let it call emcc because it does not work like a shell.
# We could make it call emcc.bat, but because gcc toolset quotes the command
# it will trip on cmd.exe bug, see https://github.com/bfgroup/b2/issues/309
if ! $(command) && [ os.name ] = NT {
command = [ common.get-absolute-tool-path emcc ] ;
if $(command) {
local python = [ os.environ EMSDK_PYTHON ] ;
python ?= py ;
command = $(python) $(command)\\emcc.py ;
}
}
command = [ common.get-invocation-command emscripten
: emcc
: $(command) ] ;
# Determine the version
local command-string = [ common.make-command-string $(command) ] ;
version = [ MATCH "([0-9.]+)" : [ SHELL "$(command-string) --version" ] ] ;
local condition = [ common.check-init-parameters emscripten
: version $(version) ] ;
local conditions = [ feature.split $(condition) ] ;
common.handle-options emscripten : $(condition) : $(command) : $(options) ;
.debug-configuration $(condition) ":: emcc ::" $(command) ;
local ar = [ feature.get-values <archiver> : $(options) ] ;
ar ?= $(command[1--2]) $(command[-1]:B=emar) ;
ar = [ common.get-invocation-command emscripten : emar : $(ar) ] ;
toolset.flags emscripten.archive .AR $(condition) : $(ar) ;
.debug-configuration $(condition) ":: archiver ::" $(ar) ;
local ProgramFiles ;
if [ os.name ] = NT {
ProgramFiles = [ os.environ "ProgramFiles" ] [ os.environ "ProgramFiles(x86)" ] ;
}
local nodejs = [ feature.get-values <nodejs> : $(options) ] ;
nodejs = [ common.get-invocation-command-nodefault emscripten : node : $(nodejs) : "$(ProgramFiles)\\nodejs" ] ;
if $(nodejs) {
local command-string = [ common.make-command-string $(nodejs) ] ;
local node-version = [ MATCH "v([0-9]+)" : [ SHELL "$(command-string) --version" ] ] ;
.debug-configuration $(condition) ":: nodejs version is" $(node-version:J=.) ;
if [ version.version-less $(node-version:E=0) : 16 ] {
toolset.add-defaults $(conditions:J=,)\:<exception-handling-method>js ;
}
local result = [ SHELL "$(command-string) --version --experimental-wasm-threads" : exit-status no-output ] ;
if $(result[2]) = 0 {
nodejs += --experimental-wasm-threads ;
}
}
nodejs ?= nodejs ;
import testing ;
toolset.flags testing LAUNCHER $(condition) : \"$(nodejs)\" : unchecked ;
.debug-configuration $(condition) ":: nodejs ::" $(nodejs) ;
version = [ SPLIT_BY_CHARACTERS $(version:E=0) : . ] ;
# The version number is a hard guess, I could not find when -pthread or -fwasm-exceptions were actually added
if [ version.version-less $(version[1]) : 2 ] {
toolset.add-requirements $(conditions:J=,)\:<exception-handling-method>js ;
}
# Workaround https://github.com/emscripten-core/emscripten/issues/19471
if [ version.version-less $(version) : 3 1 41 ] {
toolset.flags emscripten.compile OPTIONS $(condition)/<threading>multi : -sUSE_PTHREADS ;
}
if ! [ version.version-less $(version[1]) : 3 ] {
# bring back unsupported in v2 flags
toolset.flags emscripten.link FINDLIBS-ST-PFX $(condition)/<runtime-link>shared : -Wl,-Bstatic ;
toolset.flags emscripten.link FINDLIBS-SA-PFX $(condition)/<runtime-link>shared : -Wl,-Bdynamic ;
}
}
import clang-linux ;
toolset.inherit-generators emscripten : clang-linux ;
toolset.inherit-rules emscripten : clang-linux ;
toolset.inherit-flags emscripten : clang-linux : :
# emscripten barks on them being unsupported
RPATH_LINK
RPATH_OPTION
SONAME_OPTION
# supported only in v3, we reenable them conditionally in init
FINDLIBS-ST-PFX
FINDLIBS-SA-PFX
;
toolset.add-defaults <toolset>emscripten:<target-os>none ;
# dynamic linking is experemental and buggy
toolset.add-defaults <toolset>emscripten:<link>static ;
# Emscripten can produce different kinds of .js and .wasm outputs:
# -o .wasm produces a standalone .wasm executable.
# -o .js produces a .wasm executable that uses emscripten runtime and a .js launcher.
# -o .js -sSTANDALONE_WASM produces a standalone .wasm executable and a .js launcher.
type.set-generated-target-suffix EXE : <toolset>emscripten : js ;
toolset.flags emscripten.compile.c++ OPTIONS <exception-handling>on/<exception-handling-method>js : -fexceptions ;
toolset.flags emscripten.link OPTIONS <exception-handling>on/<exception-handling-method>js : -fexceptions ;
toolset.flags emscripten.compile.c++ OPTIONS <exception-handling>on/<exception-handling-method> : -fwasm-exceptions ;
toolset.flags emscripten.link OPTIONS <exception-handling>on/<exception-handling-method> : -fwasm-exceptions ;
# Emscripten support for shared libraries is incomplete, linker embeds direct
# dependencies into executable itself but do not embed transitive dependencies.
# We probably could workaround that in a custom linking generator which will add
# transitive dependencies via --preload-file/--embed-file, but it is a lot of work
# for a niche feature which should be fixed in the linker instead.
# There is -sNODERAWFS but LD_LIBRARY_PATH seems to only work for explicit dlopen.
import testing ;
# TODO: This is brittle and ugly, but currently there is no other way to specify flags for produced types by linker
local EXE_PRODUCING_TARGET_TYPES = EXE RUN_OUTPUT RUN RUN_FAIL UNIT_TEST ;
toolset.flags emscripten.link OPTIONS <link>shared/<main-target-type>$(EXE_PRODUCING_TARGET_TYPES) : -sMAIN_MODULE ;
toolset.flags emscripten.link SHARED_OPTION : -sSIDE_MODULE ;
toolset.flags emscripten.compile OPTIONS <profiling>on : --profiling-funcs ;
toolset.flags emscripten.link OPTIONS <exception-handling>on/<exception-handling-demangle-support>on : -sDEMANGLE_SUPPORT ;
toolset.flags emscripten.link OPTIONS <debug-symbols>on/<debug-symbols-source-map>on : -gsource-map ;
toolset.flags emscripten.link OPTIONS <embind>on : --bind ;
toolset.flags emscripten.link OPTIONS <closure>on : --closure 1 ;
toolset.flags emscripten.link OPTIONS <closure>full : --closure 2 ;
# things for old fastcomp backend which was removed in 2.0.0 (08/10/2020)
toolset.flags emscripten.link OPTIONS <link-optimization>on : --llvm-lto 1 ;
toolset.flags emscripten.link OPTIONS <link-optimization>full : --llvm-lto 3 ;
# Memory64/wasm64 support
toolset.flags emscripten.compile OPTIONS <address-model>64 : -sMEMORY64=1 ;
toolset.flags emscripten.link OPTIONS <address-model>64 : -sMEMORY64=1 ;