123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806 |
- # Copyright 2012-2017 The Meson development team
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- # http://www.apache.org/licenses/LICENSE-2.0
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import os.path, subprocess
- import typing as T
- from ..mesonlib import (
- EnvironmentException, MachineChoice, version_compare,
- )
- from .compilers import (
- d_dmd_buildtype_args,
- d_gdc_buildtype_args,
- d_ldc_buildtype_args,
- clike_debug_args,
- Compiler,
- CompilerArgs,
- )
- from .mixins.gnu import GnuCompiler
- if T.TYPE_CHECKING:
- from ..envconfig import MachineInfo
- d_feature_args = {'gcc': {'unittest': '-funittest',
- 'debug': '-fdebug',
- 'version': '-fversion',
- 'import_dir': '-J'
- },
- 'llvm': {'unittest': '-unittest',
- 'debug': '-d-debug',
- 'version': '-d-version',
- 'import_dir': '-J'
- },
- 'dmd': {'unittest': '-unittest',
- 'debug': '-debug',
- 'version': '-version',
- 'import_dir': '-J'
- }
- }
- ldc_optimization_args = {'0': [],
- 'g': [],
- '1': ['-O1'],
- '2': ['-O2'],
- '3': ['-O3'],
- 's': ['-Os'],
- }
- dmd_optimization_args = {'0': [],
- 'g': [],
- '1': ['-O'],
- '2': ['-O'],
- '3': ['-O'],
- 's': ['-O'],
- }
- class DmdLikeCompilerMixin:
- LINKER_PREFIX = '-L='
- def get_output_args(self, target):
- return ['-of=' + target]
- def get_linker_output_args(self, target):
- return ['-of=' + target]
- def get_include_args(self, path, is_system):
- return ['-I=' + path]
- def compute_parameters_with_absolute_paths(self, parameter_list, build_dir):
- for idx, i in enumerate(parameter_list):
- if i[:3] == '-I=':
- parameter_list[idx] = i[:3] + os.path.normpath(os.path.join(build_dir, i[3:]))
- if i[:4] == '-L-L':
- parameter_list[idx] = i[:4] + os.path.normpath(os.path.join(build_dir, i[4:]))
- if i[:5] == '-L=-L':
- parameter_list[idx] = i[:5] + os.path.normpath(os.path.join(build_dir, i[5:]))
- if i[:6] == '-Wl,-L':
- parameter_list[idx] = i[:6] + os.path.normpath(os.path.join(build_dir, i[6:]))
- return parameter_list
- def get_warn_args(self, level):
- return ['-wi']
- def get_werror_args(self):
- return ['-w']
- def get_dependency_gen_args(self, outtarget, outfile):
- # DMD and LDC does not currently return Makefile-compatible dependency info.
- return []
- def get_coverage_args(self):
- return ['-cov']
- def get_coverage_link_args(self):
- return []
- def get_preprocess_only_args(self):
- return ['-E']
- def get_compile_only_args(self):
- return ['-c']
- def depfile_for_object(self, objfile):
- return objfile + '.' + self.get_depfile_suffix()
- def get_depfile_suffix(self):
- return 'deps'
- def get_pic_args(self):
- if self.info.is_windows():
- return []
- return ['-fPIC']
- def get_feature_args(self, kwargs, build_to_src):
- res = []
- if 'unittest' in kwargs:
- unittest = kwargs.pop('unittest')
- unittest_arg = d_feature_args[self.id]['unittest']
- if not unittest_arg:
- raise EnvironmentException('D compiler %s does not support the "unittest" feature.' % self.name_string())
- if unittest:
- res.append(unittest_arg)
- if 'debug' in kwargs:
- debug_level = -1
- debugs = kwargs.pop('debug')
- if not isinstance(debugs, list):
- debugs = [debugs]
- debug_arg = d_feature_args[self.id]['debug']
- if not debug_arg:
- raise EnvironmentException('D compiler %s does not support conditional debug identifiers.' % self.name_string())
- # Parse all debug identifiers and the largest debug level identifier
- for d in debugs:
- if isinstance(d, int):
- if d > debug_level:
- debug_level = d
- elif isinstance(d, str) and d.isdigit():
- if int(d) > debug_level:
- debug_level = int(d)
- else:
- res.append('{0}={1}'.format(debug_arg, d))
- if debug_level >= 0:
- res.append('{0}={1}'.format(debug_arg, debug_level))
- if 'versions' in kwargs:
- version_level = -1
- versions = kwargs.pop('versions')
- if not isinstance(versions, list):
- versions = [versions]
- version_arg = d_feature_args[self.id]['version']
- if not version_arg:
- raise EnvironmentException('D compiler %s does not support conditional version identifiers.' % self.name_string())
- # Parse all version identifiers and the largest version level identifier
- for v in versions:
- if isinstance(v, int):
- if v > version_level:
- version_level = v
- elif isinstance(v, str) and v.isdigit():
- if int(v) > version_level:
- version_level = int(v)
- else:
- res.append('{0}={1}'.format(version_arg, v))
- if version_level >= 0:
- res.append('{0}={1}'.format(version_arg, version_level))
- if 'import_dirs' in kwargs:
- import_dirs = kwargs.pop('import_dirs')
- if not isinstance(import_dirs, list):
- import_dirs = [import_dirs]
- import_dir_arg = d_feature_args[self.id]['import_dir']
- if not import_dir_arg:
- raise EnvironmentException('D compiler %s does not support the "string import directories" feature.' % self.name_string())
- for idir_obj in import_dirs:
- basedir = idir_obj.get_curdir()
- for idir in idir_obj.get_incdirs():
- # Avoid superfluous '/.' at the end of paths when d is '.'
- if idir not in ('', '.'):
- expdir = os.path.join(basedir, idir)
- else:
- expdir = basedir
- srctreedir = os.path.join(build_to_src, expdir)
- res.append('{0}{1}'.format(import_dir_arg, srctreedir))
- if kwargs:
- raise EnvironmentException('Unknown D compiler feature(s) selected: %s' % ', '.join(kwargs.keys()))
- return res
- def get_buildtype_linker_args(self, buildtype):
- if buildtype != 'plain':
- return self.get_target_arch_args()
- return []
- def get_std_exe_link_args(self):
- return []
- def gen_import_library_args(self, implibname):
- return self.linker.import_library_args(implibname)
- def build_rpath_args(self, env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
- if self.info.is_windows():
- return []
- # GNU ld, solaris ld, and lld acting like GNU ld
- if self.linker.id.startswith('ld'):
- # The way that dmd and ldc pass rpath to gcc is different than we would
- # do directly, each argument -rpath and the value to rpath, need to be
- # split into two separate arguments both prefaced with the -L=.
- args = []
- for r in super().build_rpath_args(
- env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
- if ',' in r:
- a, b = r.split(',', maxsplit=1)
- args.append(a)
- args.append(self.LINKER_PREFIX + b)
- else:
- args.append(r)
- return args
- return super().build_rpath_args(
- env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
- def translate_args_to_nongnu(self, args):
- dcargs = []
- # Translate common arguments to flags the LDC/DMD compilers
- # can understand.
- # The flags might have been added by pkg-config files,
- # and are therefore out of the user's control.
- for arg in args:
- # Translate OS specific arguments first.
- osargs = []
- if self.info.is_windows():
- osargs = self.translate_arg_to_windows(arg)
- elif self.info.is_darwin():
- osargs = self.translate_arg_to_osx(arg)
- if osargs:
- dcargs.extend(osargs)
- continue
- # Translate common D arguments here.
- if arg == '-pthread':
- continue
- if arg.startswith('-fstack-protector'):
- continue
- if arg.startswith('-D'):
- continue
- if arg.startswith('-Wl,'):
- # Translate linker arguments here.
- linkargs = arg[arg.index(',') + 1:].split(',')
- for la in linkargs:
- dcargs.append('-L=' + la.strip())
- continue
- elif arg.startswith(('-link-defaultlib', '-linker', '-link-internally', '-linkonce-templates', '-lib')):
- # these are special arguments to the LDC linker call,
- # arguments like "-link-defaultlib-shared" do *not*
- # denote a library to be linked, but change the default
- # Phobos/DRuntime linking behavior, while "-linker" sets the
- # default linker.
- dcargs.append(arg)
- continue
- elif arg.startswith('-l'):
- # translate library link flag
- dcargs.append('-L=' + arg)
- continue
- elif arg.startswith('-isystem'):
- # translate -isystem system include path
- # this flag might sometimes be added by C library Cflags via
- # pkg-config.
- # NOTE: -isystem and -I are not 100% equivalent, so this is just
- # a workaround for the most common cases.
- if arg.startswith('-isystem='):
- dcargs.append('-I=' + arg[9:])
- else:
- dcargs.append('-I' + arg[8:])
- continue
- elif arg.startswith('-idirafter'):
- # same as -isystem, but appends the path instead
- if arg.startswith('-idirafter='):
- dcargs.append('-I=' + arg[11:])
- else:
- dcargs.append('-I' + arg[10:])
- continue
- elif arg.startswith('-L/') or arg.startswith('-L./'):
- # we need to handle cases where -L is set by e.g. a pkg-config
- # setting to select a linker search path. We can however not
- # unconditionally prefix '-L' with '-L' because the user might
- # have set this flag too to do what it is intended to for this
- # compiler (pass flag through to the linker)
- # Hence, we guess here whether the flag was intended to pass
- # a linker search path.
- # Make sure static library files are passed properly to the linker.
- if arg.endswith('.a') or arg.endswith('.lib'):
- if arg.startswith('-L='):
- farg = arg[3:]
- else:
- farg = arg[2:]
- if len(farg) > 0 and not farg.startswith('-'):
- dcargs.append('-L=' + farg)
- continue
- dcargs.append('-L=' + arg)
- continue
- elif not arg.startswith('-') and arg.endswith(('.a', '.lib')):
- # ensure static libraries are passed through to the linker
- dcargs.append('-L=' + arg)
- continue
- else:
- dcargs.append(arg)
- return dcargs
- @classmethod
- def translate_arg_to_windows(cls, arg):
- args = []
- if arg.startswith('-Wl,'):
- # Translate linker arguments here.
- linkargs = arg[arg.index(',') + 1:].split(',')
- for la in linkargs:
- if la.startswith('--out-implib='):
- # Import library name
- args.append('-L=/IMPLIB:' + la[13:].strip())
- elif arg.startswith('-mscrtlib='):
- args.append(arg)
- mscrtlib = arg[10:].lower()
- if cls is LLVMDCompiler:
- # Default crt libraries for LDC2 must be excluded for other
- # selected crt options.
- if mscrtlib != 'libcmt':
- args.append('-L=/NODEFAULTLIB:libcmt')
- args.append('-L=/NODEFAULTLIB:libvcruntime')
- # Fixes missing definitions for printf-functions in VS2017
- if mscrtlib.startswith('msvcrt'):
- args.append('-L=/DEFAULTLIB:legacy_stdio_definitions.lib')
- return args
- @classmethod
- def translate_arg_to_osx(cls, arg):
- args = []
- if arg.startswith('-install_name'):
- args.append('-L=' + arg)
- return args
- def get_debug_args(self, is_debug):
- ddebug_args = []
- if is_debug:
- ddebug_args = [d_feature_args[self.id]['debug']]
- return clike_debug_args[is_debug] + ddebug_args
- def get_crt_args(self, crt_val, buildtype):
- if not self.info.is_windows():
- return []
- if crt_val in self.mscrt_args:
- return self.mscrt_args[crt_val]
- assert(crt_val == 'from_buildtype')
- # Match what build type flags used to do.
- if buildtype == 'plain':
- return []
- elif buildtype == 'debug':
- return self.mscrt_args['mdd']
- elif buildtype == 'debugoptimized':
- return self.mscrt_args['md']
- elif buildtype == 'release':
- return self.mscrt_args['md']
- elif buildtype == 'minsize':
- return self.mscrt_args['md']
- else:
- assert(buildtype == 'custom')
- raise EnvironmentException('Requested C runtime based on buildtype, but buildtype is "custom".')
- def get_soname_args(self, *args, **kwargs) -> T.List[str]:
- # LDC and DMD actually do use a linker, but they proxy all of that with
- # their own arguments
- if self.linker.id.startswith('ld.'):
- soargs = []
- for arg in super().get_soname_args(*args, **kwargs):
- a, b = arg.split(',', maxsplit=1)
- soargs.append(a)
- soargs.append(self.LINKER_PREFIX + b)
- return soargs
- elif self.linker.id.startswith('ld64'):
- soargs = []
- for arg in super().get_soname_args(*args, **kwargs):
- if not arg.startswith(self.LINKER_PREFIX):
- soargs.append(self.LINKER_PREFIX + arg)
- else:
- soargs.append(arg)
- return soargs
- else:
- return super().get_soname_args(*args, **kwargs)
- def get_allow_undefined_link_args(self) -> T.List[str]:
- args = self.linker.get_allow_undefined_args()
- if self.info.is_darwin():
- # On macOS we're passing these options to the C compiler, but
- # they're linker options and need -Wl, so clang/gcc knows what to
- # do with them. I'm assuming, but don't know for certain, that
- # ldc/dmd do some kind of mapping internally for arguments they
- # understand, but pass arguments they don't understand directly.
- args = [a.replace('-L=', '-Xcc=-Wl,') for a in args]
- return args
- class DCompiler(Compiler):
- mscrt_args = {
- 'none': ['-mscrtlib='],
- 'md': ['-mscrtlib=msvcrt'],
- 'mdd': ['-mscrtlib=msvcrtd'],
- 'mt': ['-mscrtlib=libcmt'],
- 'mtd': ['-mscrtlib=libcmtd'],
- }
- language = 'd'
- def __init__(self, exelist, version, for_machine: MachineChoice,
- info: 'MachineInfo', arch, is_cross, exe_wrapper, **kwargs):
- 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')
- output_name = os.path.join(work_dir, 'dtest')
- with open(source_name, 'w') as ofile:
- ofile.write('''void main() { }''')
- pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + self.get_target_arch_args() + [source_name], cwd=work_dir)
- pc.wait()
- if pc.returncode != 0:
- raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string())
- 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):
- return True
- def depfile_for_object(self, objfile):
- return objfile + '.' + self.get_depfile_suffix()
- def get_depfile_suffix(self):
- return 'deps'
- def get_pic_args(self):
- if self.info.is_windows():
- return []
- return ['-fPIC']
- def get_feature_args(self, kwargs, build_to_src):
- res = []
- if 'unittest' in kwargs:
- unittest = kwargs.pop('unittest')
- unittest_arg = d_feature_args[self.id]['unittest']
- if not unittest_arg:
- raise EnvironmentException('D compiler %s does not support the "unittest" feature.' % self.name_string())
- if unittest:
- res.append(unittest_arg)
- if 'debug' in kwargs:
- debug_level = -1
- debugs = kwargs.pop('debug')
- if not isinstance(debugs, list):
- debugs = [debugs]
- debug_arg = d_feature_args[self.id]['debug']
- if not debug_arg:
- raise EnvironmentException('D compiler %s does not support conditional debug identifiers.' % self.name_string())
- # Parse all debug identifiers and the largest debug level identifier
- for d in debugs:
- if isinstance(d, int):
- if d > debug_level:
- debug_level = d
- elif isinstance(d, str) and d.isdigit():
- if int(d) > debug_level:
- debug_level = int(d)
- else:
- res.append('{0}={1}'.format(debug_arg, d))
- if debug_level >= 0:
- res.append('{0}={1}'.format(debug_arg, debug_level))
- if 'versions' in kwargs:
- version_level = -1
- versions = kwargs.pop('versions')
- if not isinstance(versions, list):
- versions = [versions]
- version_arg = d_feature_args[self.id]['version']
- if not version_arg:
- raise EnvironmentException('D compiler %s does not support conditional version identifiers.' % self.name_string())
- # Parse all version identifiers and the largest version level identifier
- for v in versions:
- if isinstance(v, int):
- if v > version_level:
- version_level = v
- elif isinstance(v, str) and v.isdigit():
- if int(v) > version_level:
- version_level = int(v)
- else:
- res.append('{0}={1}'.format(version_arg, v))
- if version_level >= 0:
- res.append('{0}={1}'.format(version_arg, version_level))
- if 'import_dirs' in kwargs:
- import_dirs = kwargs.pop('import_dirs')
- if not isinstance(import_dirs, list):
- import_dirs = [import_dirs]
- import_dir_arg = d_feature_args[self.id]['import_dir']
- if not import_dir_arg:
- raise EnvironmentException('D compiler %s does not support the "string import directories" feature.' % self.name_string())
- for idir_obj in import_dirs:
- basedir = idir_obj.get_curdir()
- for idir in idir_obj.get_incdirs():
- # Avoid superfluous '/.' at the end of paths when d is '.'
- if idir not in ('', '.'):
- expdir = os.path.join(basedir, idir)
- else:
- expdir = basedir
- srctreedir = os.path.join(build_to_src, expdir)
- res.append('{0}{1}'.format(import_dir_arg, srctreedir))
- if kwargs:
- raise EnvironmentException('Unknown D compiler feature(s) selected: %s' % ', '.join(kwargs.keys()))
- return res
- def get_buildtype_linker_args(self, buildtype):
- if buildtype != 'plain':
- return self.get_target_arch_args()
- return []
- def get_std_exe_link_args(self):
- return []
- def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
- if callable(extra_args):
- extra_args = extra_args(mode)
- if extra_args is None:
- extra_args = []
- elif isinstance(extra_args, str):
- extra_args = [extra_args]
- if dependencies is None:
- dependencies = []
- elif not isinstance(dependencies, list):
- dependencies = [dependencies]
- # Collect compiler arguments
- args = CompilerArgs(self)
- for d in dependencies:
- # Add compile flags needed by dependencies
- args += d.get_compile_args()
- if mode == 'link':
- # Add link flags needed to find dependencies
- args += d.get_link_args()
- if mode == 'compile':
- # Add DFLAGS from the env
- args += env.coredata.get_external_args(self.for_machine, self.language)
- elif mode == 'link':
- # Add LDFLAGS from the env
- args += env.coredata.get_external_link_args(self.for_machine, self.language)
- # extra_args must override all other arguments, so we add them last
- args += extra_args
- return args
- def compiles(self, code, env, *, extra_args=None, dependencies=None, mode='compile'):
- args = self._get_compiler_check_args(env, extra_args, dependencies, mode)
- with self.cached_compile(code, env.coredata, extra_args=args, mode=mode) as p:
- return p.returncode == 0, p.cached
- def has_multi_arguments(self, args, env):
- return self.compiles('int i;\n', env, extra_args=args)
- def get_target_arch_args(self):
- # LDC2 on Windows targets to current OS architecture, but
- # it should follow the target specified by the MSVC toolchain.
- if self.info.is_windows():
- if self.arch == 'x86_64':
- return ['-m64']
- return ['-m32']
- return []
- def get_crt_compile_args(self, crt_val, buildtype):
- return []
- def get_crt_link_args(self, crt_val, buildtype):
- return []
- def thread_link_flags(self, env):
- return self.linker.thread_flags(env)
- def name_string(self):
- return ' '.join(self.exelist)
- class GnuDCompiler(GnuCompiler, DCompiler):
- # we mostly want DCompiler, but that gives us the Compiler.LINKER_PREFIX instead
- LINKER_PREFIX = GnuCompiler.LINKER_PREFIX
- def __init__(self, exelist, version, for_machine: MachineChoice,
- info: 'MachineInfo', is_cross, exe_wrapper, arch, **kwargs):
- DCompiler.__init__(self, exelist, version, for_machine, info, is_cross, exe_wrapper, arch, **kwargs)
- GnuCompiler.__init__(self, {})
- self.id = 'gcc'
- default_warn_args = ['-Wall', '-Wdeprecated']
- self.warn_args = {'0': [],
- '1': default_warn_args,
- '2': default_warn_args + ['-Wextra'],
- '3': default_warn_args + ['-Wextra', '-Wpedantic']}
- self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic', 'b_vscrt', 'b_coverage']
- self._has_color_support = version_compare(self.version, '>=4.9')
- # dependencies were implemented before, but broken - support was fixed in GCC 7.1+
- # (and some backported versions)
- self._has_deps_support = version_compare(self.version, '>=7.1')
- def get_colorout_args(self, colortype):
- if self._has_color_support:
- super().get_colorout_args(colortype)
- return []
- def get_dependency_gen_args(self, outtarget, outfile):
- if self._has_deps_support:
- return super().get_dependency_gen_args(outtarget, outfile)
- return []
- def get_warn_args(self, level):
- return self.warn_args[level]
- def get_buildtype_args(self, buildtype):
- return d_gdc_buildtype_args[buildtype]
- def compute_parameters_with_absolute_paths(self, parameter_list, build_dir):
- for idx, i in enumerate(parameter_list):
- if i[:2] == '-I' or i[:2] == '-L':
- parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))
- return parameter_list
- def get_allow_undefined_link_args(self) -> T.List[str]:
- return self.linker.get_allow_undefined_args()
- def get_linker_always_args(self) -> T.List[str]:
- args = super().get_linker_always_args()
- if self.info.is_windows():
- return args
- return args + ['-shared-libphobos']
- class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler):
- def __init__(self, exelist, version, for_machine: MachineChoice,
- info: 'MachineInfo', 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']
- def get_colorout_args(self, colortype):
- if colortype == 'always':
- return ['-enable-color']
- return []
- def get_warn_args(self, level):
- if level == '2' or level == '3':
- return ['-wi', '-dw']
- elif level == '1':
- return ['-wi']
- else:
- return []
- def get_buildtype_args(self, buildtype):
- if buildtype != 'plain':
- return self.get_target_arch_args() + d_ldc_buildtype_args[buildtype]
- return d_ldc_buildtype_args[buildtype]
- def get_pic_args(self):
- return ['-relocation-model=pic']
- def get_crt_link_args(self, crt_val, buildtype):
- return self.get_crt_args(crt_val, buildtype)
- def unix_args_to_native(self, args):
- return self.translate_args_to_nongnu(args)
- def get_optimization_args(self, optimization_level):
- return ldc_optimization_args[optimization_level]
- @classmethod
- def use_linker_args(cls, linker: str) -> T.List[str]:
- return ['-linker={}'.format(linker)]
- def get_linker_always_args(self) -> T.List[str]:
- args = super().get_linker_always_args()
- if self.info.is_windows():
- return args
- return args + ['-link-defaultlib-shared']
- class DmdDCompiler(DmdLikeCompilerMixin, DCompiler):
- def __init__(self, exelist, version, for_machine: MachineChoice,
- info: 'MachineInfo', 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']
- def get_colorout_args(self, colortype):
- if colortype == 'always':
- return ['-color=on']
- return []
- def get_buildtype_args(self, buildtype):
- if buildtype != 'plain':
- return self.get_target_arch_args() + d_dmd_buildtype_args[buildtype]
- return d_dmd_buildtype_args[buildtype]
- def get_std_exe_link_args(self):
- if self.info.is_windows():
- # DMD links against D runtime only when main symbol is found,
- # so these needs to be inserted when linking static D libraries.
- if self.arch == 'x86_64':
- return ['phobos64.lib']
- elif self.arch == 'x86_mscoff':
- return ['phobos32mscoff.lib']
- return ['phobos.lib']
- return []
- def get_std_shared_lib_link_args(self):
- libname = 'libphobos2.so'
- if self.info.is_windows():
- if self.arch == 'x86_64':
- libname = 'phobos64.lib'
- elif self.arch == 'x86_mscoff':
- libname = 'phobos32mscoff.lib'
- else:
- libname = 'phobos.lib'
- return ['-shared', '-defaultlib=' + libname]
- def get_target_arch_args(self):
- # DMD32 and DMD64 on 64-bit Windows defaults to 32-bit (OMF).
- # Force the target to 64-bit in order to stay consistent
- # across the different platforms.
- if self.info.is_windows():
- if self.arch == 'x86_64':
- return ['-m64']
- elif self.arch == 'x86_mscoff':
- return ['-m32mscoff']
- return ['-m32']
- return []
- def get_crt_compile_args(self, crt_val, buildtype):
- return self.get_crt_args(crt_val, buildtype)
- def unix_args_to_native(self, args):
- return self.translate_args_to_nongnu(args)
- def get_optimization_args(self, optimization_level):
- return dmd_optimization_args[optimization_level]
- def can_linker_accept_rsp(self) -> bool:
- return False
- def get_linker_always_args(self) -> T.List[str]:
- args = super().get_linker_always_args()
- if self.info.is_windows():
- return args
- return args + ['-defaultlib=phobos2', '-debuglib=phobos2']
|