Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support lists for ObjC and ObjC++ standards #13642

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 14 additions & 64 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 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 @@ -46,9 +47,9 @@
else:
CompilerMixinBase = object

_ALL_STDS = ['c89', 'c9x', 'c90', 'c99', 'c1x', 'c11', 'c17', 'c18', 'c2x', 'c23']
_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']
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 @@ -97,45 +98,12 @@
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'

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']
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):
Dismissed Show dismissed Hide dismissed

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 @@ -188,18 +156,14 @@
id = 'armltdclang'


class AppleClangCCompiler(AppleCompilerMixin, ClangCCompiler):
class AppleClangCCompiler(AppleCompilerMixin, AppleCStdsMixin, ClangCCompiler):
Dismissed Show dismissed Hide dismissed

"""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 @@ -268,11 +232,8 @@
return []


class GnuCCompiler(GnuCompiler, CCompiler):
class GnuCCompiler(GnuCStds, GnuCompiler, CCompiler):
Dismissed Show dismissed Hide dismissed

_C18_VERSION = '>=8.0.0'
_C2X_VERSION = '>=9.0.0'
_C23_VERSION = '>=14.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 @@ -294,23 +255,12 @@
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']
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 Win libraries to link against',
gnu_winlibs),
)
Expand Down Expand Up @@ -508,7 +458,7 @@
return args


class ClangClCCompiler(_ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
class ClangClCCompiler(ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
Dismissed Show dismissed Hide dismissed
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
54 changes: 13 additions & 41 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 @@
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 @@
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):
Fixed Show fixed Hide fixed
Dismissed Show dismissed Hide dismissed

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 @@
'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 @@
'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 @@ -338,12 +325,8 @@
id = 'armltdclang'


class AppleClangCPPCompiler(AppleCompilerMixin, ClangCPPCompiler):

_CPP23_VERSION = '>=13.0.0'
# TODO: We don't know which XCode version will include LLVM 17 yet, so
# use something absurd.
_CPP26_VERSION = '>=99.0.0'
class AppleClangCPPCompiler(AppleCompilerMixin, AppleCPPStdsMixin, ClangCPPCompiler):
Dismissed Show dismissed Hide dismissed
pass


class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):
Expand Down Expand Up @@ -423,7 +406,7 @@
return []


class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler):
class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler):
Dismissed Show dismissed Hide dismissed
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 @@ -443,7 +426,7 @@

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 @@ -460,17 +443,6 @@
'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
19 changes: 19 additions & 0 deletions mesonbuild/compilers/mixins/apple.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,22 @@ def openmp_link_flags(self, env: Environment) -> T.List[str]:
def get_prelink_args(self, prelink_name: str, obj_list: T.List[str]) -> T.List[str]:
# The objects are prelinked through the compiler, which injects -lSystem
return ['-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'
# TODO: We don't know which XCode version will include LLVM 17 yet, so
# use something absurd.
_CPP26_VERSION = '>=99.0.0'
67 changes: 67 additions & 0 deletions mesonbuild/compilers/mixins/clang.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@
import typing as T

from ... import mesonlib
from ... import options
from ...linkers.linkers import AppleDynamicLinker, ClangClDynamicLinker, LLVMDynamicLinker, GnuGoldDynamicLinker, \
MoldDynamicLinker, MSVCDynamicLinker
from ...options import OptionKey
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler

if T.TYPE_CHECKING:
from ...coredata import MutableKeyedOptionDictType
from ...environment import Environment
from ...dependencies import Dependency # noqa: F401
from ..compilers import Compiler

CompilerMixinBase = Compiler
else:
CompilerMixinBase = object

clang_color_args: T.Dict[str, T.List[str]] = {
'auto': ['-fdiagnostics-color=auto'],
Expand Down Expand Up @@ -204,3 +211,63 @@ def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default',
raise mesonlib.MesonException('clang support for LTO threads requires clang >=4.0')
args.append(f'-flto-jobs={threads}')
return args


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'

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 mesonlib.version_compare(self.version, self._C17_VERSION):
stds += ['c17']
if mesonlib.version_compare(self.version, self._C18_VERSION):
stds += ['c18']
if mesonlib.version_compare(self.version, self._C2X_VERSION):
stds += ['c2x']
if mesonlib.version_compare(self.version, self._C23_VERSION):
stds += ['c23']
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 ClangCPPStds(CompilerMixinBase):

"""Mixin class for clang based compilers for setting C++ standards.

This is used by the ClangCPPCompiler
"""

_CPP23_VERSION = '>=12.0.0'
_CPP26_VERSION = '>=17.0.0'

def get_options(self) -> MutableKeyedOptionDictType:
opts = super().get_options()
stds = [
'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
'c++20',
]
if mesonlib.version_compare(self.version, self._CPP23_VERSION):
stds.append('c++23')
if mesonlib.version_compare(self.version, self._CPP26_VERSION):
stds.append('c++26')
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
Loading
Loading