Compare commits

...

9 Commits

Author SHA1 Message Date
Jussi Pakkanen d31db565e1 Add white border to logo used on web pages. [skip ci] 5 years ago
Jussi Pakkanen 23f831a674
Merge pull request #5339 from dcbaker/clike 5 years ago
Clouds a0cf7ad3d8 fix error when show default config of list 5 years ago
nicole mazzuca 24d5c73b0a add -fno-exceptions if cpp_eh=none is specified 5 years ago
Jon Turney 261878f438 Fix an assertion exception when misusing install_data 5 years ago
Dylan Baker 541523eeba compilers: Split C-Like functionality into a mixin classes 5 years ago
Dylan Baker 604b2534e8 environment: Fix syntax error 5 years ago
Dylan Baker da5f07cf39 Revert "detect Intel ICL on windows" 5 years ago
Dylan Baker 482e26764e Revert "enable Windows Intel compiler" 5 years ago
  1. 8
      docs/markdown/Builtin-options.md
  2. BIN
      docs/theme/extra/images/meson_logo.png
  3. 4
      mesonbuild/backend/backends.py
  4. 14
      mesonbuild/backend/ninjabackend.py
  5. 6
      mesonbuild/compilers/__init__.py
  6. 1498
      mesonbuild/compilers/c.py
  7. 1187
      mesonbuild/compilers/clike.py
  8. 329
      mesonbuild/compilers/compilers.py
  9. 130
      mesonbuild/compilers/cpp.py
  10. 177
      mesonbuild/compilers/fortran.py
  11. 12
      mesonbuild/compilers/objc.py
  12. 12
      mesonbuild/compilers/objcpp.py
  13. 39
      mesonbuild/environment.py
  14. 4
      mesonbuild/interpreter.py
  15. 2
      mesonbuild/msetup.py
  16. 4
      run_unittests.py
  17. 11
      test cases/common/91 default options/meson.build
  18. 1
      test cases/failing/97 custom target install data/Info.plist.cpp
  19. 11
      test cases/failing/97 custom target install data/meson.build
  20. 13
      test cases/failing/97 custom target install data/preproc.py

@ -134,7 +134,7 @@ compiler being used:
| cpp_link_args| | free-form comma-separated list | C++ link arguments to use |
| cpp_std | none | none, c++98, c++03, c++11, c++14, c++17, <br/>c++1z, gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, <br/> vc++14, vc++17, vc++latest | C++ language standard to use |
| cpp_debugstl | false | true, false | C++ STL debug mode |
| cpp_eh | sc | none, a, s, sc | C++ exception handling type |
| cpp_eh | default | none, default, a, s, sc | C++ exception handling type |
| cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against |
The default values of `c_winlibs` and `cpp_winlibs` are in compiler-specific
@ -144,3 +144,9 @@ shell32, ole32, oleaut32, uuid, comdlg32, advapi32.
c_args, cpp_args, c_link_args, and cpp_link_args only affect native builds,
when cross compiling they will not be applied to binaries or libraries
targeting the host system, only those being run on the build system.
When using MSVC, `cpp_eh=none` will result in no exception flags being passed,
while the `cpp_eh=[value]` will result in `/EH[value]`.
Since *0.51.0* `cpp_eh=default` will result in `/EHsc` on MSVC. When using
gcc-style compilers, nothing is passed (allowing exceptions to work), while
`cpp_eh=none` passes `-fno-exceptions`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 16 KiB

@ -23,7 +23,7 @@ import subprocess
from ..mesonlib import MachineChoice, MesonException, OrderedSet
from ..mesonlib import classify_unity_sources
from ..mesonlib import File
from ..compilers import CompilerArgs, VisualStudioCCompiler
from ..compilers import CompilerArgs, VisualStudioLikeCompiler
from collections import OrderedDict
import shlex
from functools import lru_cache
@ -551,7 +551,7 @@ class Backend:
return args
extra_args = []
# Compiler-specific escaping is needed for -D args but not for any others
if isinstance(compiler, VisualStudioCCompiler):
if isinstance(compiler, VisualStudioLikeCompiler):
# MSVC needs escaping when a -D argument ends in \ or \"
for arg in args:
if arg.startswith('-D') or arg.startswith('/D'):

@ -29,7 +29,7 @@ from .. import build
from .. import mlog
from .. import dependencies
from .. import compilers
from ..compilers import CompilerArgs, CCompiler, VisualStudioCCompiler, FortranCompiler
from ..compilers import CompilerArgs, CCompiler, VisualStudioLikeCompiler, FortranCompiler
from ..linkers import ArLinker
from ..mesonlib import File, MachineChoice, MesonException, OrderedSet, LibType
from ..mesonlib import get_compiler_for_source, has_path_sep
@ -221,7 +221,7 @@ class NinjaBackend(backends.Backend):
Detect the search prefix to use.'''
for compiler in self.build.compilers.values():
# Have to detect the dependency format
if isinstance(compiler, VisualStudioCCompiler):
if isinstance(compiler, VisualStudioLikeCompiler):
break
else:
# None of our compilers are MSVC, we're done.
@ -1673,7 +1673,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
command = [ninja_quote(i) for i in compiler.get_exelist()]
args = ['$ARGS'] + quoted_depargs + compiler.get_output_args('$out') + compiler.get_compile_only_args() + ['$in']
description = 'Compiling %s object $out.' % compiler.get_display_language()
if isinstance(compiler, VisualStudioCCompiler):
if isinstance(compiler, VisualStudioLikeCompiler):
deps = 'msvc'
depfile = None
else:
@ -1698,13 +1698,13 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if d != '$out' and d != '$in':
d = quote_func(d)
quoted_depargs.append(d)
if isinstance(compiler, VisualStudioCCompiler):
if isinstance(compiler, VisualStudioLikeCompiler):
output = []
else:
output = compiler.get_output_args('$out')
command = compiler.get_exelist() + ['$ARGS'] + quoted_depargs + output + compiler.get_compile_only_args() + ['$in']
description = 'Precompiling header $in.'
if isinstance(compiler, VisualStudioCCompiler):
if isinstance(compiler, VisualStudioLikeCompiler):
deps = 'msvc'
depfile = None
else:
@ -1886,7 +1886,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return compiler.get_no_stdinc_args()
def get_compile_debugfile_args(self, compiler, target, objfile):
if not isinstance(compiler, VisualStudioCCompiler):
if not isinstance(compiler, VisualStudioLikeCompiler):
return []
# The way MSVC uses PDB files is documented exactly nowhere so
# the following is what we have been able to decipher via
@ -2275,7 +2275,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
''.format(target.get_basename())
raise InvalidArguments(msg)
compiler = target.compilers[lang]
if isinstance(compiler, VisualStudioCCompiler):
if isinstance(compiler, VisualStudioLikeCompiler):
(commands, dep, dst, objs, src) = self.generate_msvc_pch_command(target, compiler, pch)
extradep = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0])
elif compiler.id == 'intel':

@ -69,8 +69,6 @@ __all__ = [
'IntelCCompiler',
'IntelCPPCompiler',
'IntelFortranCompiler',
'IntelClCCompiler',
'IntelClCPPCompiler',
'JavaCompiler',
'LLVMDCompiler',
'MonoCompiler',
@ -91,6 +89,7 @@ __all__ = [
'SunFortranCompiler',
'SwiftCompiler',
'ValaCompiler',
'VisualStudioLikeCompiler',
'VisualStudioCCompiler',
'VisualStudioCPPCompiler',
]
@ -122,6 +121,7 @@ from .compilers import (
GnuCompiler,
IntelCompiler,
CcrxCompiler,
VisualStudioLikeCompiler,
)
from .c import (
CCompiler,
@ -132,7 +132,6 @@ from .c import (
GnuCCompiler,
ElbrusCCompiler,
IntelCCompiler,
IntelClCCompiler,
PGICCompiler,
CcrxCCompiler,
VisualStudioCCompiler,
@ -146,7 +145,6 @@ from .cpp import (
GnuCPPCompiler,
ElbrusCPPCompiler,
IntelCPPCompiler,
IntelClCPPCompiler,
PGICPPCompiler,
CcrxCPPCompiler,
VisualStudioCPPCompiler,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1529,6 +1529,335 @@ def gnulike_default_include_dirs(compiler, lang):
return paths
class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
"""A common interface for all compilers implementing an MSVC-style
interface.
A number of compilers attempt to mimic MSVC, with varying levels of
success, such as Clang-CL and ICL (the Intel C/C++ Compiler for Windows).
This classs implements as much common logic as possible.
"""
std_warn_args = ['/W3']
std_opt_args = ['/O2']
ignore_libs = unixy_compiler_internal_libs
internal_libs = ()
crt_args = {'none': [],
'md': ['/MD'],
'mdd': ['/MDd'],
'mt': ['/MT'],
'mtd': ['/MTd'],
}
# /showIncludes is needed for build dependency tracking in Ninja
# See: https://ninja-build.org/manual.html#_deps
always_args = ['/nologo', '/showIncludes']
warn_args = {'0': ['/W1'],
'1': ['/W2'],
'2': ['/W3'],
'3': ['/W4'],
}
def __init__(self, target: str):
self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like
self.target = target
self.is_64 = ('x64' in target) or ('x86_64' in target)
# do some canonicalization of target machine
if 'x86_64' in target:
self.machine = 'x64'
elif '86' in target:
self.machine = 'x86'
else:
self.machine = target
# Override CCompiler.get_always_args
def get_always_args(self):
return self.always_args
def get_linker_debug_crt_args(self):
"""
Arguments needed to select a debug crt for the linker
Sometimes we need to manually select the CRT (C runtime) to use with
MSVC. One example is when trying to link with static libraries since
MSVC won't auto-select a CRT for us in that case and will error out
asking us to select one.
"""
return ['/MDd']
def get_buildtype_args(self, buildtype):
args = msvc_buildtype_args[buildtype]
if self.id == 'msvc' and version_compare(self.version, '<18.0'):
args = [arg for arg in args if arg != '/Gw']
return args
def get_buildtype_linker_args(self, buildtype):
return msvc_buildtype_linker_args[buildtype]
def get_pch_suffix(self):
return 'pch'
def get_pch_name(self, header):
chopped = os.path.basename(header).split('.')[:-1]
chopped.append(self.get_pch_suffix())
pchname = '.'.join(chopped)
return pchname
def get_pch_use_args(self, pch_dir, header):
base = os.path.basename(header)
if self.id == 'clang-cl':
base = header
pchname = self.get_pch_name(header)
return ['/FI' + base, '/Yu' + base, '/Fp' + os.path.join(pch_dir, pchname)]
def get_preprocess_only_args(self):
return ['/EP']
def get_compile_only_args(self):
return ['/c']
def get_no_optimization_args(self):
return ['/Od']
def get_output_args(self, target):
if target.endswith('.exe'):
return ['/Fe' + target]
return ['/Fo' + target]
def get_optimization_args(self, optimization_level):
return msvc_optimization_args[optimization_level]
def get_debug_args(self, is_debug):
return msvc_debug_args[is_debug]
def get_dependency_gen_args(self, outtarget, outfile):
return []
def get_linker_exelist(self):
# FIXME, should have same path as compiler.
# FIXME, should be controllable via cross-file.
if self.id == 'clang-cl':
return ['lld-link']
else:
return ['link']
def get_linker_always_args(self):
return ['/nologo']
def get_linker_output_args(self, outputname):
return ['/MACHINE:' + self.machine, '/OUT:' + outputname]
def get_linker_search_args(self, dirname):
return ['/LIBPATH:' + dirname]
def linker_to_compiler_args(self, args):
return ['/link'] + args
def get_gui_app_args(self, value):
# the default is for the linker to guess the subsystem based on presence
# of main or WinMain symbols, so always be explicit
if value:
return ['/SUBSYSTEM:WINDOWS']
else:
return ['/SUBSYSTEM:CONSOLE']
def get_pic_args(self):
return [] # PIC is handled by the loader on Windows
def gen_export_dynamic_link_args(self, env):
return [] # Not applicable with MSVC
def get_std_shared_lib_link_args(self):
return ['/DLL']
def gen_vs_module_defs_args(self, defsfile):
if not isinstance(defsfile, str):
raise RuntimeError('Module definitions file should be str')
# With MSVC, DLLs only export symbols that are explicitly exported,
# so if a module defs file is specified, we use that to export symbols
return ['/DEF:' + defsfile]
def gen_pch_args(self, header, source, pchname):
objname = os.path.splitext(pchname)[0] + '.obj'
return objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname]
def gen_import_library_args(self, implibname):
"The name of the outputted import library"
return ['/IMPLIB:' + implibname]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return []
def openmp_flags(self):
return ['/openmp']
# FIXME, no idea what these should be.
def thread_flags(self, env):
return []
def thread_link_flags(self, env):
return []
@classmethod
def unix_args_to_native(cls, args):
result = []
for i in args:
# -mms-bitfields is specific to MinGW-GCC
# -pthread is only valid for GCC
if i in ('-mms-bitfields', '-pthread'):
continue
if i.startswith('-L'):
i = '/LIBPATH:' + i[2:]
# Translate GNU-style -lfoo library name to the import library
elif i.startswith('-l'):
name = i[2:]
if name in cls.ignore_libs:
# With MSVC, these are provided by the C runtime which is
# linked in by default
continue
else:
i = name + '.lib'
# -pthread in link flags is only used on Linux
elif i == '-pthread':
continue
result.append(i)
return result
def get_werror_args(self):
return ['/WX']
def get_include_args(self, path, is_system):
if path == '':
path = '.'
# msvc does not have a concept of system header dirs.
return ['-I' + path]
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] == '/I':
parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))
elif i[:9] == '/LIBPATH:':
parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:]))
return parameter_list
# Visual Studio is special. It ignores some arguments it does not
# understand and you can't tell it to error out on those.
# http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t
def has_arguments(self, args, env, code, mode):
warning_text = '4044' if mode == 'link' else '9002'
if self.id == 'clang-cl' and mode != 'link':
args = args + ['-Werror=unknown-argument']
with self._build_wrapper(code, env, extra_args=args, mode=mode) as p:
if p.returncode != 0:
return False, p.cached
return not(warning_text in p.stde or warning_text in p.stdo), p.cached
def get_compile_debugfile_args(self, rel_obj, pch=False):
pdbarr = rel_obj.split('.')[:-1]
pdbarr += ['pdb']
args = ['/Fd' + '.'.join(pdbarr)]
# When generating a PDB file with PCH, all compile commands write
# to the same PDB file. Hence, we need to serialize the PDB
# writes using /FS since we do parallel builds. This slows down the
# build obviously, which is why we only do this when PCH is on.
# This was added in Visual Studio 2013 (MSVC 18.0). Before that it was
# always on: https://msdn.microsoft.com/en-us/library/dn502518.aspx
if pch and self.id == 'msvc' and version_compare(self.version, '>=18.0'):
args = ['/FS'] + args
return args
def get_link_debugfile_args(self, targetfile):
pdbarr = targetfile.split('.')[:-1]
pdbarr += ['pdb']
return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]
def get_link_whole_for(self, args):
# Only since VS2015
args = mesonlib.listify(args)
return ['/WHOLEARCHIVE:' + x for x in args]
def get_instruction_set_args(self, instruction_set):
if self.is_64:
return vs64_instruction_set_args.get(instruction_set, None)
if self.id == 'msvc' and self.version.split('.')[0] == '16' and instruction_set == 'avx':
# VS documentation says that this exists and should work, but
# it does not. The headers do not contain AVX intrinsics
# and the can not be called.
return None
return vs32_instruction_set_args.get(instruction_set, None)
def get_toolset_version(self):
if self.id == 'clang-cl':
# I have no idea
return '14.1'
# See boost/config/compiler/visualc.cpp for up to date mapping
try:
version = int(''.join(self.version.split('.')[0:2]))
except ValueError:
return None
if version < 1310:
return '7.0'
elif version < 1400:
return '7.1' # (Visual Studio 2003)
elif version < 1500:
return '8.0' # (Visual Studio 2005)
elif version < 1600:
return '9.0' # (Visual Studio 2008)
elif version < 1700:
return '10.0' # (Visual Studio 2010)
elif version < 1800:
return '11.0' # (Visual Studio 2012)
elif version < 1900:
return '12.0' # (Visual Studio 2013)
elif version < 1910:
return '14.0' # (Visual Studio 2015)
elif version < 1920:
return '14.1' # (Visual Studio 2017)
elif version < 1930:
return '14.2' # (Visual Studio 2019)
mlog.warning('Could not find toolset for version {!r}'.format(self.version))
return None
def get_default_include_dirs(self):
if 'INCLUDE' not in os.environ:
return []
return os.environ['INCLUDE'].split(os.pathsep)
def get_crt_compile_args(self, crt_val, buildtype):
if crt_val in self.crt_args:
return self.crt_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.crt_args['mdd']
elif buildtype == 'debugoptimized':
return self.crt_args['md']
elif buildtype == 'release':
return self.crt_args['md']
elif buildtype == 'minsize':
return self.crt_args['md']
else:
assert(buildtype == 'custom')
raise mesonlib.EnvironmentException('Requested C runtime based on buildtype, but buildtype is "custom".')
def has_func_attribute(self, name, env):
# MSVC doesn't have __attribute__ like Clang and GCC do, so just return
# false without compiling anything
return name in ['dllimport', 'dllexport'], False
def get_argument_syntax(self):
return 'msvc'
def get_allow_undefined_link_args(self):
# link.exe
return ['/FORCE:UNRESOLVED']
class GnuLikeCompiler(abc.ABC):
"""
GnuLikeCompiler is a common interface to all compilers implementing

@ -14,12 +14,12 @@
import functools
import os.path
import typing
from .. import coredata
from .. import mlog
from ..mesonlib import MesonException, version_compare
from .c import CCompiler, VisualStudioCCompiler, ClangClCCompiler, IntelClCCompiler
from .compilers import (
gnu_winlibs,
msvc_winlibs,
@ -31,20 +31,27 @@ from .compilers import (
ArmCompiler,
ArmclangCompiler,
CcrxCompiler,
Compiler,
VisualStudioLikeCompiler,
)
from .c_function_attributes import CXX_FUNC_ATTRIBUTES
from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES
from .clike import CLikeCompiler
class CPPCompiler(CCompiler):
class CPPCompiler(CLikeCompiler, Compiler):
@classmethod
def attribute_check_func(cls, name):
return CXX_FUNC_ATTRIBUTES.get(name, super().attribute_check_func(name))
try:
return CXX_FUNC_ATTRIBUTES.get(name, C_FUNC_ATTRIBUTES[name])
except KeyError:
raise MesonException('Unknown function attribute "{}"'.format(name))
def __init__(self, exelist, version, is_cross, exe_wrap, **kwargs):
def __init__(self, exelist, version, is_cross: bool,
exe_wrap: typing.Optional[str] = None, **kwargs):
# 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, **kwargs)
self.language = 'cpp'
Compiler.__init__(self, exelist, version, **kwargs)
CLikeCompiler.__init__(self, is_cross, exe_wrap)
def get_display_language(self):
return 'C++'
@ -142,7 +149,11 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def get_options(self):
opts = CPPCompiler.get_options(self)
opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'default'],
'default'),
'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'],
'none')})
@ -153,6 +164,8 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
std = options['cpp_std']
if std.value != 'none':
args.append(self._find_best_cpp_std(std.value))
if options['cpp_eh'].value == 'none':
args.append('-fno-exceptions')
return args
def get_option_link_args(self, options):
@ -174,7 +187,11 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
def get_options(self):
opts = CPPCompiler.get_options(self)
opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'default'],
'default'),
'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17',
'gnu++98', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17'],
'none')})
@ -185,6 +202,8 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
std = options['cpp_std']
if std.value != 'none':
args.append('-std=' + std.value)
if options['cpp_eh'].value == 'none':
args.append('-fno-exceptions')
return args
def get_option_link_args(self, options):
@ -203,7 +222,11 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
def get_options(self):
opts = CPPCompiler.get_options(self)
opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'default'],
'default'),
'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'],
'none'),
@ -221,6 +244,8 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
std = options['cpp_std']
if std.value != 'none':
args.append(self._find_best_cpp_std(std.value))
if options['cpp_eh'].value == 'none':
args.append('-fno-exceptions')
if options['cpp_debugstl'].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
@ -251,7 +276,11 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
# It does not support c++/gnu++ 17 and 1z, but still does support 0x, 1y, and gnu++98.
def get_options(self):
opts = CPPCompiler.get_options(self)
opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'default'],
'default'),
'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++98', 'c++03', 'c++0x', 'c++11', 'c++14', 'c++1y',
'gnu++98', 'gnu++03', 'gnu++0x', 'gnu++11', 'gnu++14', 'gnu++1y'],
'none'),
@ -297,7 +326,11 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
c_stds += ['c++17']
if version_compare(self.version, '>=17.0.0'):
g_stds += ['gnu++14']
opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'default'],
'default'),
'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
['none'] + c_stds + g_stds,
'none'),
'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl',
@ -314,6 +347,8 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
'gnu++03': 'gnu++98'
}
args.append('-std=' + remap_cpp03.get(std.value, std.value))
if options['cpp_eh'].value == 'none':
args.append('-fno-exceptions')
if options['cpp_debugstl'].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
@ -322,29 +357,18 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
return []
class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap, target)
self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like
class VisualStudioLikeCPPCompilerMixin:
def get_options(self):
cpp_stds = ['none', 'c++11', 'vc++11']
if self.id == 'clang-cl':
cpp_stds.extend(['c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'])
else:
# Visual Studio 2015 and later
if version_compare(self.version, '>=19'):
cpp_stds.extend(['c++14', 'vc++14', 'c++latest', 'vc++latest'])
# Visual Studio 2017 and later
if version_compare(self.version, '>=19.11'):
cpp_stds.extend(['c++17', 'vc++17'])
"""Mixin for C++ specific method overrides in MSVC-like compilers."""
opts = CPPCompiler.get_options(self)
def get_option_link_args(self, options):
return options['cpp_winlibs'].value[:]
def _get_options_impl(self, opts, cpp_stds: typing.List[str]):
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
['none', 'a', 's', 'sc'],
'sc'),
['none', 'a', 's', 'sc', 'default'],
'default'),
'cpp_std': coredata.UserComboOption('cpp_std',
'C++ language standard to use',
cpp_stds,
@ -358,7 +382,9 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
args = []
eh = options['cpp_eh']
if eh.value != 'none':
if eh.value == 'default':
args.append('/EHsc')
elif eh.value != 'none':
args.append('/EH' + eh.value)
vc_version_map = {
@ -393,24 +419,38 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
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 VisualStudioCCompiler.get_compiler_check_args(self)
# XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class.
return CLikeCompiler.get_compiler_check_args(self)
class ClangClCPPCompiler(VisualStudioCPPCompiler, ClangClCCompiler):
class VisualStudioCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
VisualStudioCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, target)
self.id = 'clang-cl'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioLikeCompiler.__init__(self, target)
self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like
self.id = 'msvc'
def get_options(self):
cpp_stds = ['none', 'c++11', 'vc++11']
# Visual Studio 2015 and later
if version_compare(self.version, '>=19'):
cpp_stds.extend(['c++14', 'vc++14', 'c++latest', 'vc++latest'])
# Visual Studio 2017 and later
if version_compare(self.version, '>=19.11'):
cpp_stds.extend(['c++17', 'vc++17'])
return self._get_options_impl(super().get_options(), cpp_stds)
class IntelClCPPCompiler(VisualStudioCPPCompiler, IntelClCCompiler):
class ClangClCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
VisualStudioCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, target)
self.id = 'intel'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioLikeCompiler.__init__(self, target)
self.id = 'clang-cl'
def get_options(self):
cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest']
return self._get_options_impl(super().get_options(), cpp_stds)
class ArmCPPCompiler(ArmCompiler, CPPCompiler):

@ -15,7 +15,6 @@ from typing import List
import subprocess, os
from pathlib import Path
from .c import CCompiler
from .compilers import (
CompilerType,
apple_buildtype_linker_args,
@ -28,54 +27,26 @@ from .compilers import (
ClangCompiler,
ElbrusCompiler,
IntelCompiler,
PGICompiler
PGICompiler,
)
from .clike import CLikeCompiler
from mesonbuild.mesonlib import (
EnvironmentException, MachineChoice, is_osx, LibType
)
class FortranCompiler(Compiler):
library_dirs_cache = CCompiler.library_dirs_cache
program_dirs_cache = CCompiler.library_dirs_cache
find_library_cache = CCompiler.library_dirs_cache
class FortranCompiler(CLikeCompiler, Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
self.language = 'fortran'
Compiler.__init__(self, exelist, version, **kwargs)
cc = CCompiler(exelist, version, is_cross, exe_wrapper, **kwargs)
CLikeCompiler.__init__(self, is_cross, exe_wrapper)
self.id = 'unknown'
self.is_cross = cc.is_cross
self.exe_wrapper = cc.exe_wrapper
def get_display_language(self):
return 'Fortran'
def needs_static_linker(self):
return CCompiler.needs_static_linker(self)
def get_always_args(self):
return CCompiler.get_always_args(self)
def get_linker_debug_crt_args(self):
return CCompiler.get_linker_debug_crt_args(self)
def get_no_stdinc_args(self):
return CCompiler.get_no_stdinc_args(self)
def get_no_stdlib_link_args(self):
return CCompiler.get_no_stdlib_link_args(self)
def get_warn_args(self, level):
return CCompiler.get_warn_args(self, level)
def get_no_warn_args(self):
return CCompiler.get_no_warn_args(self)
def get_soname_args(self, *args):
return CCompiler.get_soname_args(self, *args)
def sanity_check(self, work_dir: Path, environment):
"""
Check to be sure a minimal program can compile and execute
@ -133,59 +104,11 @@ class FortranCompiler(Compiler):
return apple_buildtype_linker_args[buildtype]
return gnulike_buildtype_linker_args[buildtype]
def split_shlib_to_parts(self, fname):
return CCompiler.split_shlib_to_parts(self, fname)
def build_rpath_args(self, *args):
return CCompiler.build_rpath_args(self, *args)
def get_dependency_gen_args(self, outtarget, outfile):
return []
def depfile_for_object(self, objfile):
return CCompiler.depfile_for_object(self, objfile)
def get_depfile_suffix(self):
return CCompiler.get_depfile_suffix(self)
def get_exelist(self):
return CCompiler.get_exelist(self)
def get_linker_exelist(self):
return CCompiler.get_linker_exelist(self)
def get_preprocess_only_args(self):
return ['-cpp'] + CCompiler.get_preprocess_only_args(self)
def get_compile_only_args(self):
return CCompiler.get_compile_only_args(self)
def get_no_optimization_args(self):
return CCompiler.get_no_optimization_args(self)
def get_compiler_check_args(self):
return CCompiler.get_compiler_check_args(self)
def get_output_args(self, target):
return CCompiler.get_output_args(self, target)
def get_linker_output_args(self, outputname):
return CCompiler.get_linker_output_args(self, outputname)
def get_coverage_args(self):
return CCompiler.get_coverage_args(self)
def get_coverage_link_args(self):
return CCompiler.get_coverage_link_args(self)
def get_werror_args(self):
return CCompiler.get_werror_args(self)
def get_std_exe_link_args(self):
return CCompiler.get_std_exe_link_args(self)
def get_include_args(self, path, is_system):
return CCompiler.get_include_args(self, path, is_system)
return ['-cpp'] + super().get_preprocess_only_args()
def get_module_incdir_args(self):
return ('-I', )
@ -214,102 +137,12 @@ class FortranCompiler(Compiler):
return filename
def get_std_shared_lib_link_args(self):
return CCompiler.get_std_shared_lib_link_args(self)
def _get_search_dirs(self, *args, **kwargs):
return CCompiler._get_search_dirs(self, *args, **kwargs)
def get_compiler_dirs(self, *args, **kwargs):
return CCompiler.get_compiler_dirs(self, *args, **kwargs)
def get_library_dirs(self, *args, **kwargs):
return CCompiler.get_library_dirs(self, *args, **kwargs)
def get_pic_args(self):
return CCompiler.get_pic_args(self)
def name_string(self):
return CCompiler.name_string(self)
def get_linker_search_args(self, dirname):
return CCompiler.get_linker_search_args(self, dirname)
def get_default_include_dirs(self):
return CCompiler.get_default_include_dirs(self)
def gen_export_dynamic_link_args(self, env):
return CCompiler.gen_export_dynamic_link_args(self, env)
def gen_import_library_args(self, implibname):
return CCompiler.gen_import_library_args(self, implibname)
def _get_basic_compiler_args(self, env, mode):
return CCompiler._get_basic_compiler_args(self, env, mode)
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
return CCompiler._get_compiler_check_args(self, env, extra_args, dependencies, mode=mode)
def compiles(self, code, env, *, extra_args=None, dependencies=None, mode='compile', disable_cache=False):
return CCompiler.compiles(self, code, env, extra_args=extra_args,
dependencies=dependencies, mode=mode, disable_cache=disable_cache)
def _build_wrapper(self, code, env, extra_args, dependencies=None, mode='compile', want_output=False, disable_cache=False):
return CCompiler._build_wrapper(self, code, env, extra_args, dependencies, mode, want_output, disable_cache=disable_cache)
def links(self, code, env, *, extra_args=None, dependencies=None, disable_cache=False):
return CCompiler.links(self, code, env, extra_args=extra_args,
dependencies=dependencies, disable_cache=disable_cache)
def run(self, code, env, *, extra_args=None, dependencies=None):
return CCompiler.run(self, code, env, extra_args=extra_args, dependencies=dependencies)
def _get_patterns(self, *args, **kwargs):
return CCompiler._get_patterns(self, *args, **kwargs)
def get_library_naming(self, *args, **kwargs):
return CCompiler.get_library_naming(self, *args, **kwargs)
def find_library_real(self, *args):
return CCompiler.find_library_real(self, *args)
def find_library_impl(self, *args):
return CCompiler.find_library_impl(self, *args)
def find_library(self, libname, env, extra_dirs, libtype: LibType = LibType.PREFER_SHARED):
code = '''program main
call exit(0)
end program main'''
return self.find_library_impl(libname, env, extra_dirs, code, libtype)
def thread_flags(self, env):
return CCompiler.thread_flags(self, env)
def thread_link_flags(self, env):
return CCompiler.thread_link_flags(self, env)
def linker_to_compiler_args(self, args):
return CCompiler.linker_to_compiler_args(self, args)
def has_arguments(self, args, env, code, mode):
return CCompiler.has_arguments(self, args, env, code, mode)
def has_multi_arguments(self, args, env):
return CCompiler.has_multi_arguments(self, args, env)
def has_header(self, hname, prefix, env, *, extra_args=None, dependencies=None, disable_cache=False):
return CCompiler.has_header(self, hname, prefix, env, extra_args=extra_args, dependencies=dependencies, disable_cache=disable_cache)
def get_define(self, dname, prefix, env, extra_args, dependencies, disable_cache=False):
return CCompiler.get_define(self, dname, prefix, env, extra_args, dependencies, disable_cache=disable_cache)
@classmethod
def _get_trials_from_pattern(cls, pattern, directory, libname):
return CCompiler._get_trials_from_pattern(pattern, directory, libname)
@staticmethod
def _get_file_from_list(env, files: List[str]) -> Path:
return CCompiler._get_file_from_list(env, files)
class GnuFortranCompiler(GnuCompiler, FortranCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):

@ -13,16 +13,18 @@
# limitations under the License.
import os.path, subprocess
import typing
from ..mesonlib import EnvironmentException, MachineChoice
from .c import CCompiler
from .compilers import ClangCompiler, GnuCompiler
from .clike import CLikeCompiler
from .compilers import Compiler, ClangCompiler, GnuCompiler
class ObjCCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
class ObjCCompiler(CLikeCompiler, Compiler):
def __init__(self, exelist, version, is_cross: bool, exe_wrap: typing.Optional[str]):
self.language = 'objc'
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
Compiler.__init__(self, exelist, version)
CLikeCompiler.__init__(self, is_cross, exe_wrap)
def get_display_language(self):
return 'Objective-C'

@ -13,16 +13,18 @@
# limitations under the License.
import os.path, subprocess
import typing
from ..mesonlib import EnvironmentException, MachineChoice
from .cpp import CPPCompiler
from .compilers import ClangCompiler, GnuCompiler
from .clike import CLikeCompiler
from .compilers import Compiler, ClangCompiler, GnuCompiler
class ObjCPPCompiler(CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
class ObjCPPCompiler(CLikeCompiler, Compiler):
def __init__(self, exelist, version, is_cross: bool, exe_wrap: typing.Optional[str]):
self.language = 'objcpp'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
Compiler.__init__(self, exelist, version)
CLikeCompiler.__init__(self, is_cross, exe_wrap)
def get_display_language(self):
return 'Objective-C++'

@ -61,8 +61,6 @@ from .compilers import (
IntelCCompiler,
IntelCPPCompiler,
IntelFortranCompiler,
IntelClCCompiler,
IntelClCPPCompiler,
JavaCompiler,
MonoCompiler,
CudaCompiler,
@ -681,7 +679,6 @@ class Environment:
arg = '-v'
else:
arg = '--version'
try:
p, out, err = Popen_safe(compiler + [arg])
except OSError as e:
@ -690,11 +687,6 @@ class Environment:
if 'ccrx' in compiler[0]:
out = err
if 'icl' in compiler[0]:
# https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-alphabetical-list-of-compiler-options
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-logo
# most consistent way for ICL is to just let compiler error and tell version
out = err
full_version = out.split('\n', 1)[0]
version = search_version(out)
@ -782,9 +774,9 @@ class Environment:
return cls(compiler, version, is_cross, exe_wrap, target)
if 'PGI Compilers' in out:
if mesonlib.for_darwin(is_cross, self):
if mesonlib.for_darwin(want_cross, self):
compiler_type = CompilerType.PGI_OSX
elif mesonlib.for_windows(is_cross, self):
elif mesonlib.for_windows(want_cross, self):
compiler_type = CompilerType.PGI_WIN
else:
compiler_type = CompilerType.PGI_STANDARD
@ -794,15 +786,12 @@ class Environment:
if mesonlib.for_darwin(want_cross, self):
compiler_type = CompilerType.ICC_OSX
elif mesonlib.for_windows(want_cross, self):
raise EnvironmentException('At the time of authoring, there was no ICC for Windows')
# TODO: fix ICC on Windows
compiler_type = CompilerType.ICC_WIN
else:
compiler_type = CompilerType.ICC_STANDARD
cls = IntelCCompiler if lang == 'c' else IntelCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
if out.startswith('Intel(R) C++') and mesonlib.for_windows(want_cross, self):
cls = IntelClCCompiler if lang == 'c' else IntelClCPPCompiler
target = 'x64' if 'Intel(R) 64 Compiler' in out else 'x86'
return cls(compiler, version, is_cross, exe_wrap, target)
if 'ARM' in out:
compiler_type = CompilerType.ARM_WIN
cls = ArmCCompiler if lang == 'c' else ArmCPPCompiler
@ -867,13 +856,6 @@ class Environment:
popen_exceptions[' '.join(compiler + [arg])] = e
continue
if mesonlib.for_windows(is_cross, self):
if 'ifort' in compiler[0]:
# https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-alphabetical-list-of-compiler-options
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-logo
# most consistent way for ICL is to just let compiler error and tell version
out = err
version = search_version(out)
full_version = out.split('\n', 1)[0]
@ -904,16 +886,16 @@ class Environment:
version = search_version(err)
return SunFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
if 'ifort (IFORT)' in out or out.startswith('Intel(R) Visual Fortran'):
if 'ifort (IFORT)' in out:
return IntelFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
if 'PathScale EKOPath(tm)' in err:
return PathScaleFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
if 'PGI Compilers' in out:
if mesonlib.for_darwin(is_cross, self):
if mesonlib.for_darwin(want_cross, self):
compiler_type = CompilerType.PGI_OSX
elif mesonlib.for_windows(is_cross, self):
elif mesonlib.for_windows(want_cross, self):
compiler_type = CompilerType.PGI_WIN
else:
compiler_type = CompilerType.PGI_STANDARD
@ -1073,8 +1055,9 @@ class Environment:
# 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]))
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):
@ -1175,7 +1158,7 @@ class Environment:
linkers = [self.cuda_static_linker, self.default_static_linker]
elif evar in os.environ:
linkers = [shlex.split(os.environ[evar])]
elif isinstance(compiler, compilers.VisualStudioCCompiler):
elif isinstance(compiler, compilers.VisualStudioLikeCompiler):
linkers = [self.vs_static_linker, self.clang_cl_static_linker]
elif isinstance(compiler, compilers.GnuCompiler):
# Use gcc-ar if available; needed for LTO

@ -3421,8 +3421,10 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
for s in raw_sources:
if isinstance(s, mesonlib.File):
sources.append(s)
else:
elif isinstance(s, str):
source_strings.append(s)
else:
raise InvalidArguments('Argument {!r} must be string or file.'.format(s))
sources += self.source_strings_to_files(source_strings)
install_dir = kwargs.get('install_dir', None)
if not isinstance(install_dir, (str, type(None))):

@ -191,7 +191,7 @@ class MesonApp:
# Print all default option values that don't match the current value
for def_opt_name, def_opt_value, cur_opt_value in intr.get_non_matching_default_options():
mlog.log('Option', mlog.bold(def_opt_name), 'is:',
mlog.bold(make_lower_case(cur_opt_value.printable_value())),
mlog.bold('{}'.format(make_lower_case(cur_opt_value.printable_value()))),
'[default: {}]'.format(make_lower_case(def_opt_value)))
try:
dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat')

@ -1939,8 +1939,8 @@ class AllPlatformTests(BasePlatformTests):
gnu = mesonbuild.compilers.GnuCompiler
clang = mesonbuild.compilers.ClangCompiler
intel = mesonbuild.compilers.IntelCompiler
msvc = mesonbuild.compilers.VisualStudioCCompiler
clangcl = mesonbuild.compilers.ClangClCCompiler
msvc = (mesonbuild.compilers.VisualStudioCCompiler, mesonbuild.compilers.VisualStudioCPPCompiler)
clangcl = (mesonbuild.compilers.ClangClCCompiler, mesonbuild.compilers.ClangClCPPCompiler)
ar = mesonbuild.linkers.ArLinker
lib = mesonbuild.linkers.VisualStudioLinker
langs = [('c', 'CC'), ('cpp', 'CXX')]

@ -8,13 +8,10 @@ project('default options', 'cpp', 'c', default_options : [
assert(get_option('buildtype') == 'debugoptimized', 'Build type default value wrong.')
if meson.get_compiler('cpp').get_argument_syntax() == 'msvc'
cpp_eh = get_option('cpp_eh')
assert(cpp_eh == 'none', 'MSVC eh value is "' + cpp_eh + '" instead of "none"')
else
cpp_std = get_option('cpp_std')
assert(cpp_std == 'c++11', 'C++ std value is "' + cpp_std + '" instead of c++11.')
endif
cpp_eh = get_option('cpp_eh')
assert(cpp_eh == 'none', 'EH value is "' + cpp_eh + '" instead of "none"')
cpp_std = get_option('cpp_std')
assert(cpp_std == 'c++11', 'C++ std value is "' + cpp_std + '" instead of c++11.')
w_level = get_option('warning_level')
assert(w_level == '3', 'warning level "' + w_level + '" instead of "3"')

@ -0,0 +1 @@
Some data which gets processed before installation

@ -0,0 +1,11 @@
project('custom target install data')
preproc = find_program('preproc.py')
t = custom_target('Info.plist',
command: [preproc, '@INPUT@', '@OUTPUT@'],
input: 'Info.plist.cpp',
output: 'Info.plist',
)
install_data(t)

@ -0,0 +1,13 @@
#!/usr/bin/env python3
import sys
if len(sys.argv) != 3:
print(sys.argv[0], '<input>', '<output>')
inf = sys.argv[1]
outf = sys.argv[2]
with open(outf, 'wb') as o:
with open(inf, 'rb') as i:
o.write(i.read())
Loading…
Cancel
Save