Skip to content

Commit

Permalink
Merge pull request #13642 from dcbaker/submit/fix-objc-standards
Browse files Browse the repository at this point in the history
Support lists for ObjC and ObjC++ standards
  • Loading branch information
jpakkane authored Jan 28, 2025
2 parents 7bcf38d + 1eaab02 commit b55cef0
Show file tree
Hide file tree
Showing 14 changed files with 331 additions and 177 deletions.
84 changes: 14 additions & 70 deletions mesonbuild/compilers/c.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2012-2020 The Meson development team
# Copyright © 2024-2025 Intel Corporation

from __future__ import annotations

Expand All @@ -10,18 +11,18 @@
from .. import mlog
from ..mesonlib import MesonException, version_compare
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .mixins.apple import AppleCompilerMixin
from .mixins.apple import AppleCompilerMixin, AppleCStdsMixin
from .mixins.clike import CLikeCompiler
from .mixins.ccrx import CcrxCompiler
from .mixins.xc16 import Xc16Compiler
from .mixins.compcert import CompCertCompiler
from .mixins.ti import TICompiler
from .mixins.arm import ArmCompiler, ArmclangCompiler
from .mixins.visualstudio import MSVCCompiler, ClangClCompiler
from .mixins.gnu import GnuCompiler
from .mixins.gnu import GnuCompiler, GnuCStds
from .mixins.gnu import gnu_common_warning_args, gnu_c_warning_args
from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler
from .mixins.clang import ClangCompiler
from .mixins.clang import ClangCompiler, ClangCStds
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
Expand All @@ -47,9 +48,9 @@
else:
CompilerMixinBase = object

_ALL_STDS = ['c89', 'c9x', 'c90', 'c99', 'c1x', 'c11', 'c17', 'c18', 'c2x', 'c23', 'c2y']
_ALL_STDS += [f'gnu{std[1:]}' for std in _ALL_STDS]
_ALL_STDS += ['iso9899:1990', 'iso9899:199409', 'iso9899:1999', 'iso9899:2011', 'iso9899:2017', 'iso9899:2018']
ALL_STDS = ['c89', 'c9x', 'c90', 'c99', 'c1x', 'c11', 'c17', 'c18', 'c2x', 'c23', 'c2y']
ALL_STDS += [f'gnu{std[1:]}' for std in ALL_STDS]
ALL_STDS += ['iso9899:1990', 'iso9899:199409', 'iso9899:1999', 'iso9899:2011', 'iso9899:2017', 'iso9899:2018']


class CCompiler(CLikeCompiler, Compiler):
Expand Down Expand Up @@ -98,48 +99,12 @@ def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
key = self.form_compileropt_key('std')
opts.update({
key: options.UserStdOption('C', _ALL_STDS),
key: options.UserStdOption('C', ALL_STDS),
})
return opts


class _ClangCStds(CompilerMixinBase):

"""Mixin class for clang based compilers for setting C standards.
This is used by both ClangCCompiler and ClangClCompiler, as they share
the same versions
"""

_C17_VERSION = '>=6.0.0'
_C18_VERSION = '>=8.0.0'
_C2X_VERSION = '>=9.0.0'
_C23_VERSION = '>=18.0.0'
_C2Y_VERSION = '>=19.0.0'

def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
stds = ['c89', 'c99', 'c11']
# https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html
# https://en.wikipedia.org/wiki/Xcode#Latest_versions
if version_compare(self.version, self._C17_VERSION):
stds += ['c17']
if version_compare(self.version, self._C18_VERSION):
stds += ['c18']
if version_compare(self.version, self._C2X_VERSION):
stds += ['c2x']
if version_compare(self.version, self._C23_VERSION):
stds += ['c23']
if version_compare(self.version, self._C2Y_VERSION):
stds += ['c2y']
key = self.form_compileropt_key('std')
std_opt = opts[key]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(stds, gnu=True)
return opts


class ClangCCompiler(_ClangCStds, ClangCompiler, CCompiler):
class ClangCCompiler(ClangCStds, ClangCompiler, CCompiler):

def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo',
Expand Down Expand Up @@ -192,18 +157,14 @@ class ArmLtdClangCCompiler(ClangCCompiler):
id = 'armltdclang'


class AppleClangCCompiler(AppleCompilerMixin, ClangCCompiler):
class AppleClangCCompiler(AppleCompilerMixin, AppleCStdsMixin, ClangCCompiler):

"""Handle the differences between Apple Clang and Vanilla Clang.
Right now this just handles the differences between the versions that new
C standards were added.
"""

_C17_VERSION = '>=10.0.0'
_C18_VERSION = '>=11.0.0'
_C2X_VERSION = '>=11.0.0'


class EmscriptenCCompiler(EmscriptenMixin, ClangCCompiler):

Expand Down Expand Up @@ -272,12 +233,8 @@ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []


class GnuCCompiler(GnuCompiler, CCompiler):
class GnuCCompiler(GnuCStds, GnuCompiler, CCompiler):

_C18_VERSION = '>=8.0.0'
_C2X_VERSION = '>=9.0.0'
_C23_VERSION = '>=14.0.0'
_C2Y_VERSION = '>=15.0.0'
_INVALID_PCH_VERSION = ">=3.4.0"

def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
Expand All @@ -299,25 +256,12 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_
self.supported_warn_args(gnu_c_warning_args))}

def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
stds = ['c89', 'c99', 'c11']
if version_compare(self.version, self._C18_VERSION):
stds += ['c17', 'c18']
if version_compare(self.version, self._C2X_VERSION):
stds += ['c2x']
if version_compare(self.version, self._C23_VERSION):
stds += ['c23']
if version_compare(self.version, self._C2Y_VERSION):
stds += ['c2y']
key = self.form_compileropt_key('std')
std_opt = opts[key]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(stds, gnu=True)
opts = super().get_options()
if self.info.is_windows() or self.info.is_cygwin():
self.update_options(
opts,
self.create_option(options.UserArrayOption,
key.evolve('c_winlibs'),
self.form_compileropt_key('winlibs'),
'Standard Windows libs to link against',
gnu_winlibs),
)
Expand Down Expand Up @@ -523,7 +467,7 @@ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]
return args


class ClangClCCompiler(_ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
class ClangClCCompiler(ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo', target: str,
linker: T.Optional['DynamicLinker'] = None,
Expand Down
52 changes: 13 additions & 39 deletions mesonbuild/compilers/cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
CompileCheckMode,
)
from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES
from .mixins.apple import AppleCompilerMixin
from .mixins.apple import AppleCompilerMixin, AppleCPPStdsMixin
from .mixins.clike import CLikeCompiler
from .mixins.ccrx import CcrxCompiler
from .mixins.ti import TICompiler
from .mixins.arm import ArmCompiler, ArmclangCompiler
from .mixins.visualstudio import MSVCCompiler, ClangClCompiler
from .mixins.gnu import GnuCompiler, gnu_common_warning_args, gnu_cpp_warning_args
from .mixins.gnu import GnuCompiler, GnuCPPStds, gnu_common_warning_args, gnu_cpp_warning_args
from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler
from .mixins.clang import ClangCompiler
from .mixins.clang import ClangCompiler, ClangCPPStds
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
Expand All @@ -45,9 +45,9 @@
else:
CompilerMixinBase = object

_ALL_STDS = ['c++98', 'c++0x', 'c++03', 'c++1y', 'c++1z', 'c++11', 'c++14', 'c++17', 'c++2a', 'c++20', 'c++23', 'c++26']
_ALL_STDS += [f'gnu{std[1:]}' for std in _ALL_STDS]
_ALL_STDS += ['vc++11', 'vc++14', 'vc++17', 'vc++20', 'vc++latest', 'c++latest']
ALL_STDS = ['c++98', 'c++0x', 'c++03', 'c++1y', 'c++1z', 'c++11', 'c++14', 'c++17', 'c++2a', 'c++20', 'c++23', 'c++26']
ALL_STDS += [f'gnu{std[1:]}' for std in ALL_STDS]
ALL_STDS += ['vc++11', 'vc++14', 'vc++17', 'vc++20', 'vc++latest', 'c++latest']


def non_msvc_eh_options(eh: str, args: T.List[str]) -> None:
Expand Down Expand Up @@ -175,7 +175,7 @@ def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
key = self.form_compileropt_key('std')
opts.update({
key: options.UserStdOption('C++', _ALL_STDS),
key: options.UserStdOption('C++', ALL_STDS),
})
return opts

Expand Down Expand Up @@ -218,10 +218,7 @@ def language_stdlib_only_link_flags(self, env: Environment) -> T.List[str]:
raise MesonException('Could not detect either libc++ or libstdc++ as your C++ stdlib implementation.')


class ClangCPPCompiler(_StdCPPLibMixin, ClangCompiler, CPPCompiler):

_CPP23_VERSION = '>=12.0.0'
_CPP26_VERSION = '>=17.0.0'
class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler):

def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo',
Expand All @@ -239,7 +236,7 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_
'everything': ['-Weverything']}

def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CPPCompiler.get_options(self)
opts = super().get_options()
self.update_options(
opts,
self.create_option(options.UserComboOption,
Expand All @@ -256,16 +253,6 @@ def get_options(self) -> 'MutableKeyedOptionDictType':
'STL debug mode',
False),
)
cppstd_choices = [
'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 'c++20',
]
if version_compare(self.version, self._CPP23_VERSION):
cppstd_choices.append('c++23')
if version_compare(self.version, self._CPP26_VERSION):
cppstd_choices.append('c++26')
std_opt = opts[self.form_compileropt_key('std')]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(cppstd_choices, gnu=True)
if self.info.is_windows() or self.info.is_cygwin():
self.update_options(
opts,
Expand Down Expand Up @@ -344,10 +331,8 @@ class ArmLtdClangCPPCompiler(ClangCPPCompiler):
id = 'armltdclang'


class AppleClangCPPCompiler(AppleCompilerMixin, ClangCPPCompiler):

_CPP23_VERSION = '>=13.0.0'
_CPP26_VERSION = '>=16.0.0'
class AppleClangCPPCompiler(AppleCompilerMixin, AppleCPPStdsMixin, ClangCPPCompiler):
pass


class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):
Expand Down Expand Up @@ -436,7 +421,7 @@ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []


class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler):
class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler):
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo',
linker: T.Optional['DynamicLinker'] = None,
Expand All @@ -456,7 +441,7 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_

def get_options(self) -> 'MutableKeyedOptionDictType':
key = self.form_compileropt_key('std')
opts = CPPCompiler.get_options(self)
opts = super().get_options()
self.update_options(
opts,
self.create_option(options.UserComboOption,
Expand All @@ -473,17 +458,6 @@ def get_options(self) -> 'MutableKeyedOptionDictType':
'STL debug mode',
False),
)
cppstd_choices = [
'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z',
'c++2a', 'c++20',
]
if version_compare(self.version, '>=11.0.0'):
cppstd_choices.append('c++23')
if version_compare(self.version, '>=14.0.0'):
cppstd_choices.append('c++26')
std_opt = opts[key]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(cppstd_choices, gnu=True)
if self.info.is_windows() or self.info.is_cygwin():
self.update_options(
opts,
Expand Down
6 changes: 5 additions & 1 deletion mesonbuild/compilers/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,9 +897,13 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine:
version = _get_gnu_version_from_defines(defines)
comp = objc.GnuObjCCompiler if lang == 'objc' else objcpp.GnuObjCPPCompiler
linker = guess_nix_linker(env, compiler, comp, version, for_machine)
return comp(
c = comp(
ccache, compiler, version, for_machine, is_cross, info,
defines, linker=linker)
if not c.compiles('int main(void) { return 0; }', env)[0]:
popen_exceptions[join_args(compiler)] = f'GCC was not built with support for {"objective-c" if lang == "objc" else "objective-c++"}'
continue
return c
if 'clang' in out:
linker = None
defines = _get_clang_compiler_defines(compiler, lang)
Expand Down
19 changes: 18 additions & 1 deletion mesonbuild/compilers/mixins/apple.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright © 2024 Intel Corporation
# Copyright © 2024-2025 Intel Corporation

"""Provides mixins for Apple compilers."""

Expand Down Expand Up @@ -59,3 +59,20 @@ def openmp_link_flags(self, env: Environment) -> T.List[str]:
def get_prelink_args(self, prelink_name: str, obj_list: T.List[str]) -> T.Tuple[T.List[str], T.List[str]]:
# The objects are prelinked through the compiler, which injects -lSystem
return [prelink_name], ['-nostdlib', '-r', '-o', prelink_name] + obj_list


class AppleCStdsMixin(Compiler):

"""Provide version overrides for the Apple Compilers."""

_C17_VERSION = '>=10.0.0'
_C18_VERSION = '>=11.0.0'
_C2X_VERSION = '>=11.0.0'


class AppleCPPStdsMixin(Compiler):

"""Provide version overrides for the Apple C++ Compilers."""

_CPP23_VERSION = '>=13.0.0'
_CPP26_VERSION = '>=16.0.0'
Loading

0 comments on commit b55cef0

Please sign in to comment.