Merge pull request #1853 from astavale/split-compilers-file

Split compilers file
pull/1912/merge
Jussi Pakkanen 8 years ago committed by GitHub
commit ce9cd33f27
  1. 16
      mesonbuild/backend/ninjabackend.py
  2. 3311
      mesonbuild/compilers.py
  3. 161
      mesonbuild/compilers/__init__.py
  4. 1007
      mesonbuild/compilers/c.py
  5. 1059
      mesonbuild/compilers/compilers.py
  6. 202
      mesonbuild/compilers/cpp.py
  7. 106
      mesonbuild/compilers/cs.py
  8. 324
      mesonbuild/compilers/d.py
  9. 289
      mesonbuild/compilers/fortran.py
  10. 115
      mesonbuild/compilers/java.py
  11. 64
      mesonbuild/compilers/objc.py
  12. 65
      mesonbuild/compilers/objcpp.py
  13. 59
      mesonbuild/compilers/rust.py
  14. 99
      mesonbuild/compilers/swift.py
  15. 90
      mesonbuild/compilers/vala.py
  16. 70
      mesonbuild/environment.py
  17. 114
      mesonbuild/linkers.py
  18. 1
      run_project_tests.py
  19. 8
      run_unittests.py

@ -1,4 +1,4 @@
# Copyright 2012-2016 The Meson development team
# 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.
@ -12,9 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import shlex
import os, sys, pickle, re
import subprocess, shutil
import os, pickle, re, shlex, shutil, subprocess, sys
from collections import OrderedDict
from . import backends
@ -25,6 +23,7 @@ from .. import mlog
from .. import dependencies
from .. import compilers
from ..compilers import CompilerArgs
from ..linkers import ArLinker
from ..mesonlib import File, MesonException, OrderedSet
from ..mesonlib import get_meson_script, get_compiler_for_source
from .backends import CleanTrees, InstallData
@ -1363,7 +1362,7 @@ int dummy;
# gcc-ar blindly pass the --plugin argument to `ar` and you cannot pass
# options as arguments while using the @file.rsp syntax.
# See: https://github.com/mesonbuild/meson/issues/1646
if mesonlib.is_windows() and not isinstance(static_linker, compilers.ArLinker):
if mesonlib.is_windows() and not isinstance(static_linker, ArLinker):
command_template = ''' command = {executable} @$out.rsp
rspfile = $out.rsp
rspfile_content = $LINK_ARGS {output_args} $in
@ -1375,7 +1374,7 @@ int dummy;
# them out to fix this properly on Windows. See:
# https://github.com/mesonbuild/meson/issues/1517
# https://github.com/mesonbuild/meson/issues/1526
if isinstance(static_linker, compilers.ArLinker) and not mesonlib.is_windows():
if isinstance(static_linker, ArLinker) and not mesonlib.is_windows():
# `ar` has no options to overwrite archives. It always appends,
# which is never what we want. Delete an existing library first if
# it exists. https://github.com/mesonbuild/meson/issues/1355
@ -2361,8 +2360,9 @@ rule FORTRAN_DEP_HACK
# Target names really should not have slashes in them, but
# unfortunately we did not check for that and some downstream projects
# now have them. Once slashes are forbidden, remove this bit.
target_slashname_workaround_dir = os.path.join(os.path.split(target.name)[0],
self.get_target_dir(target))
target_slashname_workaround_dir = os.path.join(
os.path.split(target.name)[0],
self.get_target_dir(target))
else:
target_slashname_workaround_dir = self.get_target_dir(target)
commands += linker.build_rpath_args(self.environment.get_build_dir(),

File diff suppressed because it is too large Load Diff

@ -0,0 +1,161 @@
# Copyright 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.
# Public symbols for compilers sub-package when using 'from . import compilers'
__all__ = [
'CLANG_OSX',
'CLANG_STANDARD',
'CLANG_WIN',
'GCC_CYGWIN',
'GCC_MINGW',
'GCC_OSX',
'GCC_STANDARD',
'ICC_OSX',
'ICC_STANDARD',
'ICC_WIN',
'base_options',
'clike_langs',
'c_suffixes',
'cpp_suffixes',
'get_base_compile_args',
'get_base_link_args',
'is_assembly',
'is_header',
'is_library',
'is_llvm_ir',
'is_object',
'is_source',
'lang_suffixes',
'sanitizer_compile_args',
'sort_clike',
'CCompiler',
'ClangCCompiler',
'ClangCompiler',
'ClangCPPCompiler',
'ClangObjCCompiler',
'ClangObjCPPCompiler',
'CompilerArgs',
'CPPCompiler',
'DCompiler',
'DmdDCompiler',
'FortranCompiler',
'G95FortranCompiler',
'GnuCCompiler',
'GnuCompiler',
'GnuCPPCompiler',
'GnuDCompiler',
'GnuFortranCompiler',
'GnuObjCCompiler',
'GnuObjCPPCompiler',
'IntelCompiler',
'IntelCCompiler',
'IntelCPPCompiler',
'IntelFortranCompiler',
'JavaCompiler',
'LLVMDCompiler',
'MonoCompiler',
'NAGFortranCompiler',
'ObjCCompiler',
'ObjCPPCompiler',
'Open64FortranCompiler',
'PathScaleFortranCompiler',
'PGIFortranCompiler',
'RustCompiler',
'SunFortranCompiler',
'SwiftCompiler',
'ValaCompiler',
'VisualStudioCCompiler',
'VisualStudioCPPCompiler',
]
# Bring symbols from each module into compilers sub-package namespace
from .compilers import (
GCC_OSX,
GCC_MINGW,
GCC_CYGWIN,
GCC_STANDARD,
CLANG_OSX,
CLANG_WIN,
CLANG_STANDARD,
ICC_OSX,
ICC_WIN,
ICC_STANDARD,
base_options,
clike_langs,
c_suffixes,
cpp_suffixes,
get_base_compile_args,
get_base_link_args,
is_header,
is_source,
is_assembly,
is_llvm_ir,
is_object,
is_library,
lang_suffixes,
sanitizer_compile_args,
sort_clike,
ClangCompiler,
CompilerArgs,
GnuCompiler,
IntelCompiler,
)
from .c import (
CCompiler,
ClangCCompiler,
GnuCCompiler,
IntelCCompiler,
VisualStudioCCompiler,
)
from .cpp import (
CPPCompiler,
ClangCPPCompiler,
GnuCPPCompiler,
IntelCPPCompiler,
VisualStudioCPPCompiler,
)
from .cs import MonoCompiler
from .d import (
DCompiler,
DmdDCompiler,
GnuDCompiler,
LLVMDCompiler,
)
from .fortran import (
FortranCompiler,
G95FortranCompiler,
GnuFortranCompiler,
IntelFortranCompiler,
NAGFortranCompiler,
Open64FortranCompiler,
PathScaleFortranCompiler,
PGIFortranCompiler,
SunFortranCompiler,
)
from .java import JavaCompiler
from .objc import (
ObjCCompiler,
ClangObjCCompiler,
GnuObjCCompiler,
)
from .objcpp import (
ObjCPPCompiler,
ClangObjCPPCompiler,
GnuObjCPPCompiler,
)
from .rust import RustCompiler
from .swift import SwiftCompiler
from .vala import ValaCompiler

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,202 @@
# 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.
from .. import coredata
from ..mesonlib import version_compare
from .c import CCompiler, VisualStudioCCompiler
from .compilers import (
GCC_MINGW,
gnu_winlibs,
msvc_winlibs,
ClangCompiler,
GnuCompiler,
IntelCompiler,
)
class CPPCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
# If a child ObjCPP class has already set it, don't set it ourselves
if not hasattr(self, 'language'):
self.language = 'cpp'
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def get_no_stdinc_args(self):
return ['-nostdinc++']
def sanity_check(self, work_dir, environment):
code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
def get_compiler_check_args(self):
# -fpermissive allows non-conforming code to compile which is necessary
# for many C++ checks. Particularly, the has_header_symbol check is
# too strict without this and always fails.
return super().get_compiler_check_args() + ['-fpermissive']
def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
# Check if it's a C-like symbol
if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
return True
# Check if it's a class or a template
if extra_args is None:
extra_args = []
fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
t = '''{prefix}
#include <{header}>
using {symbol};
int main () {{ return 0; }}'''
return self.compiles(t.format(**fargs), env, extra_args, dependencies)
class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
ClangCompiler.__init__(self, cltype)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
def get_options(self):
return {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++03', 'c++11', 'c++14', 'c++1z',
'gnu++11', 'gnu++14', 'gnu++1z'],
'none')}
def get_option_compile_args(self, options):
args = []
std = options['cpp_std']
if std.value != 'none':
args.append('-std=' + std.value)
return args
def get_option_link_args(self, options):
return []
class GnuCPPCompiler(GnuCompiler, CPPCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrap, defines):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
GnuCompiler.__init__(self, gcc_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
def get_options(self):
opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++03', 'c++11', 'c++14', 'c++1z',
'gnu++03', 'gnu++11', 'gnu++14', 'gnu++1z'],
'none'),
'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl',
'STL debug mode',
False)}
if self.gcc_type == GCC_MINGW:
opts.update({
'cpp_winlibs': coredata.UserStringArrayOption('cpp_winlibs', 'Standard Win libraries to link against',
gnu_winlibs), })
return opts
def get_option_compile_args(self, options):
args = []
std = options['cpp_std']
if std.value != 'none':
args.append('-std=' + std.value)
if options['cpp_debugstl'].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
def get_option_link_args(self, options):
if self.gcc_type == GCC_MINGW:
return options['cpp_winlibs'].value[:]
return []
class IntelCPPCompiler(IntelCompiler, CPPCompiler):
def __init__(self, exelist, version, icc_type, is_cross, exe_wrap):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
IntelCompiler.__init__(self, icc_type)
self.lang_header = 'c++-header'
default_warn_args = ['-Wall', '-w3', '-diag-disable:remark',
'-Wpch-messages', '-Wnon-virtual-dtor']
self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
def get_options(self):
c_stds = []
g_stds = ['gnu++98']
if version_compare(self.version, '>=15.0.0'):
c_stds += ['c++11', 'c++14']
g_stds += ['gnu++11']
if version_compare(self.version, '>=16.0.0'):
c_stds += ['c++17']
if version_compare(self.version, '>=17.0.0'):
g_stds += ['gnu++14']
opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none'] + c_stds + g_stds,
'none'),
'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl',
'STL debug mode',
False)}
return opts
def get_option_compile_args(self, options):
args = []
std = options['cpp_std']
if std.value != 'none':
args.append('-std=' + std.value)
if options['cpp_debugstl'].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
def get_option_link_args(self, options):
return []
def has_multi_arguments(self, args, env):
return super().has_multi_arguments(args + ['-diag-error', '10006'], env)
class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'cpp'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
def get_options(self):
return {'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'a', 's', 'sc'],
'sc'),
'cpp_winlibs': coredata.UserStringArrayOption('cpp_winlibs',
'Windows libs to link against.',
msvc_winlibs)
}
def get_option_compile_args(self, options):
args = []
std = options['cpp_eh']
if std.value != 'none':
args.append('/EH' + std.value)
return args
def get_option_link_args(self, options):
return options['cpp_winlibs'].value[:]
def get_compiler_check_args(self):
# Visual Studio C++ compiler doesn't support -fpermissive,
# so just use the plain C args.
return super(VisualStudioCCompiler, self).get_compiler_check_args()

@ -0,0 +1,106 @@
# 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
from ..mesonlib import EnvironmentException
from .compilers import Compiler, mono_buildtype_args
class MonoCompiler(Compiler):
def __init__(self, exelist, version):
self.language = 'cs'
super().__init__(exelist, version)
self.id = 'mono'
self.monorunner = 'mono'
def get_output_args(self, fname):
return ['-out:' + fname]
def get_link_args(self, fname):
return ['-r:' + fname]
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
return []
def get_werror_args(self):
return ['-warnaserror']
def split_shlib_to_parts(self, fname):
return None, fname
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return []
def get_dependency_gen_args(self, outtarget, outfile):
return []
def get_linker_exelist(self):
return self.exelist[:]
def get_compile_only_args(self):
return []
def get_linker_output_args(self, outputname):
return []
def get_coverage_args(self):
return []
def get_coverage_link_args(self):
return []
def get_std_exe_link_args(self):
return []
def get_include_args(self, path):
return []
def get_pic_args(self):
return []
def name_string(self):
return ' '.join(self.exelist)
def get_pch_use_args(self, pch_dir, header):
return []
def get_pch_name(self, header_name):
return ''
def sanity_check(self, work_dir, environment):
src = 'sanity.cs'
obj = 'sanity.exe'
source_name = os.path.join(work_dir, src)
with open(source_name, 'w') as ofile:
ofile.write('''public class Sanity {
static public void Main () {
}
}
''')
pc = subprocess.Popen(self.exelist + [src], cwd=work_dir)
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Mono compiler %s can not compile programs.' % self.name_string())
cmdlist = [self.monorunner, obj]
pe = subprocess.Popen(cmdlist, cwd=work_dir)
pe.wait()
if pe.returncode != 0:
raise EnvironmentException('Executables created by Mono compiler %s are not runnable.' % self.name_string())
def needs_static_linker(self):
return False
def get_buildtype_args(self, buildtype):
return mono_buildtype_args[buildtype]

@ -0,0 +1,324 @@
# 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
from ..mesonlib import EnvironmentException, version_compare
from .compilers import (
GCC_STANDARD,
d_dmd_buildtype_args,
d_gdc_buildtype_args,
d_ldc_buildtype_args,
get_gcc_soname_args,
gnu_color_args,
Compiler,
CompilerArgs,
)
class DCompiler(Compiler):
def __init__(self, exelist, version, is_cross):
self.language = 'd'
super().__init__(exelist, version)
self.id = 'unknown'
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) + [source_name], cwd=work_dir)
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string())
if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string())
def needs_static_linker(self):
return True
def name_string(self):
return ' '.join(self.exelist)
def get_linker_exelist(self):
return self.exelist[:]
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 'dep'
def get_pic_args(self):
return ['-fPIC']
def get_std_shared_lib_link_args(self):
return ['-shared']
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
# FIXME: Make this work for Windows, MacOS and cross-compiling
return get_gcc_soname_args(GCC_STANDARD, prefix, shlib_name, suffix, path, soversion, is_shared_module)
def get_unittest_args(self):
return ['-unittest']
def get_buildtype_linker_args(self, buildtype):
return []
def get_std_exe_link_args(self):
return []
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
# This method is to be used by LDC and DMD.
# GDC can deal with the verbatim flags.
if not rpath_paths and not install_rpath:
return []
paths = ':'.join([os.path.join(build_dir, p) for p in rpath_paths])
if len(paths) < len(install_rpath):
padding = 'X' * (len(install_rpath) - len(paths))
if not paths:
paths = padding
else:
paths = paths + ':' + padding
return ['-L-rpath={}'.format(paths)]
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
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.external_args[self.language]
elif mode == 'link':
# Add LDFLAGS from the env
args += env.coredata.external_link_args[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.compile(code, args, mode) as p:
return p.returncode == 0
def has_multi_arguments(self, args, env):
return self.compiles('int i;\n', env, extra_args=args)
@classmethod
def translate_args_to_nongnu(cls, 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:
if arg == '-pthread':
continue
if arg.startswith('-Wl,'):
linkargs = arg[arg.index(',') + 1:].split(',')
for la in linkargs:
dcargs.append('-L' + la.strip())
continue
elif arg.startswith('-l'):
# translate library link flag
dcargs.append('-L' + arg)
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.
dcargs.append('-L' + arg)
continue
dcargs.append(arg)
return dcargs
class GnuDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross):
DCompiler.__init__(self, exelist, version, is_cross)
self.id = 'gcc'
default_warn_args = ['-Wall', '-Wdeprecated']
self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic']
def get_colorout_args(self, colortype):
if version_compare(self.version, '>=4.9.0'):
return gnu_color_args[colortype][:]
return []
def get_dependency_gen_args(self, outtarget, outfile):
return ['-fmake-deps=' + outfile]
def get_output_args(self, target):
return ['-o', target]
def get_linker_output_args(self, target):
return ['-o', target]
def get_include_args(self, path, is_system):
return ['-I' + path]
def get_warn_args(self, level):
return self.warn_args[level]
def get_werror_args(self):
return ['-Werror']
def get_linker_search_args(self, dirname):
return ['-L' + dirname]
def get_buildtype_args(self, buildtype):
return d_gdc_buildtype_args[buildtype]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath)
def get_unittest_args(self):
return ['-funittest']
class LLVMDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross):
DCompiler.__init__(self, exelist, version, is_cross)
self.id = 'llvm'
self.base_options = ['b_coverage', 'b_colorout']
def get_colorout_args(self, colortype):
if colortype == 'always':
return ['-enable-color']
return []
def get_dependency_gen_args(self, outtarget, outfile):
# LDC using the -deps flag returns a non-Makefile dependency-info file, which
# the backends can not use. So we disable this feature for now.
return []
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 get_warn_args(self, level):
if level == '2' or level == '3':
return ['-wi', '-dw']
else:
return ['-wi']
def get_werror_args(self):
return ['-w']
def get_coverage_args(self):
return ['-cov']
def get_buildtype_args(self, buildtype):
return d_ldc_buildtype_args[buildtype]
def get_pic_args(self):
return ['-relocation-model=pic']
def get_linker_search_args(self, dirname):
# -L is recognized as "add this to the search path" by the linker,
# while the compiler recognizes it as "pass to linker". So, the first
# -L is for the compiler, telling it to pass the second -L to the linker.
return ['-L-L' + dirname]
@classmethod
def unix_args_to_native(cls, args):
return cls.translate_args_to_nongnu(args)
class DmdDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross):
DCompiler.__init__(self, exelist, version, is_cross)
self.id = 'dmd'
self.base_options = ['b_coverage', 'b_colorout']
def get_colorout_args(self, colortype):
if colortype == 'always':
return ['-color=on']
return []
def get_dependency_gen_args(self, outtarget, outfile):
# LDC using the -deps flag returns a non-Makefile dependency-info file, which
# the backends can not use. So we disable this feature for now.
return []
def get_output_args(self, target):
return ['-of' + target]
def get_werror_args(self):
return ['-w']
def get_linker_output_args(self, target):
return ['-of' + target]
def get_include_args(self, path, is_system):
return ['-I' + path]
def get_warn_args(self, level):
return ['-wi']
def get_coverage_args(self):
return ['-cov']
def get_linker_search_args(self, dirname):
# -L is recognized as "add this to the search path" by the linker,
# while the compiler recognizes it as "pass to linker". So, the first
# -L is for the compiler, telling it to pass the second -L to the linker.
return ['-L-L' + dirname]
def get_buildtype_args(self, buildtype):
return d_dmd_buildtype_args[buildtype]
def get_std_shared_lib_link_args(self):
return ['-shared', '-defaultlib=libphobos2.so']
@classmethod
def unix_args_to_native(cls, args):
return cls.translate_args_to_nongnu(args)

@ -0,0 +1,289 @@
# 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
from ..mesonlib import EnvironmentException, is_osx
from .compilers import (
GCC_CYGWIN,
GCC_MINGW,
GCC_OSX,
GCC_STANDARD,
ICC_STANDARD,
apple_buildtype_linker_args,
get_gcc_soname_args,
gnulike_buildtype_args,
gnulike_buildtype_linker_args,
Compiler,
IntelCompiler,
)
class FortranCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
self.language = 'fortran'
super().__init__(exelist, version)
self.is_cross = is_cross
self.exe_wrapper = exe_wrapper
# Not really correct but I don't have Fortran compilers to test with. Sorry.
self.gcc_type = GCC_STANDARD
self.id = "IMPLEMENTATION CLASSES MUST SET THIS"
def name_string(self):
return ' '.join(self.exelist)
def get_pic_args(self):
if self.gcc_type in (GCC_CYGWIN, GCC_MINGW, GCC_OSX):
return [] # On Window and OS X, pic is always on.
return ['-fPIC']
def get_std_shared_lib_link_args(self):
return ['-shared']
def needs_static_linker(self):
return True
def sanity_check(self, work_dir, environment):
source_name = os.path.join(work_dir, 'sanitycheckf.f90')
binary_name = os.path.join(work_dir, 'sanitycheckf')
with open(source_name, 'w') as ofile:
ofile.write('''program prog
print *, "Fortran compilation is working."
end program prog
''')
extra_flags = self.get_cross_extra_flags(environment, link=True)
pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('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 + [binary_name]
else:
cmdlist = [binary_name]
pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
pe.wait()
if pe.returncode != 0:
raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
def get_std_warn_args(self, level):
return FortranCompiler.std_warn_args
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
def get_buildtype_linker_args(self, buildtype):
if is_osx():
return apple_buildtype_linker_args[buildtype]
return gnulike_buildtype_linker_args[buildtype]
def split_shlib_to_parts(self, fname):
return os.path.split(fname)[0], fname
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
return get_gcc_soname_args(self.gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module)
def get_dependency_gen_args(self, outtarget, outfile):
# Disabled until this is fixed:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62162
# return ['-cpp', '-MMD', '-MQ', outtarget]
return []
def get_output_args(self, target):
return ['-o', target]
def get_preprocess_only_args(self):
return ['-E']
def get_compile_only_args(self):
return ['-c']
def get_linker_exelist(self):
return self.exelist[:]
def get_linker_output_args(self, outputname):
return ['-o', outputname]
def get_include_args(self, path, is_system):
return ['-I' + path]
def get_module_outdir_args(self, path):
return ['-J' + path]
def depfile_for_object(self, objfile):
return objfile + '.' + self.get_depfile_suffix()
def get_depfile_suffix(self):
return 'd'
def get_std_exe_link_args(self):
return []
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath)
def module_name_to_filename(self, module_name):
return module_name.lower() + '.mod'
def get_warn_args(self, level):
return ['-Wall']
def get_no_warn_args(self):
return ['-w']
class GnuFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.gcc_type = gcc_type
self.defines = defines or {}
self.id = 'gcc'
def has_builtin_define(self, define):
return define in self.defines
def get_builtin_define(self, define):
if define in self.defines:
return self.defines[define]
def get_always_args(self):
return ['-pipe']
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
Used only on Windows
"""
return ['-Wl,--out-implib=' + implibname]
class G95FortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'g95'
def get_module_outdir_args(self, path):
return ['-fmod=' + path]
def get_always_args(self):
return ['-pipe']
def get_no_warn_args(self):
# FIXME: Confirm that there's no compiler option to disable all warnings
return []
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
Used only on Windows
"""
return ['-Wl,--out-implib=' + implibname]
class SunFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'sun'
def get_dependency_gen_args(self, outtarget, outfile):
return ['-fpp']
def get_always_args(self):
return []
def get_warn_args(self, level):
return []
def get_module_outdir_args(self, path):
return ['-moddir=' + path]
class IntelFortranCompiler(IntelCompiler, FortranCompiler):
std_warn_args = ['-warn', 'all']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
self.file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp')
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
# FIXME: Add support for OS X and Windows in detect_fortran_compiler so
# we are sent the type of compiler
IntelCompiler.__init__(self, ICC_STANDARD)
self.id = 'intel'
def get_module_outdir_args(self, path):
return ['-module', path]
def get_warn_args(self, level):
return IntelFortranCompiler.std_warn_args
class PathScaleFortranCompiler(FortranCompiler):
std_warn_args = ['-fullwarn']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'pathscale'
def get_module_outdir_args(self, path):
return ['-module', path]
def get_std_warn_args(self, level):
return PathScaleFortranCompiler.std_warn_args
class PGIFortranCompiler(FortranCompiler):
std_warn_args = ['-Minform=inform']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'pgi'
def get_module_outdir_args(self, path):
return ['-module', path]
def get_warn_args(self, level):
return PGIFortranCompiler.std_warn_args
def get_no_warn_args(self):
return ['-silent']
class Open64FortranCompiler(FortranCompiler):
std_warn_args = ['-fullwarn']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'open64'
def get_module_outdir_args(self, path):
return ['-module', path]
def get_warn_args(self, level):
return Open64FortranCompiler.std_warn_args
class NAGFortranCompiler(FortranCompiler):
std_warn_args = []
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'nagfor'
def get_module_outdir_args(self, path):
return ['-mdir', path]
def get_warn_args(self, level):
return NAGFortranCompiler.std_warn_args

@ -0,0 +1,115 @@
# 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, shutil, subprocess
from ..mesonlib import EnvironmentException
from .compilers import Compiler, java_buildtype_args
class JavaCompiler(Compiler):
def __init__(self, exelist, version):
self.language = 'java'
super().__init__(exelist, version)
self.id = 'unknown'
self.javarunner = 'java'
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
return []
def get_werror_args(self):
return ['-Werror']
def split_shlib_to_parts(self, fname):
return None, fname
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return []
def get_dependency_gen_args(self, outtarget, outfile):
return []
def get_linker_exelist(self):
return self.exelist[:]
def get_compile_only_args(self):
return []
def get_output_args(self, subdir):
if subdir == '':
subdir = './'
return ['-d', subdir, '-s', subdir]
def get_linker_output_args(self, outputname):
return []
def get_coverage_args(self):
return []
def get_coverage_link_args(self):
return []
def get_std_exe_link_args(self):
return []
def get_include_args(self, path):
return []
def get_pic_args(self):
return []
def name_string(self):
return ' '.join(self.exelist)
def get_pch_use_args(self, pch_dir, header):
return []
def get_pch_name(self, header_name):
return ''
def get_buildtype_args(self, buildtype):
return java_buildtype_args[buildtype]
def sanity_check(self, work_dir, environment):
src = 'SanityCheck.java'
obj = 'SanityCheck'
source_name = os.path.join(work_dir, src)
with open(source_name, 'w') as ofile:
ofile.write('''class SanityCheck {
public static void main(String[] args) {
int i;
}
}
''')
pc = subprocess.Popen(self.exelist + [src], cwd=work_dir)
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Java compiler %s can not compile programs.' % self.name_string())
runner = shutil.which(self.javarunner)
if runner:
cmdlist = [runner, obj]
pe = subprocess.Popen(cmdlist, cwd=work_dir)
pe.wait()
if pe.returncode != 0:
raise EnvironmentException('Executables created by Java compiler %s are not runnable.' % self.name_string())
else:
m = "Java Virtual Machine wasn't found, but it's needed by Meson. " \
"Please install a JRE.\nIf you have specific needs where this " \
"requirement doesn't make sense, please open a bug at " \
"https://github.com/mesonbuild/meson/issues/new and tell us " \
"all about it."
raise EnvironmentException(m)
def needs_static_linker(self):
return False

@ -0,0 +1,64 @@
# 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
from ..mesonlib import EnvironmentException
from .c import CCompiler
from .compilers import ClangCompiler, GnuCompiler
class ObjCCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'objc'
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def sanity_check(self, work_dir, environment):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjc.m')
binary_name = os.path.join(work_dir, 'sanitycheckobjc')
extra_flags = self.get_cross_extra_flags(environment, link=False)
if self.is_cross:
extra_flags += self.get_compile_only_args()
with open(source_name, 'w') as ofile:
ofile.write('#import<stdio.h>\n'
'int main(int argc, char **argv) { return 0; }\n')
pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('ObjC compiler %s can not compile programs.' % self.name_string())
if self.is_cross:
# Can't check if the binaries run so we have to assume they do
return
pe = subprocess.Popen(binary_name)
pe.wait()
if pe.returncode != 0:
raise EnvironmentException('Executables created by ObjC compiler %s are not runnable.' % self.name_string())
class GnuObjCCompiler(GnuCompiler, ObjCCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
GnuCompiler.__init__(self, gcc_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch']
self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
class ClangObjCCompiler(ClangCompiler, GnuObjCCompiler):
def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
GnuObjCCompiler.__init__(self, exelist, version, cltype, is_cross, exe_wrapper)
ClangCompiler.__init__(self, cltype)
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']

@ -0,0 +1,65 @@
# 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
from ..mesonlib import EnvironmentException
from .cpp import CPPCompiler
from .compilers import ClangCompiler, GnuCompiler
class ObjCPPCompiler(CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'objcpp'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def sanity_check(self, work_dir, environment):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm')
binary_name = os.path.join(work_dir, 'sanitycheckobjcpp')
extra_flags = self.get_cross_extra_flags(environment, link=False)
if self.is_cross:
extra_flags += self.get_compile_only_args()
with open(source_name, 'w') as ofile:
ofile.write('#import<stdio.h>\n'
'class MyClass;'
'int main(int argc, char **argv) { return 0; }\n')
pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('ObjC++ compiler %s can not compile programs.' % self.name_string())
if self.is_cross:
# Can't check if the binaries run so we have to assume they do
return
pe = subprocess.Popen(binary_name)
pe.wait()
if pe.returncode != 0:
raise EnvironmentException('Executables created by ObjC++ compiler %s are not runnable.' % self.name_string())
class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
ObjCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
GnuCompiler.__init__(self, gcc_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
class ClangObjCPPCompiler(ClangCompiler, GnuObjCPPCompiler):
def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
GnuObjCPPCompiler.__init__(self, exelist, version, cltype, is_cross, exe_wrapper)
ClangCompiler.__init__(self, cltype)
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']

@ -0,0 +1,59 @@
# 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 subprocess, os.path
from ..mesonlib import EnvironmentException, Popen_safe
from .compilers import Compiler, rust_buildtype_args
class RustCompiler(Compiler):
def __init__(self, exelist, version):
self.language = 'rust'
super().__init__(exelist, version)
self.id = 'rustc'
def needs_static_linker(self):
return False
def name_string(self):
return ' '.join(self.exelist)
def sanity_check(self, work_dir, environment):
source_name = os.path.join(work_dir, 'sanity.rs')
output_name = os.path.join(work_dir, 'rusttest')
with open(source_name, 'w') as ofile:
ofile.write('''fn main() {
}
''')
pc = subprocess.Popen(self.exelist + ['-o', output_name, source_name], cwd=work_dir)
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Rust compiler %s can not compile programs.' % self.name_string())
if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by Rust compiler %s are not runnable.' % self.name_string())
def get_dependency_gen_args(self, outfile):
return ['--dep-info', outfile]
def get_buildtype_args(self, buildtype):
return rust_buildtype_args[buildtype]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath)
def get_sysroot(self):
cmd = self.exelist + ['--print', 'sysroot']
p, stdo, stde = Popen_safe(cmd)
return stdo.split('\n')[0]

@ -0,0 +1,99 @@
# 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 subprocess, os.path
from ..mesonlib import EnvironmentException
from .compilers import Compiler, swift_buildtype_args
class SwiftCompiler(Compiler):
def __init__(self, exelist, version):
self.language = 'swift'
super().__init__(exelist, version)
self.version = version
self.id = 'llvm'
self.is_cross = False
def get_linker_exelist(self):
return self.exelist[:]
def name_string(self):
return ' '.join(self.exelist)
def needs_static_linker(self):
return True
def get_werror_args(self):
return ['--fatal-warnings']
def get_dependency_gen_args(self, outtarget, outfile):
return ['-emit-dependencies']
def depfile_for_object(self, objfile):
return os.path.splitext(objfile)[0] + '.' + self.get_depfile_suffix()
def get_depfile_suffix(self):
return 'd'
def get_output_args(self, target):
return ['-o', target]
def get_linker_output_args(self, target):
return ['-o', target]
def get_header_import_args(self, headername):
return ['-import-objc-header', headername]
def get_warn_args(self, level):
return []
def get_buildtype_args(self, buildtype):
return swift_buildtype_args[buildtype]
def get_buildtype_linker_args(self, buildtype):
return []
def get_std_exe_link_args(self):
return ['-emit-executable']
def get_module_args(self, modname):
return ['-module-name', modname]
def get_mod_gen_args(self):
return ['-emit-module']
def build_rpath_args(self, *args):
return [] # FIXME
def get_include_args(self, dirname):
return ['-I' + dirname]
def get_compile_only_args(self):
return ['-c']
def sanity_check(self, work_dir, environment):
src = 'swifttest.swift'
source_name = os.path.join(work_dir, src)
output_name = os.path.join(work_dir, 'swifttest')
with open(source_name, 'w') as ofile:
ofile.write('''print("Swift compilation is working.")
''')
extra_flags = self.get_cross_extra_flags(environment, link=True)
pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir)
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string())
if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string())

@ -0,0 +1,90 @@
# 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
from .. import mlog
from ..mesonlib import EnvironmentException
from .compilers import Compiler
class ValaCompiler(Compiler):
def __init__(self, exelist, version):
self.language = 'vala'
super().__init__(exelist, version)
self.version = version
self.id = 'valac'
self.is_cross = False
def name_string(self):
return ' '.join(self.exelist)
def needs_static_linker(self):
return False # Because compiles into C.
def get_output_args(self, target):
return ['-o', target]
def get_compile_only_args(self):
return ['-C']
def get_pic_args(self):
return []
def get_always_args(self):
return ['-C']
def get_warn_args(self, warning_level):
return []
def get_no_warn_args(self):
return ['--disable-warnings']
def get_werror_args(self):
return ['--fatal-warnings']
def sanity_check(self, work_dir, environment):
code = 'class MesonSanityCheck : Object { }'
args = self.get_cross_extra_flags(environment, link=False)
with self.compile(code, args, 'compile') as p:
if p.returncode != 0:
msg = 'Vala compiler {!r} can not compile programs' \
''.format(self.name_string())
raise EnvironmentException(msg)
def get_buildtype_args(self, buildtype):
if buildtype == 'debug' or buildtype == 'debugoptimized' or buildtype == 'minsize':
return ['--debug']
return []
def find_library(self, libname, env, extra_dirs):
if extra_dirs and isinstance(extra_dirs, str):
extra_dirs = [extra_dirs]
# Valac always looks in the default vapi dir, so only search there if
# no extra dirs are specified.
if not extra_dirs:
code = 'class MesonFindLibrary : Object { }'
vapi_args = ['--pkg', libname]
args = self.get_cross_extra_flags(env, link=False)
args += vapi_args
with self.compile(code, args, 'compile') as p:
if p.returncode == 0:
return vapi_args
# Not found? Try to find the vapi file itself.
for d in extra_dirs:
vapi = os.path.join(d, libname + '.vapi')
if os.path.isfile(vapi):
return [vapi]
mlog.debug('Searched {!r} and {!r} wasn\'t found'.format(extra_dirs, libname))
return None

@ -12,15 +12,57 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import platform
import re
import configparser, os, platform, re, shlex, shutil, subprocess
from .compilers import *
from . import coredata
from .linkers import ArLinker, VisualStudioLinker
from . import mesonlib
from .mesonlib import EnvironmentException, Popen_safe
import configparser
import shlex
import shutil
from . import mlog
from . import compilers
from .compilers import (
CLANG_OSX,
CLANG_STANDARD,
CLANG_WIN,
GCC_CYGWIN,
GCC_MINGW,
GCC_OSX,
GCC_STANDARD,
ICC_STANDARD,
is_assembly,
is_header,
is_library,
is_llvm_ir,
is_object,
is_source,
)
from .compilers import (
ClangCCompiler,
ClangCPPCompiler,
ClangObjCCompiler,
ClangObjCPPCompiler,
G95FortranCompiler,
GnuCCompiler,
GnuCPPCompiler,
GnuFortranCompiler,
GnuObjCCompiler,
GnuObjCPPCompiler,
IntelCCompiler,
IntelCPPCompiler,
IntelFortranCompiler,
JavaCompiler,
MonoCompiler,
NAGFortranCompiler,
Open64FortranCompiler,
PathScaleFortranCompiler,
PGIFortranCompiler,
RustCompiler,
SunFortranCompiler,
ValaCompiler,
VisualStudioCCompiler,
VisualStudioCPPCompiler,
)
build_filename = 'meson.build'
@ -684,11 +726,11 @@ class Environment:
raise EnvironmentException('Could not execute D compiler "%s"' % ' '.join(exelist))
version = search_version(out)
if 'LLVM D compiler' in out:
return LLVMDCompiler(exelist, version, is_cross)
return compilers.LLVMDCompiler(exelist, version, is_cross)
elif 'gdc' in out:
return GnuDCompiler(exelist, version, is_cross)
return compilers.GnuDCompiler(exelist, version, is_cross)
elif 'Digital Mars' in out:
return DmdDCompiler(exelist, version, is_cross)
return compilers.DmdDCompiler(exelist, version, is_cross)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_swift_compiler(self):
@ -699,7 +741,7 @@ class Environment:
raise EnvironmentException('Could not execute Swift compiler "%s"' % ' '.join(exelist))
version = search_version(err)
if 'Swift' in err:
return SwiftCompiler(exelist, version)
return compilers.SwiftCompiler(exelist, version)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_static_linker(self, compiler):
@ -712,12 +754,12 @@ class Environment:
evar = 'AR'
if evar in os.environ:
linkers = [shlex.split(os.environ[evar])]
elif isinstance(compiler, VisualStudioCCompiler):
elif isinstance(compiler, compilers.VisualStudioCCompiler):
linkers = [self.vs_static_linker]
elif isinstance(compiler, GnuCompiler):
elif isinstance(compiler, compilers.GnuCompiler):
# Use gcc-ar if available; needed for LTO
linkers = [self.gcc_static_linker, self.default_static_linker]
elif isinstance(compiler, ClangCompiler):
elif isinstance(compiler, compilers.ClangCompiler):
# Use llvm-ar if available; needed for LTO
linkers = [self.clang_static_linker, self.default_static_linker]
else:

@ -0,0 +1,114 @@
# 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.
from .mesonlib import Popen_safe
class StaticLinker:
pass
class VisualStudioLinker(StaticLinker):
always_args = ['/NOLOGO']
def __init__(self, exelist):
self.exelist = exelist
def get_exelist(self):
return self.exelist[:]
def get_std_link_args(self):
return []
def get_buildtype_linker_args(self, buildtype):
return []
def get_output_args(self, target):
return ['/OUT:' + target]
def get_coverage_link_args(self):
return []
def get_always_args(self):
return VisualStudioLinker.always_args
def get_linker_always_args(self):
return VisualStudioLinker.always_args
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return []
def thread_link_flags(self):
return []
def get_option_link_args(self, options):
return []
@classmethod
def unix_args_to_native(cls, args):
from .compilers import VisualStudioCCompiler
return VisualStudioCCompiler.unix_args_to_native(args)
def get_link_debugfile_args(self, targetfile):
# Static libraries do not have PDB files
return []
class ArLinker(StaticLinker):
def __init__(self, exelist):
self.exelist = exelist
self.id = 'ar'
pc, stdo = Popen_safe(self.exelist + ['-h'])[0:2]
# Enable deterministic builds if they are available.
if '[D]' in stdo:
self.std_args = ['csrD']
else:
self.std_args = ['csr']
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
return []
def get_exelist(self):
return self.exelist[:]
def get_std_link_args(self):
return self.std_args
def get_output_args(self, target):
return [target]
def get_buildtype_linker_args(self, buildtype):
return []
def get_linker_always_args(self):
return []
def get_coverage_link_args(self):
return []
def get_always_args(self):
return []
def thread_link_flags(self):
return []
def get_option_link_args(self, options):
return []
@classmethod
def unix_args_to_native(cls, args):
return args[:]
def get_link_debugfile_args(self, targetfile):
return []

@ -25,7 +25,6 @@ import mesontest
from mesonbuild import environment
from mesonbuild import mesonlib
from mesonbuild import mlog
from mesonbuild import mesonmain
from mesonbuild.mesonlib import stringlistify, Popen_safe
from mesonbuild.coredata import backendlist
import argparse

@ -109,7 +109,7 @@ class InternalTests(unittest.TestCase):
def test_compiler_args_class(self):
cargsfunc = mesonbuild.compilers.CompilerArgs
c = mesonbuild.environment.CCompiler([], 'fake', False)
c = mesonbuild.compilers.CCompiler([], 'fake', False)
# Test that bad initialization fails
self.assertRaises(TypeError, cargsfunc, [])
self.assertRaises(TypeError, cargsfunc, [], [])
@ -701,7 +701,7 @@ class AllPlatformTests(BasePlatformTests):
static_linker = env.detect_static_linker(cc)
if is_windows():
raise unittest.SkipTest('https://github.com/mesonbuild/meson/issues/1526')
if not isinstance(static_linker, mesonbuild.compilers.ArLinker):
if not isinstance(static_linker, mesonbuild.linkers.ArLinker):
raise unittest.SkipTest('static linker is not `ar`')
# Configure
self.init(testdir)
@ -936,8 +936,8 @@ class AllPlatformTests(BasePlatformTests):
clang = mesonbuild.compilers.ClangCompiler
intel = mesonbuild.compilers.IntelCompiler
msvc = mesonbuild.compilers.VisualStudioCCompiler
ar = mesonbuild.compilers.ArLinker
lib = mesonbuild.compilers.VisualStudioLinker
ar = mesonbuild.linkers.ArLinker
lib = mesonbuild.linkers.VisualStudioLinker
langs = [('c', 'CC'), ('cpp', 'CXX')]
if not is_windows():
langs += [('objc', 'OBJC'), ('objcpp', 'OBJCXX')]

Loading…
Cancel
Save