compilers/linkers: Add a representation for wasm-ld

Emscripten does have a stand alone linker, wasm-ld. This patch adds the
linker, adds detection for the linker, and removes the IsLinkerMixin for
emscripten. This is a little more correct, and makes the code a lot
cleaner and more robust.
pull/6688/head
Dylan Baker 5 years ago
parent 771b0d3ffb
commit 654f427759
  1. 3
      docs/markdown/Reference-tables.md
  2. 5
      docs/markdown/snippets/wasm_ld.md
  3. 4
      mesonbuild/compilers/c.py
  4. 4
      mesonbuild/compilers/cpp.py
  5. 20
      mesonbuild/compilers/mixins/emscripten.py
  6. 12
      mesonbuild/environment.py
  7. 29
      mesonbuild/linkers.py

@ -37,10 +37,11 @@ These are return values of the `get_linker_id` method in a compiler object.
| Value | Linker family |
| ----- | --------------- |
| ld.bfd | The GNU linker |
| ld.bfd | The GNU linker |
| ld.gold | The GNU gold linker |
| ld.lld | The LLVM linker, with the GNU interface |
| ld.solaris | Solaris and illumos |
| ld.wasm | emscripten's wasm-ld linker |
| ld64 | Apple ld64 |
| link | MSVC linker |
| lld-link | The LLVM linker, with the MSVC interface |

@ -0,0 +1,5 @@
## Property support emscripten's wasm-ld
Before 0.54.0 we treated emscripten as both compiler and linker, which isn't
really true. It does have a linker, called wasm-ld (meson's name is ld.wasm).
This is a special version of clang's lld. This will now be detected properly.

@ -27,7 +27,7 @@ from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler
from .mixins.clang import ClangCompiler
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.islinker import BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin
from .mixins.islinker import LinkerEnvVarsMixin
from .mixins.emscripten import EmscriptenMixin
from .compilers import (
gnu_winlibs,
@ -133,7 +133,7 @@ class AppleClangCCompiler(ClangCCompiler):
_C18_VERSION = '>=11.0.0'
class EmscriptenCCompiler(EmscriptenMixin, BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin, ClangCCompiler):
class EmscriptenCCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCCompiler):
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs):
if not is_cross:

@ -36,7 +36,7 @@ from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler
from .mixins.clang import ClangCompiler
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.islinker import BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin
from .mixins.islinker import LinkerEnvVarsMixin
from .mixins.emscripten import EmscriptenMixin
if T.TYPE_CHECKING:
@ -201,7 +201,7 @@ class AppleClangCPPCompiler(ClangCPPCompiler):
pass
class EmscriptenCPPCompiler(EmscriptenMixin, BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin, ClangCPPCompiler):
class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompiler):
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs):
if not is_cross:

@ -18,7 +18,6 @@ import os.path
import typing as T
from ... import coredata
from ...mesonlib import MesonException
if T.TYPE_CHECKING:
from ..environment import Environment
@ -26,18 +25,6 @@ if T.TYPE_CHECKING:
class EmscriptenMixin:
def get_option_link_args(self, options):
return []
def get_soname_args(self, *args, **kwargs):
raise MesonException('Emscripten does not support shared libraries.')
def get_allow_undefined_link_args(self) -> T.List[str]:
return ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=0']
def get_linker_output_args(self, output: str) -> T.List[str]:
return ['-o', output]
def _get_compile_output(self, dirname, mode):
# In pre-processor mode, the output is sent to stdout and discarded
if mode == 'preprocess':
@ -54,13 +41,6 @@ class EmscriptenMixin:
def thread_flags(self, env: 'Environment') -> T.List[str]:
return ['-s', 'USE_PTHREADS=1']
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-s', 'USE_PTHREADS=1']
count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value # type: int
if count:
args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
return args
def get_options(self):
opts = super().get_options()
opts.update({

@ -58,6 +58,7 @@ from .linkers import (
XilinkDynamicLinker,
CudaLinker,
VisualStudioLikeLinkerMixin,
WASMDynamicLinker,
)
from functools import lru_cache
from .compilers import (
@ -957,9 +958,18 @@ class Environment:
if 'Emscripten' in out:
cls = EmscriptenCCompiler if lang == 'c' else EmscriptenCPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
# emcc cannot be queried to get the version out of it (it
# ignores -Wl,--version and doesn't have an alternative).
# Further, wasm-id *is* lld and will return `LLD X.Y.Z` if you
# call `wasm-ld --version`, but a special version of lld that
# takes different options.
p, o, _ = Popen_safe(['wasm-ld', '--version'])
linker = WASMDynamicLinker(
compiler, for_machine, cls.LINKER_PREFIX,
[], version=search_version(o))
return cls(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version)
exe_wrap, linker=linker, full_version=full_version)
if 'armclang' in out:
# The compiler version is not present in the first line of output,

@ -693,6 +693,35 @@ class LLVMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, Dyna
return []
class WASMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):
"""Emscripten's wasm-ld."""
def __init__(self, *args, **kwargs):
super().__init__('ld.wasm', *args, **kwargs)
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-s', 'USE_PTHREADS=1']
count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value # type: int
if count:
args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
return args
def get_allow_undefined_args(self) -> T.List[str]:
return ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=0']
def no_undefined_args(self) -> T.List[str]:
return ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=1']
def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
is_shared_module: bool) -> T.List[str]:
raise mesonlib.MesonException('{} does not support shared libraries.'.format(self.id))
def get_asneeded_args(self) -> T.List[str]:
return []
class CcrxDynamicLinker(DynamicLinker):
"""Linker for Renesis CCrx compiler."""

Loading…
Cancel
Save