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

Feature/language #16028

Merged
merged 26 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4ce9f6c
wip
memsharded Feb 19, 2024
aaeaebe
Merge branch 'develop2' into feature/language
memsharded Mar 4, 2024
a4e18e2
wip
memsharded Mar 4, 2024
01d151c
Merge branch 'develop2' into feature/language
memsharded Apr 5, 2024
4ba8049
wip
memsharded Apr 5, 2024
69ee385
Test for BazelDeps in the build context (#16025)
ErniGH Apr 5, 2024
c8545d8
copy only if different (#16031)
memsharded Apr 8, 2024
7dbfb3d
allow conf in exports-sources and export (#16034)
memsharded Apr 8, 2024
d579c0f
refactor apple_min_version_flag() (#16017)
memsharded Apr 8, 2024
ce4f5df
Allow to unhide git url (#16038)
shoeffner Apr 8, 2024
2a87015
wip
memsharded Apr 9, 2024
c669576
wip
memsharded Apr 9, 2024
875a995
Merge branch 'develop2' into feature/language
memsharded Apr 9, 2024
0845c1f
wip
memsharded Apr 9, 2024
c4f7cad
Merge branch 'develop2' into feature/language
memsharded Apr 10, 2024
846d78b
fix
memsharded Apr 10, 2024
bcb56ca
Merge branch 'develop2' into feature/language
memsharded Apr 14, 2024
a31f74c
Merge branch 'develop2' into feature/language
memsharded Apr 16, 2024
0231553
wip
memsharded May 20, 2024
7bdd372
Merge branch 'develop2' into feature/language
memsharded May 20, 2024
0920369
merged develop2
memsharded May 21, 2024
d24f254
Merge branch 'develop2' into feature/language
memsharded Jun 3, 2024
28e309e
Update conan/tools/build/cstd.py
memsharded Jun 3, 2024
fe8318d
Update conan/tools/build/cstd.py
memsharded Jun 3, 2024
6c3a5b9
Update conan/tools/build/cstd.py
memsharded Jun 3, 2024
642843a
conflicts solved
memsharded Jun 4, 2024
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
2 changes: 2 additions & 0 deletions conan/tools/build/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from conan.tools.build.flags import cppstd_flag
from conan.tools.build.cppstd import check_max_cppstd, check_min_cppstd, \
valid_max_cppstd, valid_min_cppstd, default_cppstd, supported_cppstd
from conan.tools.build.cstd import check_max_cstd, check_min_cstd, \
valid_max_cstd, valid_min_cstd, supported_cstd
from conan.tools.build.cpu import build_jobs
from conan.tools.build.cross_building import cross_building, can_run
from conan.tools.build.stdcpp_library import stdcpp_library
Expand Down
165 changes: 165 additions & 0 deletions conan/tools/build/cstd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import operator

from conan.errors import ConanInvalidConfiguration, ConanException
from conans.model.version import Version


def check_min_cstd(conanfile, cstd, gnu_extensions=False):
""" Check if current cstd fits the minimal version required.

In case the current cstd doesn't fit the minimal version required
by cstd, a ConanInvalidConfiguration exception will be raised.

1. If settings.compiler.cstd, the tool will use settings.compiler.cstd to compare
2. It not settings.compiler.cstd, the tool will use compiler to compare (reading the
default from cstd_default)
3. If not settings.compiler is present (not declared in settings) will raise because it
cannot compare.
4. If can not detect the default cstd for settings.compiler, a exception will be raised.

:param conanfile: The current recipe object. Always use ``self``.
:param cstd: Minimal cstd version required
:param gnu_extensions: GNU extension is required (e.g gnu17)
"""
_check_cstd(conanfile, cstd, operator.lt, gnu_extensions)


def check_max_cstd(conanfile, cstd, gnu_extensions=False):
""" Check if current cstd fits the maximum version required.

In case the current cstd doesn't fit the maximum version required
by cstd, a ConanInvalidConfiguration exception will be raised.

1. If settings.compiler.cstd, the tool will use settings.compiler.cstd to compare
2. It not settings.compiler.cstd, the tool will use compiler to compare (reading the
default from cstd_default)
3. If not settings.compiler is present (not declared in settings) will raise because it
cannot compare.
4. If can not detect the default cstd for settings.compiler, a exception will be raised.

:param conanfile: The current recipe object. Always use ``self``.
:param cstd: Maximum cstd version required
:param gnu_extensions: GNU extension is required (e.g gnu17)
"""
_check_cstd(conanfile, cstd, operator.gt, gnu_extensions)


def valid_min_cstd(conanfile, cstd, gnu_extensions=False):
""" Validate if current cstd fits the minimal version required.

:param conanfile: The current recipe object. Always use ``self``.
:param cstd: Minimal cstd version required
:param gnu_extensions: GNU extension is required (e.g gnu17). This option ONLY works on Linux.
:return: True, if current cstd matches the required cstd version. Otherwise, False.
"""
try:
check_min_cstd(conanfile, cstd, gnu_extensions)
except ConanInvalidConfiguration:
return False
return True


def valid_max_cstd(conanfile, cstd, gnu_extensions=False):
""" Validate if current cstd fits the maximum version required.

:param conanfile: The current recipe object. Always use ``self``.
:param cstd: Maximum cstd version required
:param gnu_extensions: GNU extension is required (e.g gnu17). This option ONLY works on Linux.
:return: True, if current cstd matches the required cstd version. Otherwise, False.
"""
try:
check_max_cstd(conanfile, cstd, gnu_extensions)
except ConanInvalidConfiguration:
return False
return True


def supported_cstd(conanfile, compiler=None, compiler_version=None):
"""
Get a list of supported ``compiler.cstd`` for the "conanfile.settings.compiler" and
"conanfile.settings.compiler_version" or for the parameters "compiler" and "compiler_version"
if specified.

:param conanfile: The current recipe object. Always use ``self``.
:param compiler: Name of the compiler e.g: gcc
:param compiler_version: Version of the compiler e.g: 12
:return: a list of supported ``cstd`` values.
"""
compiler = compiler or conanfile.settings.get_safe("compiler")
compiler_version = compiler_version or conanfile.settings.get_safe("compiler.version")
if not compiler or not compiler_version:
raise ConanException("Called supported_cstd with no compiler or no compiler.version")

func = {"apple-clang": _apple_clang_supported_cstd,
"gcc": _gcc_supported_cstd,
"msvc": _msvc_supported_cstd,
"clang": _clang_supported_cstd,
}.get(compiler)
if func:
return func(Version(compiler_version))
return None


def _check_cstd(conanfile, cstd, comparator, gnu_extensions):
""" Check if current cstd fits the version required according to a given comparator.

In case the current cstd doesn't fit the maximum version required
by cstd, a ConanInvalidConfiguration exception will be raised.

1. If settings.compiler.cstd, the tool will use settings.compiler.cstd to compare
2. It not settings.compiler.cstd, the tool will use compiler to compare (reading the
default from cstd_default)
3. If not settings.compiler is present (not declared in settings) will raise because it
cannot compare.
4. If can not detect the default cstd for settings.compiler, a exception will be raised.

:param conanfile: The current recipe object. Always use ``self``.
:param cstd: Required cstd version.
:param comparator: Operator to use to compare the detected and the required cstd versions.
:param gnu_extensions: GNU extension is required (e.g gnu17)
"""
if not str(cstd).isdigit():
raise ConanException("cstd parameter must be a number")

def compare(lhs, rhs, comp):
def extract_cpp_version(_cstd):
return str(_cstd).replace("gnu", "")

def add_millennium(_cstd):
return "19%s" % _cstd if _cstd == "99" else "20%s" % _cstd

lhs = add_millennium(extract_cpp_version(lhs))
rhs = add_millennium(extract_cpp_version(rhs))
return not comp(lhs, rhs)

current_cstd = conanfile.settings.get_safe("compiler.cstd")
if current_cstd is None:
raise ConanInvalidConfiguration("The compiler.cstd is not defined for this configuration")

if gnu_extensions and "gnu" not in current_cstd:
raise ConanInvalidConfiguration("The cstd GNU extension is required")

if not compare(current_cstd, cstd, comparator):
raise ConanInvalidConfiguration(
"Current cstd ({}) is {} than the required C standard ({}).".format(
current_cstd, "higher" if comparator == operator.gt else "lower", cstd))


def _apple_clang_supported_cstd(version):
# TODO: Per-version support
return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]


def _gcc_supported_cstd(version):
# TODO: Per-version support
return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]
memsharded marked this conversation as resolved.
Show resolved Hide resolved


def _msvc_supported_cstd(version):
# TODO: Per-version support
return ["11", "17"]
memsharded marked this conversation as resolved.
Show resolved Hide resolved


def _clang_supported_cstd(version):
# TODO: Per-version support
return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]
memsharded marked this conversation as resolved.
Show resolved Hide resolved
73 changes: 73 additions & 0 deletions conan/tools/build/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,76 @@ def _cppstd_intel_cc(_, cppstd):
"20": v20, "gnu20": vgnu20,
"23": v23, "gnu23": vgnu23}.get(cppstd)
return f'-std={flag}' if flag else None


def cstd_flag(conanfile) -> str:
"""
Returns flags specific to the C+standard based on the ``conanfile.settings.compiler``,
``conanfile.settings.compiler.version`` and ``conanfile.settings.compiler.cstd``.

It also considers when using GNU extension in ``settings.compiler.cstd``, reflecting it in the
compiler flag. Currently, it supports GCC, Clang, AppleClang, MSVC, Intel, MCST-LCC.

In case there is no ``settings.compiler`` or ``settings.cstd`` in the profile, the result will
be an **empty string**.

:param conanfile: The current recipe object. Always use ``self``.
:return: ``str`` with the standard C flag used by the compiler.
"""
compiler = conanfile.settings.get_safe("compiler")
compiler_version = conanfile.settings.get_safe("compiler.version")
cstd = conanfile.settings.get_safe("compiler.cstd")

if not compiler or not compiler_version or not cstd:
return ""

func = {"gcc": _cstd_gcc,
"clang": _cstd_clang,
"apple-clang": _cstd_apple_clang,
"msvc": _cstd_msvc}.get(compiler)
flag = None
if func:
flag = func(Version(compiler_version), str(cstd))
return flag


def _cstd_gcc(gcc_version, cstd):
# TODO: Verify flags per version
flag = {"99": "c99",
"11": "c11",
"17": "c17",
"23": "c23"}.get(cstd, cstd)
return f'-std={flag}' if flag else None


def _cstd_clang(gcc_version, cstd):
# TODO: Verify flags per version
flag = {"99": "c99",
"11": "c11",
"17": "c17",
"23": "c23"}.get(cstd, cstd)
return f'-std={flag}' if flag else None


def _cstd_apple_clang(gcc_version, cstd):
# TODO: Verify flags per version
flag = {"99": "c99",
"11": "c11",
"17": "c17",
"23": "c23"}.get(cstd, cstd)
return f'-std={flag}' if flag else None


def cstd_msvc_flag(visual_version, cstd):
if cstd == "17":
if visual_version >= "192":
return "c17"
elif cstd == "11":
if visual_version >= "192":
return "c11"
return None


def _cstd_msvc(visual_version, cstd):
flag = cstd_msvc_flag(visual_version, cstd)
return f'/std:{flag}' if flag else None
35 changes: 25 additions & 10 deletions conan/tools/cmake/toolchain/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,24 +244,39 @@ def context(self):

class CppStdBlock(Block):
template = textwrap.dedent("""
{% if cppstd %}
message(STATUS "Conan toolchain: C++ Standard {{ cppstd }} with extensions {{ cppstd_extensions }}")
set(CMAKE_CXX_STANDARD {{ cppstd }})
set(CMAKE_CXX_EXTENSIONS {{ cppstd_extensions }})
set(CMAKE_CXX_STANDARD_REQUIRED ON)
{% endif %}
{% if cstd %}
message(STATUS "Conan toolchain: C Standard {{ cstd }} with extensions {{ cstd_extensions }}")
set(CMAKE_C_STANDARD {{ cstd }})
set(CMAKE_C_EXTENSIONS {{ cstd_extensions }})
set(CMAKE_C_STANDARD_REQUIRED ON)
{% endif %}
""")

def context(self):
compiler_cppstd = self._conanfile.settings.get_safe("compiler.cppstd")
if compiler_cppstd is None:
return None

if compiler_cppstd.startswith("gnu"):
cppstd = compiler_cppstd[3:]
cppstd_extensions = "ON"
else:
cppstd = compiler_cppstd
cppstd_extensions = "OFF"
return {"cppstd": cppstd, "cppstd_extensions": cppstd_extensions}
compiler_cstd = self._conanfile.settings.get_safe("compiler.cstd")
result = {}
if compiler_cppstd is not None:
if compiler_cppstd.startswith("gnu"):
result["cppstd"] = compiler_cppstd[3:]
result["cppstd_extensions"] = "ON"
else:
result["cppstd"] = compiler_cppstd
result["cppstd_extensions"] = "OFF"
if compiler_cstd is not None:
if compiler_cstd.startswith("gnu"):
result["cstd"] = compiler_cstd[3:]
result["cstd_extensions"] = "ON"
else:
result["cstd"] = compiler_cstd
result["cstd_extensions"] = "OFF"
return result or None


class SharedLibBock(Block):
Expand Down
6 changes: 3 additions & 3 deletions conan/tools/gnu/autotoolstoolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from conan.tools.build import cmd_args_to_string, save_toolchain_args
from conan.tools.build.cross_building import cross_building
from conan.tools.build.flags import architecture_flag, build_type_flags, cppstd_flag, \
build_type_link_flags, \
libcxx_flags
build_type_link_flags, libcxx_flags, cstd_flag
from conan.tools.env import Environment
from conan.tools.gnu.get_gnu_triplet import _get_gnu_triplet
from conan.tools.microsoft import VCVars, msvc_runtime_flag, unix_path, check_min_vs, is_msvc
Expand Down Expand Up @@ -49,6 +48,7 @@ def __init__(self, conanfile, namespace=None, prefix="/"):
self.build_type_link_flags = build_type_link_flags(self._conanfile.settings)

self.cppstd = cppstd_flag(self._conanfile)
self.cstd = cstd_flag(self._conanfile)
self.arch_flag = architecture_flag(self._conanfile.settings)
self.libcxx, self.gcc_cxx11_abi = libcxx_flags(self._conanfile)
self.fpic = self._conanfile.options.get_safe("fPIC")
Expand Down Expand Up @@ -128,7 +128,7 @@ def cxxflags(self):
@property
def cflags(self):
fpic = "-fPIC" if self.fpic else None
ret = [self.arch_flag, fpic, self.msvc_runtime_flag, self.sysroot_flag]
ret = [self.cstd, self.arch_flag, fpic, self.msvc_runtime_flag, self.sysroot_flag]
apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag]
conf_flags = self._conanfile.conf.get("tools.build:cflags", default=[], check_type=list)
vs_flag = self._add_msvc_flags(self.extra_cflags)
Expand Down
15 changes: 14 additions & 1 deletion conan/tools/meson/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from conan.tools.build.flags import cppstd_msvc_flag
from conans.model.options import _PackageOption

__all__ = ["to_meson_machine", "to_meson_value", "to_cppstd_flag"]
__all__ = ["to_meson_machine", "to_meson_value", "to_cppstd_flag", "to_cstd_flag"]

# https://mesonbuild.com/Reference-tables.html#operating-system-names
_meson_system_map = {
Expand Down Expand Up @@ -126,3 +126,16 @@ def to_cppstd_flag(compiler, compiler_version, cppstd):
return 'v%s' % flag if flag else None
else:
return _cppstd_map.get(cppstd)


def to_cstd_flag(cstd):
""" possible values
none, c89, c99, c11, c17, c18, c2x, c23, gnu89, gnu99, gnu11, gnu17, gnu18, gnu2x, gnu23
"""
_cstd_map = {
'99': "c99",
'11': "c11",
'17': "c17",
'23': "c23",
}
return _cstd_map.get(cstd, cstd)
7 changes: 7 additions & 0 deletions conan/tools/meson/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class MesonToolchain(object):
{% if cpp_std %}
cpp_std = '{{cpp_std}}'
{% endif %}
{% if c_std %}
c_std = '{{c_std}}'
{% endif %}
{% if backend %}
backend = '{{backend}}'
{% endif %}
Expand Down Expand Up @@ -188,6 +191,9 @@ def __init__(self, conanfile, backend=None, native=False):
cppstd = self._conanfile.settings.get_safe("compiler.cppstd")
self._cpp_std = to_cppstd_flag(compiler, compiler_version, cppstd)

cstd = self._conanfile.settings.get_safe("compiler.cstd")
self._c_std = to_cstd_flag(cstd)

self._b_vscrt = None
if compiler in ("msvc", "clang"):
vscrt = msvc_runtime_flag(self._conanfile)
Expand Down Expand Up @@ -488,6 +494,7 @@ def _context(self):
"b_ndebug": to_meson_value(self._b_ndebug), # boolean as string
# https://mesonbuild.com/Builtin-options.html#compiler-options
"cpp_std": self._cpp_std,
"c_std": self._c_std,
"c_args": to_meson_value(self._filter_list_empty_fields(self.c_args)),
"c_link_args": to_meson_value(self._filter_list_empty_fields(self.c_link_args)),
"cpp_args": to_meson_value(self._filter_list_empty_fields(self.cpp_args)),
Expand Down
Loading