diff options
-rw-r--r-- | mesonbuild/compilers/d.py | 21 | ||||
-rw-r--r-- | mesonbuild/environment.py | 142 |
2 files changed, 86 insertions, 77 deletions
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index c9e8b44..907aeec 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -413,11 +413,13 @@ class DCompiler(Compiler): } def __init__(self, exelist, version, for_machine: MachineChoice, - info: 'MachineInfo', arch, **kwargs): + info: 'MachineInfo', arch, is_cross, exe_wrapper, **kwargs): self.language = 'd' super().__init__(exelist, version, for_machine, info, **kwargs) self.id = 'unknown' self.arch = arch + self.exe_wrapper = exe_wrapper + self.is_cross = is_cross def sanity_check(self, work_dir, environment): source_name = os.path.join(work_dir, 'sanity.d') @@ -428,7 +430,14 @@ class DCompiler(Compiler): pc.wait() if pc.returncode != 0: raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string()) - if subprocess.call(output_name) != 0: + if self.is_cross: + if self.exe_wrapper is None: + # Can't check if the binaries run so we have to assume they do + return + cmdlist = self.exe_wrapper.get_command() + [output_name] + else: + cmdlist = [output_name] + if subprocess.call(cmdlist) != 0: raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string()) def needs_static_linker(self): @@ -602,8 +611,8 @@ class GnuDCompiler(DCompiler, GnuCompiler): LINKER_PREFIX = GnuCompiler.LINKER_PREFIX def __init__(self, exelist, version, for_machine: MachineChoice, - info: 'MachineInfo', arch, **kwargs): - DCompiler.__init__(self, exelist, version, for_machine, info, arch, **kwargs) + info: 'MachineInfo', is_cross, exe_wrapper, arch, **kwargs): + DCompiler.__init__(self, exelist, version, for_machine, info, is_cross, exe_wrapper, arch, **kwargs) self.id = 'gcc' default_warn_args = ['-Wall', '-Wdeprecated'] self.warn_args = {'0': [], @@ -651,7 +660,7 @@ class LLVMDCompiler(DmdLikeCompilerMixin, LinkerEnvVarsMixin, BasicLinkerIsCompi def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo', arch, **kwargs): - DCompiler.__init__(self, exelist, version, for_machine, info, arch, **kwargs) + DCompiler.__init__(self, exelist, version, for_machine, info, arch, False, None, **kwargs) self.id = 'llvm' self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt'] @@ -693,7 +702,7 @@ class DmdDCompiler(DmdLikeCompilerMixin, LinkerEnvVarsMixin, BasicLinkerIsCompil def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo', arch, **kwargs): - DCompiler.__init__(self, exelist, version, for_machine, info, arch, **kwargs) + DCompiler.__init__(self, exelist, version, for_machine, info, arch, False, None, **kwargs) self.id = 'dmd' self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt'] diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index f53f17f..0763e7d 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -1337,30 +1337,6 @@ class Environment: def detect_d_compiler(self, for_machine: MachineChoice): info = self.machines[for_machine] - exelist = self.binaries[for_machine].lookup_entry('d') - # Search for a D compiler. - # We prefer LDC over GDC unless overridden with the DC - # environment variable because LDC has a much more - # up to date language version at time (2016). - if exelist is not None: - if os.path.basename(exelist[-1]).startswith(('ldmd', 'gdmd')): - raise EnvironmentException( - 'Meson does not support {} as it is only a DMD frontend for another compiler.' - 'Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself.'.format(exelist[-1])) - else: - for d in self.default_d: - if shutil.which(d): - exelist = [d] - break - else: - raise EnvironmentException('Could not find any supported D compiler.') - - try: - p, out = Popen_safe(exelist + ['--version'])[0:2] - except OSError: - raise EnvironmentException('Could not execute D compiler "%s"' % ' '.join(exelist)) - version = search_version(out) - full_version = out.split('\n', 1)[0] # Detect the target architecture, required for proper architecture handling on Windows. c_compiler = {} @@ -1372,55 +1348,79 @@ class Environment: if is_msvc and arch == 'x86': arch = 'x86_mscoff' - if 'LLVM D compiler' in out: - # LDC seems to require a file - m = self.machines[for_machine] - if m.is_windows() or m.is_cygwin(): - if is_msvc: - linker = MSVCDynamicLinker(for_machine, version=version) + popen_exceptions = {} + is_cross = not self.machines.matches_build_machine(for_machine) + results, ccache, exe_wrap = self._get_compilers('d', for_machine) + for exelist in results: + # Search for a D compiler. + # We prefer LDC over GDC unless overridden with the DC + # environment variable because LDC has a much more + # up to date language version at time (2016). + if not isinstance(exelist, list): + exelist = [exelist] + if os.path.basename(exelist[-1]).startswith(('ldmd', 'gdmd')): + raise EnvironmentException( + 'Meson does not support {} as it is only a DMD frontend for another compiler.' + 'Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself.'.format(exelist[-1])) + try: + p, out = Popen_safe(exelist + ['--version'])[0:2] + except OSError as e: + popen_exceptions[' '.join(exelist + ['--version'])] = e + continue + version = search_version(out) + full_version = out.split('\n', 1)[0] + + if 'LLVM D compiler' in out: + # LDC seems to require a file + m = self.machines[for_machine] + if m.is_windows() or m.is_cygwin(): + if is_msvc: + linker = MSVCDynamicLinker(for_machine, version=version) + else: + # Getting LDC on windows to give useful linker output when not + # doing real work is painfully hard. It ships with a version of + # lld-link, so just assume that we're going to use lld-link + # with it. + _, o, _ = Popen_safe(['lld-link.exe', '--version']) + linker = ClangClDynamicLinker(for_machine, version=search_version(o)) else: - # Getting LDC on windows to give useful linker output when not - # doing real work is painfully hard. It ships with a version of - # lld-link, so just assume that we're going to use lld-link - # with it. - _, o, _ = Popen_safe(['lld-link.exe', '--version']) - linker = ClangClDynamicLinker(for_machine, version=search_version(o)) - else: - with tempfile.NamedTemporaryFile(suffix='.d') as f: - linker = self._guess_nix_linker( - exelist, for_machine, - compilers.LLVMDCompiler.LINKER_PREFIX, - extra_args=[f.name]) - return compilers.LLVMDCompiler( - exelist, version, for_machine, info, arch, - full_version=full_version, linker=linker) - elif 'gdc' in out: - linker = self._guess_nix_linker(exelist, for_machine, compilers.GnuDCompiler.LINKER_PREFIX) - return compilers.GnuDCompiler( - exelist, version, for_machine, info, arch, - full_version=full_version, linker=linker) - elif 'The D Language Foundation' in out or 'Digital Mars' in out: - # DMD seems to require a file - m = self.machines[for_machine] - if m.is_windows() or m.is_cygwin(): - if is_msvc: - linker = MSVCDynamicLinker(for_machine, version=version) - elif arch == 'x86': - linker = OptlinkDynamicLinker(for_machine, version=full_version) + with tempfile.NamedTemporaryFile(suffix='.d') as f: + linker = self._guess_nix_linker( + exelist, for_machine, + compilers.LLVMDCompiler.LINKER_PREFIX, + extra_args=[f.name]) + return compilers.LLVMDCompiler( + exelist, version, for_machine, info, arch, + full_version=full_version, linker=linker) + elif 'gdc' in out: + linker = self._guess_nix_linker(exelist, for_machine, compilers.GnuDCompiler.LINKER_PREFIX) + return compilers.GnuDCompiler( + exelist, version, for_machine, info, arch, is_cross, exe_wrap, + full_version=full_version, linker=linker) + elif 'The D Language Foundation' in out or 'Digital Mars' in out: + # DMD seems to require a file + m = self.machines[for_machine] + if m.is_windows() or m.is_cygwin(): + if is_msvc: + linker = MSVCDynamicLinker(for_machine, version=version) + elif arch == 'x86': + linker = OptlinkDynamicLinker(for_machine, version=full_version) + else: + # DMD ships with lld-link + _, o, _ = Popen_safe(['lld-link.exe', '--version']) + linker = ClangClDynamicLinker(for_machine, version=search_version(o)) else: - # DMD ships with lld-link - _, o, _ = Popen_safe(['lld-link.exe', '--version']) - linker = ClangClDynamicLinker(for_machine, version=search_version(o)) - else: - with tempfile.NamedTemporaryFile(suffix='.d') as f: - linker = self._guess_nix_linker( - exelist, for_machine, - compilers.LLVMDCompiler.LINKER_PREFIX, - extra_args=[f.name]) - return compilers.DmdDCompiler( - exelist, version, for_machine, info, arch, - full_version=full_version, linker=linker) - raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') + with tempfile.NamedTemporaryFile(suffix='.d') as f: + linker = self._guess_nix_linker( + exelist, for_machine, + compilers.LLVMDCompiler.LINKER_PREFIX, + extra_args=[f.name]) + return compilers.DmdDCompiler( + exelist, version, for_machine, info, arch, + full_version=full_version, linker=linker) + raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') + + self._handle_exceptions(popen_exceptions, compilers) def detect_swift_compiler(self, for_machine): exelist = self.binaries.host.lookup_entry('swift') |