aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/compilers/c.py17
-rw-r--r--mesonbuild/compilers/compilers.py52
-rw-r--r--mesonbuild/compilers/cpp.py4
-rw-r--r--mesonbuild/environment.py6
-rw-r--r--mesonbuild/interpreter.py15
-rw-r--r--mesonbuild/modules/unstable_simd.py72
6 files changed, 161 insertions, 5 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index cf9d1ee..593366a 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -25,6 +25,8 @@ from .compilers import (
msvc_buildtype_args,
msvc_buildtype_linker_args,
msvc_winlibs,
+ vs32_instruction_set_args,
+ vs64_instruction_set_args,
ClangCompiler,
Compiler,
CompilerArgs,
@@ -810,7 +812,7 @@ class VisualStudioCCompiler(CCompiler):
std_warn_args = ['/W3']
std_opt_args = ['/O2']
- def __init__(self, exelist, version, is_cross, exe_wrap):
+ def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.id = 'msvc'
# /showIncludes is needed for build dependency tracking in Ninja
@@ -820,6 +822,7 @@ class VisualStudioCCompiler(CCompiler):
'2': ['/W3'],
'3': ['/W4']}
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
+ self.is_64 = is_64
# Override CCompiler.get_always_args
def get_always_args(self):
@@ -1005,3 +1008,15 @@ class VisualStudioCCompiler(CCompiler):
if not isinstance(args, list):
args = [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.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)
+
+
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index a8ec5e3..0be3908 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -228,6 +228,43 @@ base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled he
True),
}
+gnulike_instruction_set_args = {'mmx': ['-mmmx'],
+ 'sse': ['-msse'],
+ 'sse2': ['-msse2'],
+ 'sse3': ['-msse3'],
+ 'ssse3': ['-mssse3'],
+ 'sse41': ['-msse4.1'],
+ 'sse42': ['-msse4.2'],
+ 'avx': ['-mavx'],
+ 'avx2': ['-mavx2'],
+ 'neon': ['-mfpu=neon'],
+ }
+
+vs32_instruction_set_args = {'mmx': ['/arch:SSE'], # There does not seem to be a flag just for MMX
+ 'sse': ['/arch:SSE'],
+ 'sse2': ['/arch:SSE2'],
+ 'sse3': ['/arch:AVX'], # VS leaped from SSE2 directly to AVX.
+ 'sse41': ['/arch:AVX'],
+ 'sse42': ['/arch:AVX'],
+ 'avx': ['/arch:AVX'],
+ 'avx2': ['/arch:AVX2'],
+ 'neon': None,
+}
+
+# The 64 bit compiler defaults to /arch:avx.
+vs64_instruction_set_args = {'mmx': ['/arch:AVX'],
+ 'sse': ['/arch:AVX'],
+ 'sse2': ['/arch:AVX'],
+ 'sse3': ['/arch:AVX'],
+ 'ssse3': ['/arch:AVX'],
+ 'sse41': ['/arch:AVX'],
+ 'sse42': ['/arch:AVX'],
+ 'avx': ['/arch:AVX'],
+ 'avx2': ['/arch:AVX2'],
+ 'neon': None,
+ }
+
+
def sanitizer_compile_args(value):
if value == 'none':
return []
@@ -755,6 +792,12 @@ class Compiler:
return []
raise EnvironmentException('Language %s does not support linking whole archives.' % self.get_display_language())
+ # Compiler arguments needed to enable the given instruction set.
+ # May be [] meaning nothing needed or None meaning the given set
+ # is not supported.
+ def get_instruction_set_args(self, instruction_set):
+ return None
+
def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath):
if not rpath_paths and not install_rpath:
return []
@@ -933,6 +976,10 @@ class GnuCompiler:
return ['-mwindows']
return []
+ def get_instruction_set_args(self, instruction_set):
+ return gnulike_instruction_set_args.get(instruction_set, None)
+
+
class ClangCompiler:
def __init__(self, clang_type):
self.id = 'clang'
@@ -983,7 +1030,7 @@ class ClangCompiler:
def has_multi_arguments(self, args, env):
return super().has_multi_arguments(
- ['-Werror=unknown-warning-option'] + args,
+ ['-Werror=unknown-warning-option', '-Werror=unused-command-line-argument'] + args,
env)
def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None):
@@ -1010,6 +1057,9 @@ class ClangCompiler:
return result
return ['-Wl,--whole-archive'] + args + ['-Wl,--no-whole-archive']
+ def get_instruction_set_args(self, instruction_set):
+ return gnulike_instruction_set_args.get(instruction_set, None)
+
# Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1
class IntelCompiler:
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 01525b0..a8fc8a3 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -173,10 +173,10 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
- def __init__(self, exelist, version, is_cross, exe_wrap):
+ def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
self.language = 'cpp'
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
- VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
+ VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap, is_64)
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
def get_options(self):
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index a6da3f9..dd9f56e 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -534,8 +534,12 @@ class Environment:
# Visual Studio prints version number to stderr but
# everything else to stdout. Why? Lord only knows.
version = search_version(err)
+ if not err or not err.split('\n')[0]:
+ m = 'Failed to detect MSVC compiler arch: stderr was\n{!r}'
+ raise EnvironmentException(m.format(err))
+ is_64 = err.split('\n')[0].endswith(' x64')
cls = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler
- return cls(compiler, version, is_cross, exe_wrap)
+ return cls(compiler, version, is_cross, exe_wrap, is_64)
if '(ICC)' in out:
# TODO: add microsoft add check OSX
inteltype = ICC_STANDARD
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 63cdf9e..359dd17 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -161,6 +161,7 @@ class ConfigurationDataHolder(MutableInterpreterObject):
'set_quoted': self.set_quoted_method,
'has': self.has_method,
'get': self.get_method,
+ 'merge_from': self.merge_from_method,
})
def is_used(self):
@@ -221,6 +222,16 @@ class ConfigurationDataHolder(MutableInterpreterObject):
def keys(self):
return self.held_object.values.keys()
+ def merge_from_method(self, args, kwargs):
+ if len(args) != 1:
+ raise InterpreterException('Merge_from takes one positional argument.')
+ from_object = args[0]
+ if not isinstance(from_object, ConfigurationDataHolder):
+ raise InterpreterException('Merge_from argument must be a configuration data object.')
+ from_object = from_object.held_object
+ for k, v in from_object.values.items():
+ self.held_object.values[k] = v
+
# Interpreter objects can not be pickled so we must have
# these wrappers.
@@ -1479,6 +1490,10 @@ class Interpreter(InterpreterBase):
if len(args) != 1:
raise InvalidCode('Import takes one argument.')
modname = args[0]
+ if modname.startswith('unstable-'):
+ plainname = modname.split('-', 1)[1]
+ mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname)
+ modname = 'unstable_' + plainname
if modname not in self.environment.coredata.modules:
try:
module = importlib.import_module('mesonbuild.modules.' + modname)
diff --git a/mesonbuild/modules/unstable_simd.py b/mesonbuild/modules/unstable_simd.py
new file mode 100644
index 0000000..4aebc02
--- /dev/null
+++ b/mesonbuild/modules/unstable_simd.py
@@ -0,0 +1,72 @@
+# 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.
+
+from .. import mesonlib, compilers, mlog
+
+from . import ExtensionModule
+
+class SimdModule(ExtensionModule):
+
+ def __init__(self):
+ super().__init__()
+ self.snippets.add('check')
+ # FIXME add Altivec and AVX512.
+ self.isets = ('mmx',
+ 'sse',
+ 'sse2',
+ 'sse3',
+ 'ssse3',
+ 'sse41',
+ 'sse42',
+ 'avx',
+ 'avx2',
+ 'neon',
+ )
+
+ def check(self, interpreter, state, args, kwargs):
+ result = []
+ if len(args) != 1:
+ raise mesonlib.MesonException('Check requires one argument, a name prefix for checks.')
+ prefix = args[0]
+ if not isinstance(prefix, str):
+ raise mesonlib.MesonException('Argument must be a string.')
+ if 'compiler' not in kwargs:
+ raise mesonlib.MesonException('Must specify compiler keyword')
+ compiler = kwargs['compiler'].compiler
+ if not isinstance(compiler, compilers.compilers.Compiler):
+ raise mesonlib.MesonException('Compiler argument must be a compiler object.')
+ cdata = interpreter.func_configuration_data(None, [], {})
+ conf = cdata.held_object
+ for iset in self.isets:
+ if iset not in kwargs:
+ continue
+ iset_fname = kwargs[iset] # Migth also be an array or Files. static_library will validate.
+ args = compiler.get_instruction_set_args(iset)
+ if args is None:
+ mlog.log('Compiler supports %s:' % iset, mlog.red('NO'))
+ continue
+ if len(args) > 0:
+ if not compiler.has_multi_arguments(args, state.environment):
+ mlog.log('Compiler supports %s:' % iset, mlog.red('NO'))
+ continue
+ mlog.log('Compiler supports %s:' % iset, mlog.green('YES'))
+ conf.values['HAVE_' + iset.upper()] = ('1', 'Compiler supports %s.' % iset)
+ libname = prefix + '_' + iset
+ lib_kwargs = {'sources': iset_fname,
+ compiler.get_language() + '_args': args}
+ result.append(interpreter.func_static_lib(None, [libname], lib_kwargs))
+ return [result, cdata]
+
+def initialize():
+ return SimdModule()