summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2019-06-19 21:56:00 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2019-08-02 22:12:05 +0300
commit9251e3bf2ca607b3d6778c246c708916a29aaa88 (patch)
tree7b6dd0a509d6615e5a06f0529451d507b4685dd0
parentcba23413c58b2089ad752a358aafa3d06edaea4a (diff)
downloadmeson-wasm.tar.gz
Add basic Webassembly support via Emscripten.wasm
-rw-r--r--cross/wasm.txt19
-rw-r--r--docs/markdown/Reference-tables.md4
-rw-r--r--docs/markdown/snippets/wasm.md5
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/compilers/__init__.py2
-rw-r--r--mesonbuild/compilers/c.py25
-rw-r--r--mesonbuild/compilers/compilers.py1
-rw-r--r--mesonbuild/compilers/cpp.py35
-rw-r--r--mesonbuild/envconfig.py3
-rw-r--r--mesonbuild/environment.py7
-rw-r--r--mesonbuild/minstall.py7
-rw-r--r--test cases/wasm/1 basic/hello.cpp7
-rw-r--r--test cases/wasm/1 basic/hello.html8
-rw-r--r--test cases/wasm/1 basic/meson.build3
14 files changed, 127 insertions, 1 deletions
diff --git a/cross/wasm.txt b/cross/wasm.txt
new file mode 100644
index 000000000..a43636fde
--- /dev/null
+++ b/cross/wasm.txt
@@ -0,0 +1,19 @@
+[binaries]
+c = '/home/jpakkane/emsdk/fastcomp/emscripten/emcc'
+cpp = '/home/jpakkane/emsdk/fastcomp/emscripten/em++'
+ar = '/home/jpakkane/emsdk/fastcomp/emscripten/emar'
+
+[properties]
+
+c_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1']
+c_link_args = ['-s','EXPORT_ALL=1']
+cpp_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1']
+cpp_link_args = ['-s', 'EXPORT_ALL=1']
+
+[host_machine]
+
+system = 'emscripten'
+cpu_family = 'wasm32'
+cpu = 'wasm32'
+endian = 'little'
+
diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md
index 84ce06f41..41dd23852 100644
--- a/docs/markdown/Reference-tables.md
+++ b/docs/markdown/Reference-tables.md
@@ -13,6 +13,7 @@ These are return values of the `get_id` (Compiler family) and
| clang | The Clang compiler | gcc |
| clang-cl | The Clang compiler (MSVC compatible driver) | msvc |
| dmd | D lang reference compiler | |
+| emscripten| Emscripten WASM compiler | |
| flang | Flang Fortran compiler | |
| g95 | The G95 Fortran compiler | |
| gcc | The GNU Compiler Collection | gcc |
@@ -66,6 +67,8 @@ set in the cross file.
| s390x | IBM zSystem s390x |
| sparc | 32 bit SPARC |
| sparc64 | SPARC v9 processor |
+| wasm32 | 32 bit Webassembly |
+| wasm64 | 64 bit Webassembly |
| x86 | 32 bit x86 processor |
| x86_64 | 64 bit x86 processor |
@@ -86,6 +89,7 @@ These are provided by the `.system()` method call.
| cygwin | The Cygwin environment for Windows |
| darwin | Either OSX or iOS |
| dragonfly | DragonFly BSD |
+| emscripten | Emscripten's Javascript environment |
| freebsd | FreeBSD and its derivatives |
| gnu | GNU Hurd |
| haiku | |
diff --git a/docs/markdown/snippets/wasm.md b/docs/markdown/snippets/wasm.md
new file mode 100644
index 000000000..04fbf4916
--- /dev/null
+++ b/docs/markdown/snippets/wasm.md
@@ -0,0 +1,5 @@
+## Experimental Webassembly support via Emscripten
+
+Meson now supports compiling code to Webassembly using the Emscripten
+compiler. As with most things regarding Webassembly, this support is
+subject to change.
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index d5814ffd8..b77995ac2 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1432,6 +1432,8 @@ class Executable(BuildTarget):
# Executable for Windows or C#/Mono
if machine.is_windows() or machine.is_cygwin() or 'cs' in self.compilers:
self.suffix = 'exe'
+ elif machine.system.startswith('wasm') or machine.system == 'emscripten':
+ self.suffix = 'js'
elif ('c' in self.compilers and self.compilers['c'].get_id().startswith('arm') or
'cpp' in self.compilers and self.compilers['cpp'].get_id().startswith('arm')):
self.suffix = 'axf'
diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py
index 6d9e8148f..5cd56b871 100644
--- a/mesonbuild/compilers/__init__.py
+++ b/mesonbuild/compilers/__init__.py
@@ -126,6 +126,7 @@ from .c import (
ClangClCCompiler,
GnuCCompiler,
ElbrusCCompiler,
+ EmscriptenCCompiler,
IntelCCompiler,
IntelClCCompiler,
PGICCompiler,
@@ -140,6 +141,7 @@ from .cpp import (
ClangClCPPCompiler,
GnuCPPCompiler,
ElbrusCPPCompiler,
+ EmscriptenCPPCompiler,
IntelCPPCompiler,
IntelClCPPCompiler,
PGICPPCompiler,
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index eff716106..f50b77cdf 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -119,6 +119,31 @@ class ClangCCompiler(ClangCompiler, CCompiler):
return basic
+class EmscriptenCCompiler(ClangCCompiler):
+ def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
+ if not is_cross:
+ raise MesonException('Emscripten compiler can only be used for cross compilation.')
+ ClangCCompiler.__init__(self, exelist, version, compiler_type, for_machine, is_cross, exe_wrapper, **kwargs)
+ self.id = 'emscripten'
+
+ def get_option_link_args(self, options):
+ return []
+
+ def get_linker_always_args(self):
+ return []
+
+ def get_asneeded_args(self):
+ return []
+
+ def get_lundef_args(self):
+ return []
+
+ def build_rpath_args(self, *args, **kwargs):
+ return []
+
+ def get_soname_args(self, *args, **kwargs):
+ raise MesonException('Emscripten does not support shared libraries.')
+
class ArmclangCCompiler(ArmclangCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 3b61e6141..4502750ff 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1204,6 +1204,7 @@ class CompilerType(enum.Enum):
CLANG_STANDARD = 10
CLANG_OSX = 11
CLANG_MINGW = 12
+ CLANG_EMSCRIPTEN = 13
# Possibly clang-cl?
ICC_STANDARD = 20
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 6ae267323..5808b2e7c 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -131,7 +131,7 @@ class CPPCompiler(CLikeCompiler, Compiler):
}
# Currently, remapping is only supported for Clang, Elbrus and GCC
- assert(self.id in frozenset(['clang', 'lcc', 'gcc']))
+ assert(self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten']))
if cpp_std not in CPP_FALLBACKS:
# 'c++03' and 'c++98' don't have fallback types
@@ -183,6 +183,39 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
return ['-lstdc++']
+class EmscriptenCPPCompiler(ClangCPPCompiler):
+ def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
+ if not is_cross:
+ raise MesonException('Emscripten compiler can only be used for cross compilation.')
+ ClangCPPCompiler.__init__(self, exelist, version, compiler_type, for_machine, is_cross, exe_wrapper, **kwargs)
+ self.id = 'emscripten'
+
+ def get_option_compile_args(self, options):
+ args = []
+ std = options['cpp_std']
+ if std.value != 'none':
+ args.append(self._find_best_cpp_std(std.value))
+ return args
+
+ def get_option_link_args(self, options):
+ return []
+
+ def get_linker_always_args(self):
+ return []
+
+ def get_asneeded_args(self):
+ return []
+
+ def get_lundef_args(self):
+ return []
+
+ def build_rpath_args(self, *args, **kwargs):
+ return []
+
+ def get_soname_args(self, *args, **kwargs):
+ raise MesonException('Emscripten does not support shared libraries.')
+
+
class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py
index 011ab5d50..15d937b14 100644
--- a/mesonbuild/envconfig.py
+++ b/mesonbuild/envconfig.py
@@ -53,6 +53,8 @@ known_cpu_families = (
's390x',
'sparc',
'sparc64',
+ 'wasm32',
+ 'wasm64',
'x86',
'x86_64'
)
@@ -66,6 +68,7 @@ CPU_FAMILES_64_BIT = [
'ppc64',
'riscv64',
'sparc64',
+ 'wasm64',
'x86_64',
]
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 6c30fc197..096cd090f 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -60,6 +60,8 @@ from .compilers import (
ElbrusCCompiler,
ElbrusCPPCompiler,
ElbrusFortranCompiler,
+ EmscriptenCCompiler,
+ EmscriptenCPPCompiler,
IntelCCompiler,
IntelCPPCompiler,
IntelClCCompiler,
@@ -716,6 +718,11 @@ class Environment:
cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, defines, full_version=full_version)
+ if 'Emscripten' in out:
+ cls = EmscriptenCCompiler if lang == 'c' else EmscriptenCPPCompiler
+ compiler_type = CompilerType.CLANG_EMSCRIPTEN
+ return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
+
if 'armclang' in out:
# The compiler version is not present in the first line of output,
# instead it is present in second line, startswith 'Component:'.
diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py
index ed82c3791..8b0768e76 100644
--- a/mesonbuild/minstall.py
+++ b/mesonbuild/minstall.py
@@ -465,6 +465,13 @@ class Installer:
pdb_outname = os.path.splitext(outname)[0] + '.pdb'
self.do_copyfile(pdb_filename, pdb_outname)
set_mode(pdb_outname, install_mode, d.install_umask)
+ if fname.endswith('.js'):
+ # Emscripten outputs js files and optionally a wasm file.
+ # If one was generated, install it as well.
+ wasm_source = os.path.splitext(fname)[0] + '.wasm'
+ if os.path.exists(wasm_source):
+ wasm_output = os.path.splitext(outname)[0] + '.wasm'
+ self.do_copyfile(wasm_source, wasm_output)
elif os.path.isdir(fname):
fname = os.path.join(d.build_dir, fname.rstrip('/'))
outname = os.path.join(outdir, os.path.basename(fname))
diff --git a/test cases/wasm/1 basic/hello.cpp b/test cases/wasm/1 basic/hello.cpp
new file mode 100644
index 000000000..6ce13daef
--- /dev/null
+++ b/test cases/wasm/1 basic/hello.cpp
@@ -0,0 +1,7 @@
+#include<iostream>
+
+int main() {
+ std::cout << "Hello World" << std::endl;
+ return 0;
+}
+
diff --git a/test cases/wasm/1 basic/hello.html b/test cases/wasm/1 basic/hello.html
new file mode 100644
index 000000000..637bc2074
--- /dev/null
+++ b/test cases/wasm/1 basic/hello.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <script src="hello.js"></script>
+ </body>
+</html>
diff --git a/test cases/wasm/1 basic/meson.build b/test cases/wasm/1 basic/meson.build
new file mode 100644
index 000000000..8fe713c73
--- /dev/null
+++ b/test cases/wasm/1 basic/meson.build
@@ -0,0 +1,3 @@
+project('emcctest', 'cpp')
+
+executable('hello', 'hello.cpp')