Skip to content

Commit 395d737

Browse files
authored
Added first class citizen emscripten support (new wasm64 architecture + emcc) (#18432)
Changelog: Feature: Added first class citizen emscripten support (new wasm64 architecture + emcc) Docs: conan-io/docs#4115 Examples2: conan-io/examples2#184 This PR adds updated support to `wasm` (32 bits) and `asm.js` and introduces new architecture `wasm64`.
2 parents d1a8514 + 43769af commit 395d737

File tree

12 files changed

+240
-7
lines changed

12 files changed

+240
-7
lines changed

.ci/docker/conan-tests

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ ENV PY36=3.6.15 \
2525
CLANGXX_14=/usr/bin/clang++-14 \
2626
BAZEL_6=6.5.0 \
2727
BAZEL_7=7.4.1 \
28-
BAZEL_8=8.0.0
28+
BAZEL_8=8.0.0 \
29+
EMSDK=4.0.10
2930

3031
RUN apt-get update && \
3132
apt-get install -y --no-install-recommends \
@@ -169,6 +170,21 @@ RUN cd /tmp && \
169170
mv qbs-linux-x86_64-2.6.0 /usr/share/qbs && \
170171
rm qbs-linux-x86_64-2.6.0.tar.gz
171172

173+
RUN cd /tmp && \
174+
wget https://github.com/emscripten-core/emsdk/archive/refs/tags/${EMSDK}.tar.gz && \
175+
tar xzf ${EMSDK}.tar.gz --directory /usr/share && \
176+
cd /usr/share/emsdk-${EMSDK} && \
177+
./emsdk update && \
178+
./emsdk install latest && \
179+
./emsdk activate latest --permanent && \
180+
. /usr/share/emsdk-${EMSDK}/emsdk_env.sh && \
181+
embuilder build MINIMAL && \
182+
embuilder build MINIMAL --wasm64
183+
# echo "EMSDK_QUIET=1 . /usr/share/emsdk-${EMSDK}/emsdk_env.sh" >> /etc/bash.bashrc
184+
# Manually add the emsdk binaries to the PATH and set emcc cache directory to a writable location
185+
ENV PATH="/usr/share/emsdk-$EMSDK:/usr/share/emsdk-$EMSDK/upstream/emscripten:/usr/share/emsdk-$EMSDK/node/22.16.0_64bit/bin:$PATH" \
186+
EM_CACHE=$HOME/.emscripten_cache
187+
172188
RUN echo "export QT_NO_GLIB=1" >> /etc/profile.d/qt.sh
173189

174190
USER conan

.github/workflows/osx-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747

4848
- name: Install homebrew dependencies
4949
run: |
50-
brew install xcodegen make libtool zlib autoconf automake ninja
50+
brew install xcodegen make libtool zlib autoconf automake ninja emscripten
5151
5252
- name: Cache CMake and Bazel installations
5353
id: cache-tools
@@ -168,7 +168,7 @@ jobs:
168168
169169
- name: Install homebrew dependencies
170170
run: |
171-
brew install xcodegen make libtool zlib autoconf automake ninja
171+
brew install xcodegen make libtool zlib autoconf automake ninja emscripten
172172
export PATH=${HOME}/Applications/CMake/3.15.7/bin:$PATH:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin
173173
cmake --version
174174
bazel --version

conan/internal/default_settings.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64,
9292
armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, arm64ec,
9393
sparc, sparcv9,
94-
mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le,
94+
mips, mips64, avr, s390, s390x, asm.js, wasm, wasm64, sh4le,
9595
e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7,
9696
riscv64, riscv32,
9797
xtensalx6, xtensalx106, xtensalx7,
@@ -163,6 +163,13 @@
163163
version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]
164164
libcxx: [libstdc++, libstdc++11]
165165
cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
166+
emcc:
167+
# From https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md
168+
# There is no ABI compatibility guarantee between versions
169+
version: [ANY]
170+
libcxx: [null, libstdc++, libstdc++11, libc++]
171+
cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]
172+
cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]
166173
167174
build_type: [null, Debug, Release, RelWithDebInfo, MinSizeRel]
168175
"""

conan/tools/build/cppstd.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def supported_cppstd(conanfile, compiler=None, compiler_version=None):
104104
"clang": _clang_supported_cppstd,
105105
"mcst-lcc": _mcst_lcc_supported_cppstd,
106106
"qcc": _qcc_supported_cppstd,
107+
"emcc": _emcc_supported_cppstd,
107108
}.get(compiler)
108109
if func:
109110
return func(Version(compiler_version))
@@ -267,3 +268,16 @@ def _qcc_supported_cppstd(version):
267268
return ["98", "gnu98"]
268269
else:
269270
return ["98", "gnu98", "11", "gnu11", "14", "gnu14", "17", "gnu17"]
271+
272+
def _emcc_supported_cppstd(version):
273+
"""
274+
emcc is based on clang but follow different versioning scheme.
275+
"""
276+
if version <= "3.0.1":
277+
return _clang_supported_cppstd(Version("14"))
278+
if version <= "3.1.50":
279+
return _clang_supported_cppstd(Version("18"))
280+
if version <= "4.0.1":
281+
return _clang_supported_cppstd(Version("20"))
282+
# Since emcc 4.0.2 clang version is 21
283+
return _clang_supported_cppstd(Version("21"))

conan/tools/build/cstd.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ def supported_cstd(conanfile, compiler=None, compiler_version=None):
110110
"gcc": _gcc_supported_cstd,
111111
"msvc": _msvc_supported_cstd,
112112
"clang": _clang_supported_cstd,
113+
"emcc": _emcc_supported_cstd,
113114
}.get(compiler)
114115
if func:
115116
return func(Version(compiler_version))
@@ -190,3 +191,18 @@ def _clang_supported_cstd(version):
190191
if version < "18":
191192
return ["99", "gnu99", "11", "gnu11", "17", "gnu17"]
192193
return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]
194+
195+
def _emcc_supported_cstd(version):
196+
"""
197+
emcc is based on clang but follow different versioning scheme.
198+
"""
199+
if version <= "3.0.1":
200+
return _clang_supported_cstd(Version("14"))
201+
if version <= "3.1.50":
202+
return _clang_supported_cstd(Version("18"))
203+
if version <= "4.0.1":
204+
return _clang_supported_cstd(Version("20"))
205+
# Since emcc 4.0.2 clang version is 21
206+
return _clang_supported_cstd(Version("21"))
207+
208+

conan/tools/build/flags.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ def architecture_flag(conanfile):
6666
"e2k-v5": "-march=elbrus-v5",
6767
"e2k-v6": "-march=elbrus-v6",
6868
"e2k-v7": "-march=elbrus-v7"}.get(arch, "")
69+
elif compiler == "emcc":
70+
# Emscripten default output is WASM since 1.37.x (long time ago)
71+
if arch == "wasm64":
72+
return "-sMEMORY64=1"
73+
# Deactivate WASM output forcing asm.js output instead
74+
elif arch == "asm.js":
75+
return "-sWASM=0"
6976
return ""
7077

7178

@@ -78,7 +85,7 @@ def libcxx_flags(conanfile):
7885
if compiler == "apple-clang":
7986
# In apple-clang 2 only values atm are "libc++" and "libstdc++"
8087
lib = f'-stdlib={libcxx}'
81-
elif compiler == "clang" or compiler == "intel-cc":
88+
elif compiler in ("clang", "intel-cc", "emcc"):
8289
if libcxx == "libc++":
8390
lib = "-stdlib=libc++"
8491
elif libcxx == "libstdc++" or libcxx == "libstdc++11":
@@ -93,7 +100,7 @@ def libcxx_flags(conanfile):
93100
elif compiler == "qcc":
94101
lib = f'-Y _{libcxx}'
95102

96-
if compiler in ['clang', 'apple-clang', 'gcc']:
103+
if compiler in ['clang', 'apple-clang', 'gcc', 'emcc']:
97104
if libcxx == "libstdc++":
98105
stdlib11 = "_GLIBCXX_USE_CXX11_ABI=0"
99106
elif libcxx == "libstdc++11" and conanfile.conf.get("tools.gnu:define_libcxx11_abi",

conan/tools/gnu/get_gnu_triplet.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def _get_gnu_arch(os_, arch):
1010
"armv8.3": "aarch64",
1111
"asm.js": "asmjs",
1212
"wasm": "wasm32",
13+
"wasm64": "wasm64",
1314
}.get(arch, None)
1415

1516
if not machine:

conan/tools/meson/helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
'sparc': ('sparc', 'sparc', 'big'),
5050
'sparcv9': ('sparc64', 'sparc64', 'big'),
5151
'wasm': ('wasm32', 'wasm32', 'little'),
52+
'wasm64': ('wasm64', 'wasm64', 'little'),
5253
'x86': ('x86', 'x86', 'little'),
5354
'x86_64': ('x86_64', 'x86_64', 'little'),
5455
'riscv32': ('riscv32', 'riscv32', 'little'),

conan/tools/qbs/common.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
's390x': 's390x',
2727
'asm.js': None,
2828
'wasm': None,
29+
'wasm64': None,
2930
'sh4le': 'sh'
3031
}
3132

@@ -84,4 +85,4 @@
8485
'MT': 'static',
8586
'MDd': 'dynamic',
8687
'MTd': 'static',
87-
}
88+
}

test/conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@
190190
"path": {'Linux': '/usr/share/qbs/bin'}
191191
}
192192
},
193+
"emcc": {},
194+
"node": {},
193195
# TODO: Intel oneAPI is not installed in CI yet. Uncomment this line whenever it's done.
194196
# "intel_oneapi": {
195197
# "default": "2021.3",

0 commit comments

Comments
 (0)