Merge pull request #4359 from dcbaker/icc-fixes

ICC fixes for Linux and MacOS
pull/4531/head
Dylan Baker 7 years ago committed by GitHub
commit 0092a7d3f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      mesonbuild/compilers/c.py
  2. 8
      mesonbuild/compilers/c_function_attributes.py
  3. 72
      mesonbuild/compilers/compilers.py
  4. 14
      mesonbuild/compilers/fortran.py
  5. 1
      mesonbuild/dependencies/misc.py
  6. 24
      run_unittests.py
  7. 4
      test cases/common/204 function attributes/meson.build
  8. 13
      test cases/fortran/9 cpp/meson.build

@ -157,26 +157,6 @@ class CCompiler(Compiler):
''' '''
return self.get_no_optimization_args() return self.get_no_optimization_args()
def get_allow_undefined_link_args(self):
'''
Get args for allowing undefined symbols when linking to a shared library
'''
if self.id in ('clang', 'gcc'):
if self.compiler_type.is_osx_compiler:
# Apple ld
return ['-Wl,-undefined,dynamic_lookup']
elif self.compiler_type.is_windows_compiler:
# For PE/COFF this is impossible
return []
else:
# GNU ld and LLVM lld
return ['-Wl,--allow-shlib-undefined']
elif isinstance(self, VisualStudioCCompiler):
# link.exe
return ['/FORCE:UNRESOLVED']
# FIXME: implement other linkers
return []
def get_output_args(self, target): def get_output_args(self, target):
return ['-o', target] return ['-o', target]
@ -413,12 +393,12 @@ class CCompiler(Compiler):
dependencies=dependencies) dependencies=dependencies)
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'): def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
if callable(extra_args):
extra_args = extra_args(mode)
if extra_args is None: if extra_args is None:
extra_args = [] extra_args = []
elif isinstance(extra_args, str): else:
extra_args = [extra_args] extra_args = listify(extra_args)
extra_args = listify([e(mode) if callable(e) else e for e in extra_args])
if dependencies is None: if dependencies is None:
dependencies = [] dependencies = []
elif not isinstance(dependencies, list): elif not isinstance(dependencies, list):
@ -1268,7 +1248,7 @@ class IntelCCompiler(IntelCompiler, CCompiler):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs) CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
IntelCompiler.__init__(self, compiler_type) IntelCompiler.__init__(self, compiler_type)
self.lang_header = 'c-header' self.lang_header = 'c-header'
default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages'] default_warn_args = ['-Wall', '-w3', '-diag-disable:remark']
self.warn_args = {'1': default_warn_args, self.warn_args = {'1': default_warn_args,
'2': default_warn_args + ['-Wextra'], '2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra']} '3': default_warn_args + ['-Wextra']}
@ -1597,11 +1577,17 @@ class VisualStudioCCompiler(CCompiler):
def get_argument_syntax(self): def get_argument_syntax(self):
return 'msvc' return 'msvc'
def get_allow_undefined_link_args(self):
# link.exe
return ['/FORCE:UNRESOLVED']
class ClangClCCompiler(VisualStudioCCompiler): class ClangClCCompiler(VisualStudioCCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, is_64): def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
super().__init__(exelist, version, is_cross, exe_wrap, is_64) super().__init__(exelist, version, is_cross, exe_wrap, is_64)
self.id = 'clang-cl' self.id = 'clang-cl'
class ArmCCompiler(ArmCompiler, CCompiler): class ArmCCompiler(ArmCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs): def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs) CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)

@ -91,10 +91,10 @@ C_FUNC_ATTRIBUTES = {
'used': 'used':
'int foo(void) __attribute__((used));', 'int foo(void) __attribute__((used));',
'visibility': ''' 'visibility': '''
int foo_def(void) __attribute__((visibility(("default")))); int foo_def(void) __attribute__((visibility("default")));
int foo_hid(void) __attribute__((visibility(("hidden")))); int foo_hid(void) __attribute__((visibility("hidden")));
int foo_int(void) __attribute__((visibility(("internal")))); int foo_int(void) __attribute__((visibility("internal")));
int foo_pro(void) __attribute__((visibility(("protected"))));''', int foo_pro(void) __attribute__((visibility("protected")));''',
'warning': 'warning':
'int foo(void) __attribute__((warning("")));', 'int foo(void) __attribute__((warning("")));',
'warn_unused_result': 'warn_unused_result':

@ -19,7 +19,10 @@ from ..linkers import StaticLinker
from .. import coredata from .. import coredata
from .. import mlog from .. import mlog
from .. import mesonlib from .. import mesonlib
from ..mesonlib import EnvironmentException, MesonException, OrderedSet, version_compare, Popen_safe from ..mesonlib import (
EnvironmentException, MesonException, OrderedSet, version_compare,
Popen_safe
)
"""This file contains the data files of all compilers Meson knows """This file contains the data files of all compilers Meson knows
about. To support a new compiler, add its information below. about. To support a new compiler, add its information below.
@ -454,9 +457,9 @@ def get_base_compile_args(options, compiler):
try: try:
pgo_val = options['b_pgo'].value pgo_val = options['b_pgo'].value
if pgo_val == 'generate': if pgo_val == 'generate':
args.append('-fprofile-generate') args.extend(compiler.get_profile_generate_args())
elif pgo_val == 'use': elif pgo_val == 'use':
args.extend(['-fprofile-use', '-fprofile-correction']) args.extend(compiler.get_profile_use_args())
except KeyError: except KeyError:
pass pass
try: try:
@ -500,9 +503,9 @@ def get_base_link_args(options, linker, is_shared_module):
try: try:
pgo_val = options['b_pgo'].value pgo_val = options['b_pgo'].value
if pgo_val == 'generate': if pgo_val == 'generate':
args.append('-fprofile-generate') args.extend(linker.get_profile_generate_args())
elif pgo_val == 'use': elif pgo_val == 'use':
args.extend(['-fprofile-use', '-fprofile-correction']) args.extend(linker.get_profile_use_args())
except KeyError: except KeyError:
pass pass
try: try:
@ -671,7 +674,6 @@ class CompilerArgs(list):
to recursively search for symbols in the libraries. This is not needed to recursively search for symbols in the libraries. This is not needed
with other linkers. with other linkers.
''' '''
# A standalone argument must never be deduplicated because it is # A standalone argument must never be deduplicated because it is
# defined by what comes _after_ it. Thus dedupping this: # defined by what comes _after_ it. Thus dedupping this:
# -D FOO -D BAR # -D FOO -D BAR
@ -1255,6 +1257,20 @@ class Compiler:
""" """
return 'other' return 'other'
def get_profile_generate_args(self):
raise EnvironmentException(
'%s does not support get_profile_generate_args ' % self.get_id())
def get_profile_use_args(self):
raise EnvironmentException(
'%s does not support get_profile_use_args ' % self.get_id())
def get_undefined_link_args(self):
'''
Get args for allowing undefined symbols when linking to a shared library
'''
return []
@enum.unique @enum.unique
class CompilerType(enum.Enum): class CompilerType(enum.Enum):
@ -1495,6 +1511,20 @@ class GnuLikeCompiler(abc.ABC):
def get_argument_syntax(self): def get_argument_syntax(self):
return 'gcc' return 'gcc'
def get_profile_generate_args(self):
return ['-fprofile-generate']
def get_profile_use_args(self):
return ['-fprofile-use', '-fprofile-correction']
def get_allow_undefined_link_args(self):
if self.compiler_type.is_osx_compiler:
# Apple ld
return ['-Wl,-undefined,dynamic_lookup']
else:
# GNU ld and LLVM lld
return ['-Wl,--allow-shlib-undefined']
class GnuCompiler(GnuLikeCompiler): class GnuCompiler(GnuLikeCompiler):
""" """
@ -1731,10 +1761,18 @@ class ArmclangCompiler:
return ['--symdefs=' + implibname] return ['--symdefs=' + implibname]
# Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1 # Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1, 19.0.0
class IntelCompiler(GnuLikeCompiler): class IntelCompiler(GnuLikeCompiler):
def __init__(self, compiler_type): def __init__(self, compiler_type):
super().__init__(compiler_type) super().__init__(compiler_type)
# As of 19.0.0 ICC doesn't have sanitizer, color, or lto support.
#
# It does have IPO, which serves much the same purpose as LOT, but
# there is an unfortunate rule for using IPO (you can't control the
# name of the output file) which break assumptions meson makes
self.base_options = ['b_pch', 'b_lundef', 'b_asneeded', 'b_pgo',
'b_coverage', 'b_ndebug', 'b_staticpic', 'b_pie']
self.id = 'intel' self.id = 'intel'
self.lang_header = 'none' self.lang_header = 'none'
@ -1757,9 +1795,23 @@ class IntelCompiler(GnuLikeCompiler):
else: else:
return ['-openmp'] return ['-openmp']
def has_arguments(self, args, env, code, mode): def compiles(self, *args, **kwargs):
# -diag-error 10148 is required to catch invalid -W options # This covers a case that .get('foo', []) doesn't, that extra_args is
return super().has_arguments(args + ['-diag-error', '10006', '-diag-error', '10148'], env, code, mode) # defined and is None
extra_args = kwargs.get('extra_args') or []
kwargs['extra_args'] = [
extra_args,
'-diag-error', '10006', # ignoring unknown option
'-diag-error', '10148', # Option not supported
'-diag-error', '1292', # unknown __attribute__
]
return super().compiles(*args, **kwargs)
def get_profile_generate_args(self):
return ['-prof-gen=threadsafe']
def get_profile_use_args(self):
return ['-prof-use']
class ArmCompiler: class ArmCompiler:

@ -144,9 +144,6 @@ end program prog
def get_compiler_check_args(self): def get_compiler_check_args(self):
return CCompiler.get_compiler_check_args(self) return CCompiler.get_compiler_check_args(self)
def get_allow_undefined_link_args(self):
return CCompiler.get_allow_undefined_link_args(self)
def get_output_args(self, target): def get_output_args(self, target):
return CCompiler.get_output_args(self, target) return CCompiler.get_output_args(self, target)
@ -172,7 +169,7 @@ end program prog
return ('-I', ) return ('-I', )
def get_module_outdir_args(self, path): def get_module_outdir_args(self, path):
return ['-module' + path] return ['-module', path]
def module_name_to_filename(self, module_name): def module_name_to_filename(self, module_name):
return module_name.lower() + '.mod' return module_name.lower() + '.mod'
@ -342,6 +339,15 @@ class IntelFortranCompiler(IntelCompiler, FortranCompiler):
def get_preprocess_only_args(self): def get_preprocess_only_args(self):
return ['-cpp', '-EP'] return ['-cpp', '-EP']
def get_always_args(self):
"""Ifort doesn't have -pipe."""
val = super().get_always_args()
val.remove('-pipe')
return val
def language_stdlib_only_link_flags(self):
return ['-lifcore', '-limf']
class PathScaleFortranCompiler(FortranCompiler): class PathScaleFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags): def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):

@ -235,6 +235,7 @@ class OpenMPDependency(ExternalDependency):
# Map date of specification release (which is the macro value) to a version. # Map date of specification release (which is the macro value) to a version.
VERSIONS = { VERSIONS = {
'201811': '5.0', '201811': '5.0',
'201611': '5.0-revision1', # This is supported by ICC 19.x
'201511': '4.5', '201511': '4.5',
'201307': '4.0', '201307': '4.0',
'201107': '3.1', '201107': '3.1',

@ -144,6 +144,24 @@ def skip_if_env_value(value):
return wrapped return wrapped
return wrapper return wrapper
def skip_if_not_base_option(feature):
"""Skip tests if The compiler does not support a given base option.
for example, ICC doesn't currently support b_sanitize.
"""
def actual(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
env = get_fake_env('', '', '')
cc = env.detect_c_compiler(False)
if feature not in cc.base_options:
raise unittest.SkipTest(
'{} not available with {}'.format(feature, cc.id))
return f(*args, **kwargs)
return wrapped
return actual
class PatchModule: class PatchModule:
''' '''
Fancy monkey-patching! Whee! Can't use mock.patch because it only Fancy monkey-patching! Whee! Can't use mock.patch because it only
@ -3522,6 +3540,7 @@ class LinuxlikeTests(BasePlatformTests):
self.assertRegex('\n'.join(mesonlog), self.assertRegex('\n'.join(mesonlog),
r'Dependency qt5 \(modules: Core\) found: YES 5.* \(pkg-config\)\n') r'Dependency qt5 \(modules: Core\) found: YES 5.* \(pkg-config\)\n')
@skip_if_not_base_option('b_sanitize')
def test_generate_gir_with_address_sanitizer(self): def test_generate_gir_with_address_sanitizer(self):
if is_cygwin(): if is_cygwin():
raise unittest.SkipTest('asan not available on Cygwin') raise unittest.SkipTest('asan not available on Cygwin')
@ -3899,7 +3918,7 @@ class LinuxlikeTests(BasePlatformTests):
# when all tests are run (but works when only this test is run), # when all tests are run (but works when only this test is run),
# but doing this explicitly works. # but doing this explicitly works.
env = os.environ.copy() env = os.environ.copy()
env['LD_LIBRARY_PATH'] = installed_libdir env['LD_LIBRARY_PATH'] = ':'.join([installed_libdir, env.get('LD_LIBRARY_PATH', '')])
self.assertEqual(subprocess.call(installed_exe, env=env), 0) self.assertEqual(subprocess.call(installed_exe, env=env), 0)
# Ensure that introspect --installed works # Ensure that introspect --installed works
installed = self.introspect('--installed') installed = self.introspect('--installed')
@ -3984,6 +4003,7 @@ class LinuxlikeTests(BasePlatformTests):
install_rpath = get_rpath(os.path.join(self.installdir, 'usr/bin/progcxx')) install_rpath = get_rpath(os.path.join(self.installdir, 'usr/bin/progcxx'))
self.assertEqual(install_rpath, 'baz') self.assertEqual(install_rpath, 'baz')
@skip_if_not_base_option('b_sanitize')
def test_pch_with_address_sanitizer(self): def test_pch_with_address_sanitizer(self):
if is_cygwin(): if is_cygwin():
raise unittest.SkipTest('asan not available on Cygwin') raise unittest.SkipTest('asan not available on Cygwin')
@ -4099,7 +4119,7 @@ endian = 'little'
self.init(testdir2) self.init(testdir2)
self.build() self.build()
myenv = os.environ.copy() myenv = os.environ.copy()
myenv['LD_LIBRARY_PATH'] = lib_dir myenv['LD_LIBRARY_PATH'] = ':'.join([lib_dir, myenv.get('LD_LIBRARY_PATH', '')])
if is_cygwin(): if is_cygwin():
bin_dir = os.path.join(tempdirname, 'bin') bin_dir = os.path.join(tempdirname, 'bin')
myenv['PATH'] = bin_dir + os.pathsep + myenv['PATH'] myenv['PATH'] = bin_dir + os.pathsep + myenv['PATH']

@ -63,7 +63,7 @@ if host_machine.system() != 'darwin'
attributes += 'visibility' attributes += 'visibility'
endif endif
if c.get_id() == 'gcc' if ['gcc', 'intel'].contains(c.get_id())
# not supported by clang as of 5.0.0 (at least up to 6.0.1) # not supported by clang as of 5.0.0 (at least up to 6.0.1)
attributes += 'artificial' attributes += 'artificial'
attributes += 'error' attributes += 'error'
@ -73,7 +73,7 @@ if c.get_id() == 'gcc'
attributes += 'optimize' attributes += 'optimize'
attributes += 'warning' attributes += 'warning'
if c.version().version_compare('>= 7.0.0') if c.get_id() == 'gcc' and c.version().version_compare('>= 7.0.0')
attributes += 'fallthrough' attributes += 'fallthrough'
endif endif
endif endif

@ -6,5 +6,16 @@ if cpp.get_id() == 'clang'
error('MESON_SKIP_TEST Clang C++ does not find -lgfortran for some reason.') error('MESON_SKIP_TEST Clang C++ does not find -lgfortran for some reason.')
endif endif
e = executable('cppfort', 'main.cpp', 'fortran.f') fc = meson.get_compiler('fortran')
link_with = []
if fc.get_id() == 'intel'
link_with += fc.find_library('ifport')
endif
e = executable(
'cppfort',
['main.cpp', 'fortran.f'],
dependencies : [link_with],
)
test('C++ FORTRAN', e) test('C++ FORTRAN', e)

Loading…
Cancel
Save