aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers/cpp.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/compilers/cpp.py')
-rw-r--r--mesonbuild/compilers/cpp.py202
1 files changed, 202 insertions, 0 deletions
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
new file mode 100644
index 0000000..6d50e57
--- /dev/null
+++ b/mesonbuild/compilers/cpp.py
@@ -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()