Repository: conan-io/conan
Pull request #16364 (2024-05-29 10:24:16)

shared docker runner profiles fixed
Changelog: Bugfix: Fix profile errors when using a docker runner of `type=shared`
Docs: Omit

- [ ] Refer to the issue that supports this Pull Request.
- [ ] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [ ] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop2/.github/CONTRIBUTING.md).
- [ ] I've followed the PEP8 style guides for Python code.
- [ ] I've opened another PR in the Conan docs repo to the ``develop`` branch, documenting this one.



Patch:
diff --git a/.gitignore b/.gitignore
index cd3afe32d..87824d101 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@ venv/
 *.egg-info/
 .installed.cfg
 *.egg
+pip-wheel-metadata/
 
 # PyInstaller
 #  Usually these files are written by a python script from a template
diff --git a/conan/api/subapi/new.py b/conan/api/subapi/new.py
index 573ce75d4..23eaab4fb 100644
--- a/conan/api/subapi/new.py
+++ b/conan/api/subapi/new.py
@@ -29,6 +29,7 @@ class NewAPI:
         from conan.internal.api.new.autotools_lib import autotools_lib_files
         from conan.internal.api.new.autoools_exe import autotools_exe_files
         from conan.internal.api.new.local_recipes_index import local_recipes_index_files
+        from conan.internal.api.new.qbs_lib import qbs_lib_files
         new_templates = {"basic": basic_file,
                          "cmake_lib": cmake_lib_files,
                          "cmake_exe": cmake_exe_files,
@@ -41,7 +42,8 @@ class NewAPI:
                          "autotools_lib": autotools_lib_files,
                          "autotools_exe": autotools_exe_files,
                          "alias": alias_file,
-                         "local_recipes_index": local_recipes_index_files}
+                         "local_recipes_index": local_recipes_index_files,
+                         "qbs_lib": qbs_lib_files}
         template_files = new_templates.get(template_name)
         return template_files
 
diff --git a/conan/internal/api/detect_api.py b/conan/internal/api/detect_api.py
index e90894b29..04bb3ab16 100644
--- a/conan/internal/api/detect_api.py
+++ b/conan/internal/api/detect_api.py
@@ -438,8 +438,15 @@ def _cc_compiler(compiler_exe="cc"):
         if ret != 0:
             return None, None, None
         compiler = "clang" if "clang" in out else "gcc"
-        installed_version = re.search(r"([0-9]+(\.[0-9])?)", out).group()
-        if installed_version:
+        # clang and gcc have version after a space, first try to find that to skip extra numbers
+        # that might appear in the first line of the output before the version
+        installed_version = re.search(r" ([0-9]+(\.[0-9])+)", out)
+        # Try only major but with spaces next
+        installed_version = installed_version or re.search(r" ([0-9]+(\.[0-9])?)", out)
+        # Fallback to the first number we find optionally followed by other version fields
+        installed_version = installed_version or re.search(r"([0-9]+(\.[0-9])?)", out)
+        if installed_version and installed_version.group():
+            installed_version = installed_version.group()
             ConanOutput(scope="detect_api").info("Found cc=%s-%s" % (compiler, installed_version))
             return compiler, Version(installed_version), compiler_exe
     except (Exception,):  # to disable broad-except
@@ -581,3 +588,12 @@ def default_compiler_version(compiler, version):
     elif compiler == "intel-cc":
         return major
     return version
+
+
+def detect_sdk_version(sdk):
+    if platform.system() != "Darwin":
+        return
+    cmd = f'xcrun -sdk {sdk} --show-sdk-version'
+    result = check_output_runner(cmd)
+    result = result.strip()
+    return result
diff --git a/conan/internal/api/new/qbs_lib.py b/conan/internal/api/new/qbs_lib.py
new file mode 100644
index 000000000..2c71e8ff5
--- /dev/null
+++ b/conan/internal/api/new/qbs_lib.py
@@ -0,0 +1,103 @@
+from conan.internal.api.new.cmake_lib import source_cpp, source_h, test_main
+
+
+conanfile_sources = '''
+import os
+
+from conan import ConanFile
+from conan.tools.qbs import Qbs
+
+
+class {{package_name}}Recipe(ConanFile):
+    name = "{{name}}"
+    version = "{{version}}"
+
+    exports_sources = "*.cpp", "*.h", "*.qbs"
+    settings = "os", "compiler", "arch"
+    options = {"shared": [True, False]}
+    default_options = {"shared": False}
+
+    def build(self):
+        qbs = Qbs(self)
+        qbs.profile = ""
+        qbs_config = {"products.{{name}}.isShared": "true" if self.options.shared else "false"}
+        qbs.add_configuration("default", qbs_config)
+        qbs.build()
+
+    def package(self):
+        qbs = Qbs(self)
+        qbs.profile = ""
+        qbs.install()
+
+    def package_info(self):
+        self.cpp_info.libs = ["{{name}}"]
+'''
+
+qbs_lib_file = '''
+    Library {
+        property bool isShared: true
+        name: "{{name}}"
+        type: isShared ? "dynamiclibrary" : "staticlibrary"
+        files: [ "{{name}}.cpp" ]
+        Group {
+            name: "headers"
+            files: [ "{{name}}.h" ]
+            qbs.install: true
+            qbs.installDir: "include"
+        }
+        Depends { name: "cpp" }
+        Depends { name: "bundle" }
+        bundle.isBundle: false
+        install: true
+        qbs.installPrefix: ""
+    }
+'''
+
+test_conanfile_v2 = """import os
+
+from conan import ConanFile
+from conan.tools.build import can_run
+from conan.tools.qbs import Qbs
+from conan.tools.build import cmd_args_to_string
+
+class {{package_name}}TestConan(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+    generators = "PkgConfigDeps"
+
+    def requirements(self):
+        self.requires(self.tested_reference_str)
+
+    def build(self):
+        qbs = Qbs(self)
+        qbs.profile = ""
+        qbs.build()
+        qbs.install()
+
+    def test(self):
+        if can_run(self):
+            cmd = os.path.join(self.package_folder, "bin", "example")
+            self.run(cmd_args_to_string([cmd]), env="conanrun")
+"""
+
+qbs_test_file = '''
+    Application {
+        name: "example"
+        consoleApplication: true
+        files: [ "example.cpp" ]
+        Depends { name: "cpp" }
+        install: true
+        qbs.installPrefix: ""
+        // external dependency via pkg-config
+        qbsModuleProviders: ["qbspkgconfig"]
+        moduleProviders.qbspkgconfig.libDirs: path
+        Depends { name: "{{name}}" }
+    }
+'''
+
+qbs_lib_files = {"conanfile.py": conanfile_sources,
+                 "{{name}}.qbs": qbs_lib_file,
+                 "{{name}}.cpp": source_cpp,
+                 "{{name}}.h": source_h,
+                 "test_package/conanfile.py": test_conanfile_v2,
+                 "test_package/example.cpp": test_main,
+                 "test_package/example.qbs": qbs_test_file}
diff --git a/conan/internal/runner/docker.py b/conan/internal/runner/docker.py
index 77aabaf0a..167e4ba4e 100644
--- a/conan/internal/runner/docker.py
+++ b/conan/internal/runner/docker.py
@@ -9,7 +9,6 @@ from conan.api.output import Color, ConanOutput
 from conan.api.conan_api import ConfigAPI
 from conan.cli import make_abs_path
 from conan.internal.runner import RunnerException
-from conans.client.profile_loader import ProfileLoader
 from conans.errors import ConanException
 from conans.model.version import Version
 
@@ -79,29 +78,6 @@ class DockerRunner:
         if args.format:
             raise ConanException("format argument is forbidden if running in a docker runner")
 
-        # Runner config
-        self.abs_runner_home_path = os.path.join(self.abs_host_path, '.conanrunner')
-        self.abs_docker_path = os.path.join('/root/conanrunner', os.path.basename(self.abs_host_path)).replace("\\","/")
-
-        # Update conan command and some paths to run inside the container
-        raw_args[raw_args.index(args.path)] = self.abs_docker_path
-        self.profiles = []
-        if self.args.profile_build and self.args.profile_host:
-            profile_list = set(self.args.profile_build + self.args.profile_host)
-        else:
-            profile_list = self.args.profile_host or self.args.profile_build
-
-        # Update the profile paths
-        for i, raw_arg in enumerate(raw_args):
-            for i, raw_profile in enumerate(profile_list):
-                _profile = ProfileLoader.get_profile_path(os.path.join(ConfigAPI(self.conan_api).home(), 'profiles'), raw_profile, os.getcwd())
-                _name = f'{os.path.basename(_profile)}_{i}'
-                if raw_profile in raw_arg:
-                    raw_args[raw_args.index(raw_arg)] = raw_arg.replace(raw_profile, os.path.join(self.abs_docker_path, '.conanrunner/profiles', _name))
-                self.profiles.append([_profile, os.path.join(self.abs_runner_home_path, 'profiles', _name)])
-
-        self.command = ' '.join([f'conan {command}'] + [f'"{raw_arg}"' if ' ' in raw_arg else raw_arg for raw_arg in raw_args] + ['-f json > create.json'])
-
         # Container config
         # https://containers.dev/implementors/json_reference/
         self.configfile = config_parser(host_profile.runner.get('configfile'))
@@ -116,6 +92,15 @@ class DockerRunner:
         self.cache = str(host_profile.runner.get('cache', 'clean'))
         self.container = None
 
+        # Runner config>
+        self.abs_runner_home_path = os.path.join(self.abs_host_path, '.conanrunner')
+        self.docker_user_name = self.configfile.run.user or 'root'
+        self.abs_docker_path = os.path.join(f'/{self.docker_user_name}/conanrunner', os.path.basename(self.abs_host_path)).replace("\\","/")
+
+        # Update conan command and some paths to run inside the container
+        raw_args[raw_args.index(args.path)] = self.abs_docker_path
+        self.command = ' '.join([f'conan {command}'] + [f'"{raw_arg}"' if ' ' in raw_arg else raw_arg for raw_arg in raw_args] + ['-f json > create.json'])
+
     def run(self):
         """
         run conan inside a Docker continer
@@ -194,10 +179,11 @@ class DockerRunner:
                         if stream:
                             ConanOutput().status(stream.strip())
 
-    def run_command(self, command, log=True):
+    def run_command(self, command, workdir=None, log=True):
+        workdir = workdir or self.abs_docker_path
         if log:
             _docker_info(f'Running in container: "{command}"')
-        exec_instance = self.docker_api.exec_create(self.container.id, f"/bin/bash -c '{command}'", tty=True)
+        exec_instance = self.docker_api.exec_create(self.container.id, f"/bin/bash -c '{command}'", workdir=workdir, tty=True)
         exec_output = self.docker_api.exec_start(exec_instance['Id'], tty=True, stream=True, demux=True,)
         stderr_log, stdout_log = '', ''
         try:
@@ -226,22 +212,22 @@ class DockerRunner:
         shutil.rmtree(self.abs_runner_home_path, ignore_errors=True)
         volumes = {self.abs_host_path: {'bind': self.abs_docker_path, 'mode': 'rw'}}
         environment = {'CONAN_RUNNER_ENVIRONMENT': '1'}
+
         if self.cache == 'shared':
-            volumes[ConfigAPI(self.conan_api).home()] = {'bind': '/root/.conan2', 'mode': 'rw'}
+            volumes[self.conan_api.home_folder] = {'bind': f'/{self.docker_user_name}/.conan2', 'mode': 'rw'}
+
         if self.cache in ['clean', 'copy']:
+            # Copy all conan profiles and config files to docker workspace
             os.mkdir(self.abs_runner_home_path)
-            os.mkdir(os.path.join(self.abs_runner_home_path, 'profiles'))
-
-            # Copy all conan config files to docker workspace
+            shutil.copytree(
+                os.path.join(self.conan_api.home_folder, 'profiles'),
+                os.path.join(self.abs_runner_home_path, 'profiles')
+            )
             for file_name in ['global.conf', 'settings.yml', 'remotes.json']:
-                src_file = os.path.join(ConfigAPI(self.conan_api).home(), file_name)
+                src_file = os.path.join(self.conan_api.home_folder, file_name)
                 if os.path.exists(src_file):
                     shutil.copy(src_file, os.path.join(self.abs_runner_home_path, file_name))
 
-            # Copy all profiles to docker workspace
-            for current_path, new_path in self.profiles:
-                shutil.copy(current_path, new_path)
-
             if self.cache == 'copy':
                 tgz_path = os.path.join(self.abs_runner_home_path, 'local_cache_save.tgz')
                 _docker_info(f'Save host cache in: {tgz_path}')
@@ -257,7 +243,6 @@ class DockerRunner:
             raise ConanException( f'conan version inside the container must be greater than {min_conan_version}')
         if self.cache != 'shared':
             self.run_command('mkdir -p ${HOME}/.conan2/profiles', log=False)
-            self.run_command('cp -r "'+self.abs_docker_path+'/.conanrunner/profiles/." ${HOME}/.conan2/profiles/.', log=False)
             for file_name in ['global.conf', 'settings.yml', 'remotes.json']:
                 if os.path.exists( os.path.join(self.abs_runner_home_path, file_name)):
                     self.run_command('cp "'+self.abs_docker_path+'/.conanrunner/'+file_name+'" ${HOME}/.conan2/'+file_name, log=False)
diff --git a/conan/tools/build/__init__.py b/conan/tools/build/__init__.py
index 9c77a3f4d..0ae8bc5f3 100644
--- a/conan/tools/build/__init__.py
+++ b/conan/tools/build/__init__.py
@@ -6,6 +6,8 @@ from shlex import quote
 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
diff --git a/conan/tools/build/cstd.py b/conan/tools/build/cstd.py
new file mode 100644
index 000000000..2d69eaba9
--- /dev/null
+++ b/conan/tools/build/cstd.py
@@ -0,0 +1,176 @@
+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):
+    if version < "4.7":
+        return ["99", "gnu99"]
+    if version < "8":
+        return ["99", "gnu99", "11", "gnu11"]
+    if version < "14":
+        return ["99", "gnu99", "11", "gnu11", "17", "gnu17"]
+    return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]
+
+
+def _msvc_supported_cstd(version):
+    if version < "192":
+        return []
+    return ["11", "17"]
+
+
+def _clang_supported_cstd(version):
+    if version < "3":
+        return ["99", "gnu99"]
+    if version < "6":
+        return ["99", "gnu99", "11", "gnu11"]
+    if version < "18":
+        return ["99", "gnu99", "11", "gnu11", "17", "gnu17"]
+    return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]
diff --git a/conan/tools/build/flags.py b/conan/tools/build/flags.py
index 7dbb1e06b..8b20fed3d 100644
--- a/conan/tools/build/flags.py
+++ b/conan/tools/build/flags.py
@@ -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
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index fbd719972..34021ece8 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -19,6 +19,7 @@ from conan.tools.microsoft.visual import msvc_version_to_toolset_version
 from conans.client.generators import relativize_path
 from conans.client.subsystems import deduce_subsystem, WINDOWS
 from conan.errors import ConanException
+from conans.model.version import Version
 from conans.util.files import load
 
 
@@ -248,24 +249,39 @@ class LinkerScriptsBlock(Block):
 
 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):
@@ -931,6 +947,34 @@ class GenericSystemBlock(Block):
         return os_host in ('iOS', 'watchOS', 'tvOS', 'visionOS') or (
                 os_host == 'Macos' and (arch_host != arch_build or os_build != os_host))
 
+    def _get_darwin_version(self, os_name, os_version):
+        # version mapping from https://en.wikipedia.org/wiki/Darwin_(operating_system)
+        version_mapping = {
+            "Macos": {
+                "10.6": "10", "10.7": "11", "10.8": "12", "10.9": "13", "10.10": "14", "10.11": "15",
+                "10.12": "16", "10.13": "17", "10.14": "18", "10.15": "19", "11": "20", "12": "21",
+                "13": "22", "14": "23",
+            },
+            "iOS": {
+                "7": "14", "8": "14", "9": "15", "10": "16", "11": "17", "12": "18", "13": "19",
+                "14": "20", "15": "21", "16": "22", "17": "23"
+            },
+            "watchOS": {
+                "4": "17", "5": "18", "6": "19", "7": "20",
+                "8": "21", "9": "22", "10": "23"
+            },
+            "tvOS": {
+                "11": "17", "12": "18", "13": "19", "14": "20",
+                "15": "21", "16": "22", "17": "23"
+            },
+            "visionOS": {
+                "1": "23"
+            }
+        }
+        os_version = Version(os_version).major if os_name != "Macos" or (os_name == "Macos" and Version(
+            os_version) >= Version("11")) else os_version
+        return version_mapping.get(os_name, {}).get(str(os_version))
+
     def _get_cross_build(self):
         user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain")
 
@@ -942,6 +986,7 @@ class GenericSystemBlock(Block):
         if not user_toolchain and not is_universal_arch(self._conanfile.settings.get_safe("arch"),
                                                         self._conanfile.settings.possible_values().get("arch")):
             os_host = self._conanfile.settings.get_safe("os")
+            os_host_version = self._conanfile.settings.get_safe("os.version")
             arch_host = self._conanfile.settings.get_safe("arch")
             if arch_host == "armv8":
                 arch_host = {"Windows": "ARM64", "Macos": "arm64"}.get(os_host, "aarch64")
@@ -952,12 +997,12 @@ class GenericSystemBlock(Block):
                 if self._is_apple_cross_building():
                     # cross-build in Macos also for M1
                     system_name = {'Macos': 'Darwin'}.get(os_host, os_host)
-                    #  CMAKE_SYSTEM_VERSION for Apple sets the sdk version, not the os version
-                    _system_version = self._conanfile.settings.get_safe("os.sdk_version")
+                    #  CMAKE_SYSTEM_VERSION for Apple sets the Darwin version, not the os version
+                    _system_version = self._get_darwin_version(os_host, os_host_version)
                     _system_processor = to_apple_arch(self._conanfile)
                 elif os_host != 'Android':
                     system_name = self._get_generic_system_name()
-                    _system_version = self._conanfile.settings.get_safe("os.version")
+                    _system_version = os_host_version
                     _system_processor = arch_host
 
                 if system_name is not None and system_version is None:
@@ -1018,6 +1063,46 @@ class GenericSystemBlock(Block):
                 "winsdk_version": winsdk_version,
                 "gen_platform_sdk_version": gen_platform_sdk_version}
 
+class ExtraVariablesBlock(Block):
+    template = textwrap.dedent(r"""
+        {% if extra_variables %}
+        {% for key, value in extra_variables.items() %}
+        set({{ key }} {{ value }})
+        {% endfor %}
+        {% endif %}
+    """)
+
+    CMAKE_CACHE_TYPES = ["BOOL","FILEPATH", "PATH", "STRING", "INTERNAL"]
+
+    def get_exact_type(self, key, value):
+        if isinstance(value, str):
+            return f"\"{value}\""
+        elif isinstance(value, (int, float)):
+            return value
+        elif isinstance(value, dict):
+            var_value = self.get_exact_type(key, value.get("value"))
+            is_cache = value.get("cache")
+            if is_cache:
+                if not isinstance(is_cache, bool):
+                    raise ConanException(f'tools.cmake.cmaketoolchain:extra_variables "cache" must be a boolean (True/False)')
+                var_type = value.get("type")
+                if not var_type:
+                    raise ConanException(f'tools.cmake.cmaketoolchain:extra_variables needs "type" defined for cache variable "{key}"')
+                if var_type not in self.CMAKE_CACHE_TYPES:
+                    raise ConanException(f'tools.cmake.cmaketoolchain:extra_variables invalid type "{var_type}" for cache variable "{key}". Possible types: {", ".join(self.CMAKE_CACHE_TYPES)}')
+                # Set docstring as variable name if not defined
+                docstring = value.get("docstring") or key
+                return f"{var_value} CACHE {var_type} \"{docstring}\""
+            else:
+                return var_value
+
+    def context(self):
+        # Reading configuration from "tools.cmake.cmaketoolchain:extra_variables"
+        extra_variables = self._conanfile.conf.get("tools.cmake.cmaketoolchain:extra_variables", default={}, check_type=dict)
+        parsed_extra_variables = {}
+        for key, value in extra_variables.items():
+            parsed_extra_variables[key] = self.get_exact_type(key, value)
+        return {"extra_variables": parsed_extra_variables}
 
 class OutputDirsBlock(Block):
 
diff --git a/conan/tools/cmake/toolchain/toolchain.py b/conan/tools/cmake/toolchain/toolchain.py
index 6924a1d9f..0692751eb 100644
--- a/conan/tools/cmake/toolchain/toolchain.py
+++ b/conan/tools/cmake/toolchain/toolchain.py
@@ -9,7 +9,7 @@ from conan.internal import check_duplicated_generator
 from conan.tools.build import use_win_mingw
 from conan.tools.cmake.presets import write_cmake_presets
 from conan.tools.cmake.toolchain import CONAN_TOOLCHAIN_FILENAME
-from conan.tools.cmake.toolchain.blocks import ToolchainBlocks, UserToolchain, GenericSystemBlock, \
+from conan.tools.cmake.toolchain.blocks import ExtraVariablesBlock, ToolchainBlocks, UserToolchain, GenericSystemBlock, \
     AndroidSystemBlock, AppleSystemBlock, FPicBlock, ArchitectureBlock, GLibCXXBlock, VSRuntimeBlock, \
     CppStdBlock, ParallelBlock, CMakeFlagsInitBlock, TryCompileBlock, FindFiles, PkgConfigBlock, \
     SkipRPath, SharedLibBock, OutputDirsBlock, ExtraFlagsBlock, CompilersBlock, LinkerScriptsBlock, \
@@ -165,6 +165,7 @@ class CMakeToolchain(object):
                                        ("parallel", ParallelBlock),
                                        ("extra_flags", ExtraFlagsBlock),
                                        ("cmake_flags_init", CMakeFlagsInitBlock),
+                                       ("extra_variables", ExtraVariablesBlock),
                                        ("try_compile", TryCompileBlock),
                                        ("find_paths", FindFiles),
                                        ("pkg_config", PkgConfigBlock),
diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py
index 6f961e442..f76edb7d1 100644
--- a/conan/tools/gnu/autotoolstoolchain.py
+++ b/conan/tools/gnu/autotoolstoolchain.py
@@ -5,8 +5,7 @@ from conan.tools.apple.apple import is_apple_os, resolve_apple_flags
 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
@@ -49,6 +48,7 @@ class AutotoolsToolchain:
         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")
@@ -60,8 +60,8 @@ class AutotoolsToolchain:
         self._build = self._conanfile.conf.get("tools.gnu:build_triplet")
         self._target = None
 
-        is_cross_building = cross_building(self._conanfile)
-        if is_cross_building:
+        self._is_cross_building = cross_building(self._conanfile)
+        if self._is_cross_building:
             os_host = conanfile.settings.get_safe("os")
             arch_host = conanfile.settings.get_safe("arch")
             os_build = conanfile.settings_build.get_safe('os')
@@ -84,11 +84,12 @@ class AutotoolsToolchain:
         self.autoreconf_args = self._default_autoreconf_flags()
         self.make_args = []
         # Apple stuff
-        is_cross_building_osx = (is_cross_building
+        is_cross_building_osx = (self._is_cross_building
                                  and conanfile.settings_build.get_safe('os') == "Macos"
                                  and is_apple_os(conanfile))
-        min_flag, arch_flag, isysroot_flag = resolve_apple_flags(conanfile,
-                                                                 is_cross_building=is_cross_building_osx)
+        min_flag, arch_flag, isysroot_flag = (
+            resolve_apple_flags(conanfile, is_cross_building=is_cross_building_osx)
+        )
         # https://man.archlinux.org/man/clang.1.en#Target_Selection_Options
         self.apple_arch_flag = arch_flag
         # -isysroot makes all includes for your library relative to the build directory
@@ -102,7 +103,8 @@ class AutotoolsToolchain:
         return flag
 
     def _msvc_extra_flags(self):
-        if is_msvc(self._conanfile) and check_min_vs(self._conanfile, "180", raise_invalid=False):
+        if is_msvc(self._conanfile) and check_min_vs(self._conanfile, "180",
+                                                     raise_invalid=False):
             return ["-FS"]
         return []
 
@@ -128,7 +130,7 @@ class AutotoolsToolchain:
     @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)
@@ -160,7 +162,8 @@ class AutotoolsToolchain:
         compilers_by_conf = self._conanfile.conf.get("tools.build:compiler_executables", default={},
                                                      check_type=dict)
         if compilers_by_conf:
-            compilers_mapping = {"c": "CC", "cpp": "CXX", "cuda": "NVCC", "fortran": "FC", "rc": "RC"}
+            compilers_mapping = {"c": "CC", "cpp": "CXX", "cuda": "NVCC", "fortran": "FC",
+                                 "rc": "RC"}
             for comp, env_var in compilers_mapping.items():
                 if comp in compilers_by_conf:
                     compiler = compilers_by_conf[comp]
@@ -172,6 +175,16 @@ class AutotoolsToolchain:
         env.append("CFLAGS", self.cflags)
         env.append("LDFLAGS", self.ldflags)
         env.prepend_path("PKG_CONFIG_PATH", self._conanfile.generators_folder)
+        # Issue related: https://github.com/conan-io/conan/issues/15486
+        if self._is_cross_building and self._conanfile.conf_build:
+            compilers_build_mapping = (
+                self._conanfile.conf_build.get("tools.build:compiler_executables", default={},
+                                               check_type=dict)
+            )
+            if "c" in compilers_build_mapping:
+                env.define("CC_FOR_BUILD", compilers_build_mapping["c"])
+            if "cpp" in compilers_build_mapping:
+                env.define("CXX_FOR_BUILD", compilers_build_mapping["cpp"])
         return env
 
     def vars(self):
diff --git a/conan/tools/meson/helpers.py b/conan/tools/meson/helpers.py
index d0decdf8b..ba8e1eb85 100644
--- a/conan/tools/meson/helpers.py
+++ b/conan/tools/meson/helpers.py
@@ -2,7 +2,7 @@ from conan.api.output import ConanOutput
 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 = {
@@ -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)
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index 67713d769..743d38cbb 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -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 %}
@@ -188,13 +191,26 @@ class MesonToolchain(object):
         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)
             if vscrt:
                 self._b_vscrt = str(vscrt).lower()
 
-        #: Dict-like object that defines Meson``properties`` with ``key=value`` format
+        # Extra flags
+        #: List of extra ``CXX`` flags. Added to ``cpp_args``
+        self.extra_cxxflags = []
+        #: List of extra ``C`` flags. Added to ``c_args``
+        self.extra_cflags = []
+        #: List of extra linker flags. Added to ``c_link_args`` and ``cpp_link_args``
+        self.extra_ldflags = []
+        #: List of extra preprocessor definitions. Added to ``c_args`` and ``cpp_args`` with the
+        #: format ``-D[FLAG_N]``.
+        self.extra_defines = []
+        #: Dict-like object that defines Meson ``properties`` with ``key=value`` format
         self.properties = {}
         #: Dict-like object that defines Meson ``project options`` with ``key=value`` format
         self.project_options = {
@@ -245,6 +261,11 @@ class MesonToolchain(object):
             default_comp = "cl"
             default_comp_cpp = "cl"
 
+        # Read configuration for sys_root property (honoring existing conf)
+        self._sys_root = self._conanfile_conf.get("tools.build:sysroot", check_type=str)
+        if self._sys_root:
+            self.properties["sys_root"] = self._sys_root
+
         # Read configuration for compilers
         compilers_by_conf = self._conanfile_conf.get("tools.build:compiler_executables", default={},
                                                      check_type=dict)
@@ -403,12 +424,14 @@ class MesonToolchain(object):
         exelinkflags = self._conanfile_conf.get("tools.build:exelinkflags", default=[], check_type=list)
         linker_scripts = self._conanfile_conf.get("tools.build:linker_scripts", default=[], check_type=list)
         linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts]
-        defines = [f"-D{d}" for d in self._conanfile.conf.get("tools.build:defines", default=[], check_type=list)]
+        defines = self._conanfile.conf.get("tools.build:defines", default=[], check_type=list)
+        sys_root = [f"--sysroot={self._sys_root}"] if self._sys_root else [""]
         return {
-            "cxxflags": cxxflags,
-            "cflags": cflags,
-            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags,
-            "defines": defines
+            "cxxflags": cxxflags + sys_root + self.extra_cxxflags,
+            "cflags": cflags + sys_root + self.extra_cflags,
+            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags
+                       + sys_root + self.extra_ldflags,
+            "defines": [f"-D{d}" for d in (defines + self.extra_defines)]
         }
 
     @staticmethod
@@ -488,6 +511,7 @@ class MesonToolchain(object):
             "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)),
diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py
index e5427001c..5e33d5103 100644
--- a/conan/tools/microsoft/toolchain.py
+++ b/conan/tools/microsoft/toolchain.py
@@ -27,6 +27,7 @@ class MSBuildToolchain(object):
               <PreprocessorDefinitions>{{ defines }}%(PreprocessorDefinitions)</PreprocessorDefinitions>
               <AdditionalOptions>{{ compiler_flags }} %(AdditionalOptions)</AdditionalOptions>
               <RuntimeLibrary>{{ runtime_library }}</RuntimeLibrary>
+              {% if cstd %}<LanguageStandard_C>{{ cstd }}</LanguageStandard_C>{% endif %}
               <LanguageStandard>{{ cppstd }}</LanguageStandard>{{ parallel }}{{ compile_options }}
             </ClCompile>
             <Link>
@@ -69,6 +70,7 @@ class MSBuildToolchain(object):
         self.runtime_library = self._runtime_library(conanfile.settings)
         #: cppstd value. By default, ``compiler.cppstd`` one.
         self.cppstd = conanfile.settings.get_safe("compiler.cppstd")
+        self.cstd = conanfile.settings.get_safe("compiler.cstd")
         #: VS IDE Toolset, e.g., ``"v140"``. If ``compiler=msvc``, you can use ``compiler.toolset``
         #: setting, else, it'll be based on ``msvc`` version.
         self.toolset = msvs_toolset(conanfile)
@@ -139,6 +141,7 @@ class MSBuildToolchain(object):
         self.ldflags.extend(sharedlinkflags + exelinkflags)
 
         cppstd = "stdcpp%s" % self.cppstd if self.cppstd else ""
+        cstd = f"stdc{self.cstd}" if self.cstd else ""
         runtime_library = self.runtime_library
         toolset = self.toolset or ""
         compile_options = self._conanfile.conf.get("tools.microsoft.msbuildtoolchain:compile_options",
@@ -161,6 +164,7 @@ class MSBuildToolchain(object):
             'compiler_flags': " ".join(self.cxxflags + self.cflags),
             'linker_flags': " ".join(self.ldflags),
             "cppstd": cppstd,
+            "cstd": cstd,
             "runtime_library": runtime_library,
             "toolset": toolset,
             "compile_options": compile_options,
diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py
index 844031489..e4e76737b 100644
--- a/conan/tools/microsoft/visual.py
+++ b/conan/tools/microsoft/visual.py
@@ -118,6 +118,7 @@ class VCVars:
         if vs_install_path == "":  # Empty string means "disable"
             return
 
+        msvc_update = conanfile.conf.get("tools.microsoft:msvc_update")
         if compiler == "clang":
             # The vcvars only needed for LLVM/Clang and VS ClangCL, who define runtime
             if not conanfile.settings.get_safe("compiler.runtime"):
@@ -127,20 +128,24 @@ class VCVars:
             vs_version = {"v140": "14",
                           "v141": "15",
                           "v142": "16",
-                          "v143": "17"}.get(toolset_version)
+                          "v143": "17",
+                          "v144": "17"}.get(toolset_version)
             if vs_version is None:
-                raise ConanException("Visual Studio Runtime version (v140-v143) not defined")
+                raise ConanException("Visual Studio Runtime version (v140-v144) not defined")
             vcvars_ver = {"v140": "14.0",
                           "v141": "14.1",
                           "v142": "14.2",
-                          "v143": "14.3"}.get(toolset_version)
+                          "v143": "14.3",
+                          "v144": "14.4"}.get(toolset_version)
+            if vcvars_ver and msvc_update is not None:
+                vcvars_ver += f"{msvc_update}"
         else:
             vs_version = vs_ide_version(conanfile)
             if int(vs_version) <= 14:
                 vcvars_ver = None
             else:
                 compiler_version = str(conanfile.settings.compiler.version)
-                compiler_update = conanfile.settings.get_safe("compiler.update", "")
+                compiler_update = msvc_update or conanfile.settings.get_safe("compiler.update", "")
                 # The equivalent of compiler 19.26 is toolset 14.26
                 vcvars_ver = "14.{}{}".format(compiler_version[-1], compiler_update)
 
diff --git a/conan/tools/qbs/qbs.py b/conan/tools/qbs/qbs.py
index db4bb87e0..d65a91b3f 100644
--- a/conan/tools/qbs/qbs.py
+++ b/conan/tools/qbs/qbs.py
@@ -1,6 +1,6 @@
 import os
 
-from conan.tools.build import build_jobs
+from conan.tools.build import build_jobs, cmd_args_to_string
 from conan.errors import ConanException
 
 
@@ -59,7 +59,7 @@ class Qbs(object):
             config = self._configuration[name]
             args.extend(_configuration_dict_to_commandlist(name, config))
 
-        cmd = 'qbs build %s' % (' '.join(args))
+        cmd = 'qbs build %s' % cmd_args_to_string(args)
         self._conanfile.run(cmd)
 
     def build_all(self):
@@ -79,7 +79,7 @@ class Qbs(object):
             config = self._configuration[name]
             args.extend(_configuration_dict_to_commandlist(name, config))
 
-        cmd = 'qbs build %s' % (' '.join(args))
+        cmd = 'qbs build %s' % cmd_args_to_string(args)
         self._conanfile.run(cmd)
 
     def install(self):
@@ -92,5 +92,5 @@ class Qbs(object):
         for name in self._configuration:
             args.append('config:%s' % name)
 
-        cmd = 'qbs install %s' % (' '.join(args))
+        cmd = 'qbs install %s' % cmd_args_to_string(args)
         self._conanfile.run(cmd)
diff --git a/conans/client/conanfile/configure.py b/conans/client/conanfile/configure.py
index 116a879a8..4b0aa99f1 100644
--- a/conans/client/conanfile/configure.py
+++ b/conans/client/conanfile/configure.py
@@ -1,7 +1,8 @@
 from conans.errors import conanfile_exception_formatter
 from conans.model.pkg_type import PackageType
 from conans.model.requires import BuildRequirements, TestRequirements, ToolRequirements
-from conans.client.conanfile.implementations import auto_shared_fpic_config_options, auto_shared_fpic_configure
+from conans.client.conanfile.implementations import auto_shared_fpic_config_options, \
+    auto_shared_fpic_configure, auto_language
 
 
 def run_configure_method(conanfile, down_options, profile_options, ref):
@@ -15,6 +16,8 @@ def run_configure_method(conanfile, down_options, profile_options, ref):
     elif "auto_shared_fpic" in conanfile.implements:
         auto_shared_fpic_config_options(conanfile)
 
+    auto_language(conanfile)  # default implementation removes `compiler.cstd`
+
     # Assign only the current package options values, but none of the dependencies
     is_consumer = conanfile._conan_is_consumer
     conanfile.options.apply_downstream(down_options, profile_options, ref, is_consumer)
diff --git a/conans/client/conanfile/implementations.py b/conans/client/conanfile/implementations.py
index 133ddcea7..14cabc760 100644
--- a/conans/client/conanfile/implementations.py
+++ b/conans/client/conanfile/implementations.py
@@ -17,3 +17,14 @@ def auto_shared_fpic_configure(conanfile):
 def auto_header_only_package_id(conanfile):
     if conanfile.options.get_safe("header_only") or conanfile.package_type is PackageType.HEADER:
         conanfile.info.clear()
+
+
+def auto_language(conanfile):
+    if not conanfile.languages:
+        conanfile.settings.rm_safe("compiler.cstd")
+        return
+    if "C" not in conanfile.languages:
+        conanfile.settings.rm_safe("compiler.cstd")
+    if "C++" not in conanfile.languages:
+        conanfile.settings.rm_safe("compiler.cppstd")
+        conanfile.settings.rm_safe("compiler.libcxx")
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index bf64917c7..23b5e28f5 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -100,6 +100,7 @@ compiler:
         threads: [null, posix, win32]  # Windows MinGW
         exception: [null, dwarf2, sjlj, seh]  # Windows MinGW
         cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]
     msvc:
         version: [170, 180, 190, 191, 192, 193, 194]
         update: [null, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
@@ -107,6 +108,7 @@ compiler:
         runtime_type: [Debug, Release]
         cppstd: [null, 14, 17, 20, 23]
         toolset: [null, v110_xp, v120_xp, v140_xp, v141_xp]
+        cstd: [null, 11, 17]
     clang:
         version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0",
                   "5.0", "6.0", "7.0", "7.1",
@@ -115,12 +117,14 @@ compiler:
         cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
         runtime: [null, static, dynamic]
         runtime_type: [null, Debug, Release]
-        runtime_version: [null, v140, v141, v142, v143]
+        runtime_version: [null, v140, v141, v142, v143, v144]
+        cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]
     apple-clang:
         version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1",
                   "10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0", "15", "15.0"]
         libcxx: [libstdc++, libc++]
         cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]
     intel-cc:
         version: ["2021.1", "2021.2", "2021.3", "2021.4", "2022.1", "2022.2",
                   "2022.3", "2023.0", "2023.1", "2023.2", "2024.0",]
diff --git a/conans/client/graph/compatibility.py b/conans/client/graph/compatibility.py
index 1d67e7cf5..a23669c88 100644
--- a/conans/client/graph/compatibility.py
+++ b/conans/client/graph/compatibility.py
@@ -23,7 +23,7 @@ def compatibility(conanfile):
 _default_cppstd_compat = """\
 # This file was generated by Conan. Remove this comment if you edit this file or Conan
 # will destroy your changes.
-from conan.tools.build import supported_cppstd
+from conan.tools.build import supported_cppstd, supported_cstd
 from conan.errors import ConanException
 
 
@@ -44,6 +44,14 @@ def cppstd_compat(conanfile):
         else: # The current cppst must be included in case there is other factor
             factors.append([{"compiler.cppstd": v} for v in cppstd_possible_values])
 
+    cstd = conanfile.settings.get_safe("compiler.cstd")
+    if cstd is not None and extension_properties.get("compatibility_cstd") is not False:
+        cstd_possible_values = supported_cstd(conanfile)
+        if cstd_possible_values is None:
+            conanfile.output.warning(f'No cstd compatibility defined for compiler "{compiler}"')
+        else:
+            factors.append([{"compiler.cstd": v} for v in cstd_possible_values if v != cstd])
+
     if compiler == "msvc":
         msvc_fallback = {"194": "193"}.get(compiler_version)
         if msvc_fallback:
diff --git a/conans/client/profile_loader.py b/conans/client/profile_loader.py
index 6b1ba23e8..cc4763fba 100644
--- a/conans/client/profile_loader.py
+++ b/conans/client/profile_loader.py
@@ -39,6 +39,7 @@ def profile_plugin(profile):
             except ConanException:
                 pass
     _check_correct_cppstd(settings)
+    _check_correct_cstd(settings)
 
 def _check_correct_cppstd(settings):
     from conan.tools.scm import Version
@@ -76,6 +77,36 @@ def _check_correct_cppstd(settings):
                     "14": "190"}.get(cppstd)
         if mver and version < mver:
             _error(compiler, cppstd, mver, version)
+
+
+def _check_correct_cstd(settings):
+    from conan.tools.scm import Version
+    def _error(compiler, cstd, min_version, version):
+        from conan.errors import ConanException
+        raise ConanException(f"The provided compiler.cstd={cstd} requires at least {compiler}"
+                             f">={min_version} but version {version} provided")
+    cstd = settings.get("compiler.cstd")
+    version = settings.get("compiler.version")
+
+    if cstd and version:
+        cstd = cstd.replace("gnu", "")
+        version = Version(version)
+        mver = None
+        compiler = settings.get("compiler")
+        if compiler == "gcc":
+            # TODO: right versions
+            mver = {}.get(cstd)
+        elif compiler == "clang":
+            # TODO: right versions
+            mver = {}.get(cstd)
+        elif compiler == "apple-clang":
+            # TODO: Right versions
+            mver = {}.get(cstd)
+        elif compiler == "msvc":
+            mver = {"17": "192",
+                    "11": "192"}.get(cstd)
+        if mver and version < mver:
+            _error(compiler, cppstd, mver, version)
 """
 
 
diff --git a/conans/client/subsystems.py b/conans/client/subsystems.py
index daba56c06..ac7ca25c7 100644
--- a/conans/client/subsystems.py
+++ b/conans/client/subsystems.py
@@ -82,6 +82,7 @@ def _windows_bash_wrapper(conanfile, command, env, envfiles_folder):
         # - CHERE_INVOKING is necessary to keep the CWD and not change automatically to the user home
         msys2_mode_env.define("MSYSTEM", _msystem)
         msys2_mode_env.define("MSYS2_PATH_TYPE", "inherit")
+        msys2_mode_env.unset("ORIGINAL_PATH")
         # So --login do not change automatically to the user home
         msys2_mode_env.define("CHERE_INVOKING", "1")
         path = os.path.join(conanfile.generators_folder, "msys2_mode.bat")
diff --git a/conans/model/conan_file.py b/conans/model/conan_file.py
index 96e819ff1..7fcdbf8ac 100644
--- a/conans/model/conan_file.py
+++ b/conans/model/conan_file.py
@@ -47,6 +47,7 @@ class ConanFile:
     default_options = None
     default_build_options = None
     package_type = None
+    languages = []
 
     implements = []
 
@@ -91,6 +92,8 @@ class ConanFile:
 
         if isinstance(self.generators, str):
             self.generators = [self.generators]
+        if isinstance(self.languages, str):
+            self.languages = [self.languages]
         if isinstance(self.settings, str):
             self.settings = [self.settings]
         self.requires = Requirements(self.requires, self.build_requires, self.test_requires,
@@ -134,6 +137,7 @@ class ConanFile:
         result["version"] = str(self.version) if self.version is not None else None
         result["topics"] = list(self.topics) if self.topics is not None else None
         result["package_type"] = str(self.package_type)
+        result["languages"] = self.languages
 
         settings = self.settings
         if settings is not None:
diff --git a/conans/model/conanfile_interface.py b/conans/model/conanfile_interface.py
index 0ebb1b1ff..2130ff85b 100644
--- a/conans/model/conanfile_interface.py
+++ b/conans/model/conanfile_interface.py
@@ -100,6 +100,10 @@ class ConanFileInterface:
     def package_type(self):
         return self._conanfile.package_type
 
+    @property
+    def languages(self):
+        return self._conanfile.languages
+
     @property
     def info(self):
         return self._conanfile.info
diff --git a/conans/model/conf.py b/conans/model/conf.py
index 7809f4d9d..e11037845 100644
--- a/conans/model/conf.py
+++ b/conans/model/conf.py
@@ -73,6 +73,7 @@ BUILT_IN_CONFS = {
     "tools.cmake.cmaketoolchain:toolset_arch": "Toolset architecture to be used as part of CMAKE_GENERATOR_TOOLSET in CMakeToolchain",
     "tools.cmake.cmaketoolchain:toolset_cuda": "(Experimental) Path to a CUDA toolset to use, or version if installed at the system level",
     "tools.cmake.cmaketoolchain:presets_environment": "String to define wether to add or not the environment section to the CMake presets. Empty by default, will generate the environment section in CMakePresets. Can take values: 'disabled'.",
+    "tools.cmake.cmaketoolchain:extra_variables": "Dictionary with variables to be injected in CMakeToolchain (potential override of CMakeToolchain defined variables)",
     "tools.cmake.cmake_layout:build_folder_vars": "Settings and Options that will produce a different build folder and different CMake presets names",
     "tools.cmake.cmake_layout:build_folder": "(Experimental) Allow configuring the base folder of the build for local builds",
     "tools.cmake.cmake_layout:test_folder": "(Experimental) Allow configuring the base folder of the build for test_package",


Test patch:
diff --git a/conan/test/utils/mocks.py b/conan/test/utils/mocks.py
index 6c1a160ef..bfed795b6 100644
--- a/conan/test/utils/mocks.py
+++ b/conan/test/utils/mocks.py
@@ -92,6 +92,7 @@ class ConanFileMock(ConanFile):
         self.options = options or Options()
         self.generators = []
         self.conf = Conf()
+        self.conf_build = Conf()
         self.folders = Folders()
         self.folders.set_base_source(".")
         self.folders.set_base_export_sources(".")
diff --git a/conan/test/utils/scm.py b/conan/test/utils/scm.py
index 29b35d941..280a56314 100644
--- a/conan/test/utils/scm.py
+++ b/conan/test/utils/scm.py
@@ -2,7 +2,7 @@ import os
 
 from conan.test.utils.test_files import temp_folder
 from conans.util.files import save_files, chdir
-from conans.util.runners import check_output_runner
+from conans.util.runners import detect_runner
 
 
 def git_create_bare_repo(folder=None, reponame="repo.git"):
@@ -10,7 +10,7 @@ def git_create_bare_repo(folder=None, reponame="repo.git"):
     cwd = os.getcwd()
     try:
         os.chdir(folder)
-        check_output_runner('git init --bare {}'.format(reponame))
+        detect_runner('git init --bare {}'.format(reponame))
         return os.path.join(folder, reponame).replace("\\", "/")
     finally:
         os.chdir(cwd)
@@ -24,7 +24,8 @@ def create_local_git_repo(files=None, branch=None, submodules=None, folder=None,
 
     def _run(cmd, p):
         with chdir(p):
-            return check_output_runner("git {}".format(cmd)).strip()
+            _, out = detect_runner("git {}".format(cmd))
+            return out.strip()
 
     _run("init .", tmp)
     _run('config user.name "Your Name"', tmp)
@@ -56,9 +57,10 @@ def git_add_changes_commit(folder, msg="fix"):
     try:
         os.chdir(folder)
         # Make sure user and email exist, otherwise it can error
-        check_output_runner('git config user.name "Your Name"')
-        check_output_runner('git config user.email "you@example.com"')
-        check_output_runner('git add . && git commit -m "{}"'.format(msg))
-        return check_output_runner("git rev-parse HEAD").strip()
+        detect_runner('git config user.name "Your Name"')
+        detect_runner('git config user.email "you@example.com"')
+        detect_runner('git add . && git commit -m "{}"'.format(msg))
+        _, out = detect_runner("git rev-parse HEAD")
+        return out.strip()
     finally:
         os.chdir(cwd)
diff --git a/test/conftest.py b/test/conftest.py
index 7c668e666..bc148aabe 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -155,9 +155,13 @@ tools_locations = {
         "system": {"path": {'Windows': "C:/cygwin64/bin"}},
     },
     'bazel': {
-        "default": "system",
-        "system": {"path": {'Windows': 'C:/bazel/bin',
-                            "Darwin": '/Users/jenkins/bin'}},
+        "default": "6.3.2",
+        "6.3.2": {"path": {'Linux': '/usr/share/bazel-6.3.2/bin',
+                           'Windows': 'C:/bazel-6.3.2/bin',
+                           'Darwin': '/Users/jenkins/bazel-6.3.2/bin'}},
+        "7.1.2": {"path": {'Linux': '/usr/share/bazel-7.1.2/bin',
+                           'Windows': 'C:/bazel-7.1.2/bin',
+                           'Darwin': '/Users/jenkins/bazel-7.1.2/bin'}},
     },
     'premake': {
         "exe": "premake5",
@@ -177,6 +181,7 @@ tools_locations = {
             "path": {'Darwin': f'{homebrew_root}/share/android-ndk'}
         }
     },
+    "qbs": {"disabled": True},
     # TODO: Intel oneAPI is not installed in CI yet. Uncomment this line whenever it's done.
     # "intel_oneapi": {
     #     "default": "2021.3",
diff --git a/test/functional/command/profile_test.py b/test/functional/command/profile_test.py
index c700ca591..454df2325 100644
--- a/test/functional/command/profile_test.py
+++ b/test/functional/command/profile_test.py
@@ -1,6 +1,5 @@
 import os
 import platform
-import subprocess
 import textwrap
 import unittest
 
@@ -11,9 +10,10 @@ from conan.test.utils.mocks import RedirectedTestOutput
 from conan.test.utils.tools import TestClient, redirect_output
 from conans.util.env import environment_update
 from conans.util.files import save
-from conans.util.runners import check_output_runner
+from conans.util.runners import detect_runner
 from conan.tools.microsoft.visual import vcvars_command
 
+
 class TestProfile(unittest.TestCase):
 
     def test_list_empty(self):
@@ -100,7 +100,7 @@ class DetectCompilersTest(unittest.TestCase):
         Test if gcc in Mac OS X is using apple-clang as frontend
         """
         # See: https://github.com/conan-io/conan/issues/2231
-        output = check_output_runner("gcc --version", stderr=subprocess.STDOUT)
+        _, output = detect_runner("gcc --version")
 
         if "clang" not in output:
             # Not test scenario gcc should display clang in output
diff --git a/test/functional/test_profile_detect_api.py b/test/functional/test_profile_detect_api.py
index 24f6b3f8d..1bac560e8 100644
--- a/test/functional/test_profile_detect_api.py
+++ b/test/functional/test_profile_detect_api.py
@@ -76,3 +76,17 @@ class TestProfileDetectAPI:
             user.confvar:libc_version={libc_version}
             """)
         assert expected in client.out
+
+    @pytest.mark.skipif(platform.system() != "Darwin", reason="Only OSX")
+    def test_profile_detect_darwin_sdk(self):
+        client = TestClient()
+        tpl1 = textwrap.dedent("""\
+            [settings]
+            os = "Macos"
+            os.sdk_version = {{ detect_api.detect_sdk_version(sdk="macosx")  }}
+            """)
+
+        client.save({"profile1": tpl1})
+        client.run("profile show -pr=profile1")
+        sdk_version = detect_api.detect_sdk_version(sdk="macosx")
+        assert f"os.sdk_version={sdk_version}" in client.out
diff --git a/test/functional/toolchains/meson/test_meson.py b/test/functional/toolchains/meson/test_meson.py
index a24f79600..8298c17b9 100644
--- a/test/functional/toolchains/meson/test_meson.py
+++ b/test/functional/toolchains/meson/test_meson.py
@@ -6,10 +6,10 @@ import textwrap
 
 import pytest
 
-from conans.model.recipe_ref import RecipeReference
 from conan.test.assets.sources import gen_function_cpp, gen_function_h
-from test.functional.toolchains.meson._base import TestMesonBase
 from conan.test.utils.tools import TestClient
+from conans.model.recipe_ref import RecipeReference
+from test.functional.toolchains.meson._base import TestMesonBase
 
 
 class MesonToolchainTest(TestMesonBase):
diff --git a/test/functional/toolchains/qbs/test_qbs.py b/test/functional/toolchains/qbs/test_qbs.py
new file mode 100644
index 000000000..c61439f21
--- /dev/null
+++ b/test/functional/toolchains/qbs/test_qbs.py
@@ -0,0 +1,14 @@
+import pytest
+
+from conan.test.utils.tools import TestClient
+
+@pytest.mark.parametrize('shared', [
+    ('False'),
+    ('True'),
+])
+@pytest.mark.tool("qbs")
+def test_api_qbs_create_lib(shared):
+    client = TestClient()
+    client.run("new qbs_lib -d name=hello -d version=1.0")
+    client.run("create . -o:h &:shared={shared}".format(shared=shared))
+    assert "compiling hello.cpp" in client.out
\ No newline at end of file
diff --git a/test/functional/util/test_cmd_args_to_string.py b/test/functional/util/test_cmd_args_to_string.py
index a03d78c5c..ac2372e05 100644
--- a/test/functional/util/test_cmd_args_to_string.py
+++ b/test/functional/util/test_cmd_args_to_string.py
@@ -7,7 +7,7 @@ import pytest
 from conan.tools.build import cmd_args_to_string
 from conan.test.utils.tools import TestClient
 from conans.util.files import chdir
-from conans.util.runners import check_output_runner
+from conans.util.runners import detect_runner
 
 
 @pytest.fixture(scope="module")
@@ -66,7 +66,7 @@ def test_unix_cases(application_folder, _input, output):
 
     # Check calling the exe that the arguments are the same we tried to input
     with chdir(application_folder):
-        cmd_parsed_output = check_output_runner("./{}".format(output))
+        _, cmd_parsed_output = detect_runner("./{}".format(output))
         interpreted_args = cmd_parsed_output.splitlines()
         real_args = _input[1:]
         assert real_args == interpreted_args
@@ -90,7 +90,7 @@ def test_windows_cases(application_folder, _input, output):
 
     # Check calling the exe that the arguments are the same we tried to input
     with chdir(application_folder):
-        cmd_parsed_output = check_output_runner(output)
+        _, cmd_parsed_output = detect_runner(output)
         interpreted_args = cmd_parsed_output.splitlines()
         real_args = _input[1:]
         assert real_args == interpreted_args
diff --git a/test/integration/command/runner_test.py b/test/integration/command/runner_test.py
index 9a68ec67f..6071b7109 100644
--- a/test/integration/command/runner_test.py
+++ b/test/integration/command/runner_test.py
@@ -34,7 +34,135 @@ def dockerfile_path(name=None):
 
 
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
+def test_create_docker_runner_cache_shared():
+    """
+    Tests the ``conan create . ``
+    """
+    client = TestClient()
+    profile_build = textwrap.dedent(f"""\
+    [settings]
+    arch=x86_64
+    build_type=Release
+    compiler=gcc
+    compiler.cppstd=gnu17
+    compiler.libcxx=libstdc++11
+    compiler.version=11
+    os=Linux
+    """)
+
+    profile_host = textwrap.dedent(f"""\
+    [settings]
+    arch=x86_64
+    build_type=Release
+    compiler=gcc
+    compiler.cppstd=gnu17
+    compiler.libcxx=libstdc++11
+    compiler.version=11
+    os=Linux
+    [runner]
+    type=docker
+    dockerfile={dockerfile_path()}
+    build_context={conan_base_path()}
+    image=conan-runner-default-test
+    cache=shared
+    remove=True
+    """)
+
+    client.save({"host": profile_host, "build": profile_build})
+    client.run("new cmake_lib -d name=pkg -d version=0.2")
+    client.run("create . -pr:h host -pr:b build")
+
+    assert "[100%] Built target example" in client.out
+    assert "Removing container" in client.out
+
+
+@pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
+def test_create_docker_runner_cache_shared_profile_from_cache():
+    """
+    Tests the ``conan create . ``
+    """
+    client = TestClient()
+    profile_build = textwrap.dedent(f"""\
+    [settings]
+    arch=x86_64
+    build_type=Release
+    compiler=gcc
+    compiler.cppstd=gnu17
+    compiler.libcxx=libstdc++11
+    compiler.version=11
+    os=Linux
+    """)
+
+    profile_host = textwrap.dedent(f"""\
+    [settings]
+    arch=x86_64
+    build_type=Release
+    compiler=gcc
+    compiler.cppstd=gnu17
+    compiler.libcxx=libstdc++11
+    compiler.version=11
+    os=Linux
+    [runner]
+    type=docker
+    dockerfile={dockerfile_path()}
+    build_context={conan_base_path()}
+    image=conan-runner-default-test
+    cache=shared
+    remove=True
+    """)
+
+    client.save({"default_host": profile_host, "default_build": profile_build}, path=client.cache.profiles_path)
+    client.run("new cmake_lib -d name=pkg -d version=0.2")
+    client.run("create . -pr:h default_host -pr:b default_build")
+
+    assert "[100%] Built target example" in client.out
+    assert "Removing container" in client.out
+
+
+@pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
+def test_create_docker_runner_cache_shared_profile_folder():
+    """
+    Tests the ``conan create . ``
+    """
+    client = TestClient()
+    profile_build = textwrap.dedent(f"""\
+    [settings]
+    arch=x86_64
+    build_type=Release
+    compiler=gcc
+    compiler.cppstd=gnu17
+    compiler.libcxx=libstdc++11
+    compiler.version=11
+    os=Linux
+    """)
+
+    profile_host = textwrap.dedent(f"""\
+    [settings]
+    arch=x86_64
+    build_type=Release
+    compiler=gcc
+    compiler.cppstd=gnu17
+    compiler.libcxx=libstdc++11
+    compiler.version=11
+    os=Linux
+    [runner]
+    type=docker
+    dockerfile={dockerfile_path()}
+    build_context={conan_base_path()}
+    image=conan-runner-default-test
+    cache=shared
+    remove=True
+    """)
+
+    client.save({"build": profile_build})
+    client.save({"docker_default": profile_host}, path = os.path.join(client.cache_folder, "profiles"))
+    client.run("new cmake_lib -d name=pkg -d version=0.2")
+    client.run("create . -pr:h docker_default -pr:b build")
+
+    assert "[100%] Built target example" in client.out
+    assert "Removing container" in client.out
+
+@pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
 def test_create_docker_runner_dockerfile_folder_path():
     """
     Tests the ``conan create . ``
@@ -105,7 +233,6 @@ def test_create_docker_runner_dockerfile_folder_path():
 
 
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
 def test_create_docker_runner_dockerfile_file_path():
     """
     Tests the ``conan create . ``
@@ -150,7 +277,6 @@ def test_create_docker_runner_dockerfile_file_path():
 
 
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
 @pytest.mark.parametrize("build_type,shared", [("Release", False), ("Debug", True)])
 @pytest.mark.tool("ninja")
 def test_create_docker_runner_with_ninja(build_type, shared):
@@ -215,55 +341,8 @@ def test_create_docker_runner_with_ninja(build_type, shared):
     assert 'cmake -G "Ninja"' in client.out
     assert "main: {}!".format(build_type) in client.out
 
-
-@pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
-def test_create_docker_runner_profile_abs_path():
-    """
-    Tests the ``conan create . ``
-    """
-    client = TestClient()
-    profile_build = textwrap.dedent(f"""\
-    [settings]
-    arch=x86_64
-    build_type=Release
-    compiler=gcc
-    compiler.cppstd=gnu17
-    compiler.libcxx=libstdc++11
-    compiler.version=11
-    os=Linux
-    """)
-    profile_host = textwrap.dedent(f"""\
-    [settings]
-    arch=x86_64
-    build_type=Release
-    compiler=gcc
-    compiler.cppstd=gnu17
-    compiler.libcxx=libstdc++11
-    compiler.version=11
-    os=Linux
-    [runner]
-    type=docker
-    dockerfile={dockerfile_path("Dockerfile_test")}
-    build_context={conan_base_path()}
-    image=conan-runner-default-test
-    cache=copy
-    remove=True
-    """)
-
-    client.save({"host": profile_host, "build": profile_build})
-    client.run("new cmake_lib -d name=pkg -d version=0.2")
-    client.run(f"create . -pr:h '{os.path.join(client.current_folder, 'host')}' -pr:b '{os.path.join(client.current_folder, 'build')}'")
-
-    assert "Restore: pkg/0.2" in client.out
-    assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe" in client.out
-    assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata" in client.out
-    assert "Removing container" in client.out
-
-
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
-def test_create_docker_runner_profile_abs_path_from_configfile():
+def test_create_docker_runner_from_configfile():
     """
     Tests the ``conan create . ``
     """
@@ -307,7 +386,7 @@ def test_create_docker_runner_profile_abs_path_from_configfile():
 
     client.save({"host": profile_host, "build": profile_build})
     client.run("new cmake_lib -d name=pkg -d version=0.2")
-    client.run(f"create . -pr:h '{os.path.join(client.current_folder, 'host')}' -pr:b '{os.path.join(client.current_folder, 'build')}'")
+    client.run("create . -pr:h 'host' -pr:b 'build'")
 
     assert "Container my-custom-conan-runner-container running" in client.out
     assert "Restore: pkg/0.2" in client.out
@@ -317,8 +396,7 @@ def test_create_docker_runner_profile_abs_path_from_configfile():
 
 
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
-def test_create_docker_runner_profile_abs_path_from_configfile_with_args():
+def test_create_docker_runner_from_configfile_with_args():
     """
     Tests the ``conan create . ``
     """
@@ -364,7 +442,7 @@ def test_create_docker_runner_profile_abs_path_from_configfile_with_args():
 
     client.save({"host": profile_host, "build": profile_build})
     client.run("new cmake_lib -d name=pkg -d version=0.2")
-    client.run(f"create . -pr:h '{os.path.join(client.current_folder, 'host')}' -pr:b '{os.path.join(client.current_folder, 'build')}'")
+    client.run("create . -pr:h 'host' -pr:b 'build'")
 
     assert "test/integration/command/dockerfiles/Dockerfile_args" in client.out
     assert "Restore: pkg/0.2" in client.out
@@ -374,7 +452,6 @@ def test_create_docker_runner_profile_abs_path_from_configfile_with_args():
 
 
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
 def test_create_docker_runner_default_build_profile():
     """
     Tests the ``conan create . ``
@@ -410,7 +487,6 @@ def test_create_docker_runner_default_build_profile():
 
 
 @pytest.mark.skipif(docker_skip('ubuntu:22.04'), reason="Only docker running")
-# @pytest.mark.xfail(reason="conan inside docker optional test")
 def test_create_docker_runner_default_build_profile_error():
     """
     Tests the ``conan create . ``
diff --git a/test/integration/command_v2/test_inspect.py b/test/integration/command_v2/test_inspect.py
index 129ee3761..8de7c470a 100644
--- a/test/integration/command_v2/test_inspect.py
+++ b/test/integration/command_v2/test_inspect.py
@@ -14,6 +14,7 @@ def test_basic_inspect():
                      '    shared: False',
                      'generators: []',
                      'label: ',
+                     'languages: []',
                      'name: foo',
                      'options:',
                      '    shared: False',
@@ -83,6 +84,7 @@ def test_normal_inspect():
                                    'generators: []',
                                    'homepage: <Your project homepage goes here>',
                                    'label: ',
+                                   'languages: []',
                                    'license: <Your project license goes here>',
                                    'name: pkg',
                                    'options:',
@@ -126,6 +128,7 @@ def test_requiremens_inspect():
     tc.run("inspect .")
     assert ['generators: []',
             'label: ',
+            'languages: []',
             "license: ['MIT', 'Apache']",
             'options:',
             'options_definitions:',
diff --git a/test/integration/package_id/test_cache_compatibles.py b/test/integration/package_id/test_cache_compatibles.py
index 35fe89e92..74f1c364c 100644
--- a/test/integration/package_id/test_cache_compatibles.py
+++ b/test/integration/package_id/test_cache_compatibles.py
@@ -311,6 +311,37 @@ class TestDefaultCompat:
         assert "valid standard!!" in c.out
         assert "pkg/0.1: CPPSTD: 17" in c.out
 
+    def test_check_min_cstd(self):
+        """ test that the check_min_cstd works fine wiht compatibility
+        """
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.build import check_min_cstd
+            class Pkg(ConanFile):
+                name = "pkg"
+                version = "0.1"
+                settings = "os", "arch", "compiler", "build_type"
+                languages = "C"
+                def validate(self):
+                    check_min_cstd(self, "17", False)
+                    self.output.info("valid standard!!")
+                def package_info(self):
+                    self.output.info("CSTD: {}".format(self.settings.compiler.cstd))
+            """)
+
+        c = TestClient()
+        c.save({"conanfile.py": conanfile})
+        settings = "-s compiler=gcc -s compiler.version=9 -s compiler.libcxx=libstdc++11"
+        c.run(f"create .  {settings} -s compiler.cstd=17")
+        assert "pkg/0.1: valid standard!!" in c.out
+        assert "pkg/0.1: CSTD: 17" in c.out
+        c.run(f"install {settings} --requires=pkg/0.1 -s compiler.cstd=11", assert_error=True)
+        assert "pkg/0.1: Invalid: Current cstd (11) is lower than the required C standard (17)."\
+               in c.out
+        c.run(f"install {settings} --requires=pkg/0.1 -s compiler.cstd=23")
+        assert "valid standard!!" in c.out
+        assert "pkg/0.1: CSTD: 17" in c.out
+
     def test_check_min_cppstd_interface(self):
         """ test that says that compatible binaries are ok, as long as the user defined
         cppstd>=14. The syntax is a bit forced, maybe we want to improve ``check_min_cppstd``
diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 81ad493a1..c21b35ffc 100644
--- a/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -68,7 +68,7 @@ def test_cross_build_linux_to_macos():
     macos_profile = textwrap.dedent("""
         [settings]
         os=Macos
-        os.sdk_version=13.1
+        os.version=13.1
         arch=x86_64
         compiler=apple-clang
         compiler.version=13
@@ -85,7 +85,7 @@ def test_cross_build_linux_to_macos():
     toolchain = client.load("conan_toolchain.cmake")
 
     assert "set(CMAKE_SYSTEM_NAME Darwin)" in toolchain
-    assert "set(CMAKE_SYSTEM_VERSION 13.1)" in toolchain
+    assert "set(CMAKE_SYSTEM_VERSION 22)" in toolchain
     assert "set(CMAKE_SYSTEM_PROCESSOR x86_64)" in toolchain
 
 
@@ -437,7 +437,7 @@ def test_cmaketoolchain_cmake_system_processor_cross_apple():
     client.run("install hello.py -pr:h=./profile_ios -pr:b=default -g CMakeToolchain")
     toolchain = client.load("conan_toolchain.cmake")
     assert "set(CMAKE_SYSTEM_NAME iOS)" in toolchain
-    assert "set(CMAKE_SYSTEM_VERSION 15.0)" in toolchain
+    assert "set(CMAKE_SYSTEM_VERSION 21)" in toolchain
     assert "set(CMAKE_SYSTEM_PROCESSOR arm64)" in toolchain
 
 
@@ -1501,7 +1501,6 @@ def test_toolchain_keep_absolute_paths():
     presets = json.loads(c.load(user_presets["include"][0]))
     assert os.path.isabs(presets["configurePresets"][0]["toolchainFile"])
 
-
 def test_output_dirs_gnudirs_local_default():
     # https://github.com/conan-io/conan/issues/14733
     c = TestClient()
@@ -1575,3 +1574,59 @@ def test_output_dirs_gnudirs_local_custom():
     c.run("build .")
     _assert_install(c.out)
     assert "CMAKE_INSTALL_PREFIX" not in c.out
+
+
+def test_toolchain_extra_variables():
+    windows_profile = textwrap.dedent("""
+        [settings]
+        os=Windows
+        arch=x86_64
+        [conf]
+        tools.cmake.cmaketoolchain:extra_variables={'CMAKE_GENERATOR_INSTANCE': '${GENERATOR_INSTANCE}/buildTools/', 'FOO': '42' }
+        """)
+
+    client = TestClient()
+    client.save({"conanfile.txt": "[generators]\nCMakeToolchain",
+                 "windows": windows_profile})
+
+    # Test passing extra_variables from pro ile
+    client.run("install . --profile:host=windows")
+    toolchain = client.load("conan_toolchain.cmake")
+    assert 'set(CMAKE_GENERATOR_INSTANCE "${GENERATOR_INSTANCE}/buildTools/")' in toolchain
+    assert 'set(FOO "42")' in toolchain
+
+    # Test input from command line passing dict between doble quotes
+    client.run(textwrap.dedent(r"""
+        install . -c tools.cmake.cmaketoolchain:extra_variables="{'CMAKE_GENERATOR_INSTANCE': '${GENERATOR_INSTANCE}/buildTools/', 'FOO': 42.2, 'DICT': {'value': 1}, 'CACHE_VAR': {'value': 'hello world', 'cache': True, 'type': 'BOOL', 'docstring': 'test variable'}}"
+    """)
+    )
+
+    toolchain = client.load("conan_toolchain.cmake")
+    assert 'set(CMAKE_GENERATOR_INSTANCE "${GENERATOR_INSTANCE}/buildTools/")' in toolchain
+    assert 'set(FOO 42.2)' in toolchain
+    assert 'set(DICT 1)' in toolchain
+    assert 'set(CACHE_VAR "hello world" CACHE BOOL "test variable")' in toolchain
+
+
+    client.run(textwrap.dedent("""
+        install . -c tools.cmake.cmaketoolchain:extra_variables="{'invalid': {'value': 'hello world', 'cache': 'true'}}"
+    """) , assert_error=True)
+    assert 'tools.cmake.cmaketoolchain:extra_variables "cache" must be a boolean (True/False)' in client.out
+
+    # Test invalid cache variable
+    client.run(textwrap.dedent("""
+        install . -c tools.cmake.cmaketoolchain:extra_variables="{'invalid': {'value': 'hello world', 'cache': True}}"
+    """) , assert_error=True)
+    assert 'tools.cmake.cmaketoolchain:extra_variables needs "type" defined for cache variable "invalid"' in client.out
+
+    client.run(textwrap.dedent("""
+        install . -c tools.cmake.cmaketoolchain:extra_variables="{'invalid': {'value': 'hello world', 'cache': True, 'type': 'INVALID_TYPE'}}"
+    """) , assert_error=True)
+    assert 'tools.cmake.cmaketoolchain:extra_variables invalid type "INVALID_TYPE" for cache variable "invalid". Possible types: BOOL, FILEPATH, PATH, STRING, INTERNAL' in client.out
+
+    client.run(textwrap.dedent("""
+        install . -c tools.cmake.cmaketoolchain:extra_variables="{'CACHE_VAR_DEFAULT_DOC': {'value': 'hello world', 'cache': True, 'type': 'PATH'}}"
+    """))
+    toolchain = client.load("conan_toolchain.cmake")
+    assert 'set(CACHE_VAR_DEFAULT_DOC "hello world" CACHE PATH "CACHE_VAR_DEFAULT_DOC")' in toolchain
+
diff --git a/test/integration/toolchains/gnu/test_autotoolstoolchain.py b/test/integration/toolchains/gnu/test_autotoolstoolchain.py
index c80468a71..7364274ae 100644
--- a/test/integration/toolchains/gnu/test_autotoolstoolchain.py
+++ b/test/integration/toolchains/gnu/test_autotoolstoolchain.py
@@ -266,6 +266,9 @@ def test_toolchain_and_compilers_build_context():
             assert 'export CC="gcc"' in content
             assert 'export CXX="g++"' in content
             assert 'export RC="windres"' in content
+            # Issue: https://github.com/conan-io/conan/issues/15486
+            assert 'export CC_FOR_BUILD="clang"' in content
+            assert 'export CXX_FOR_BUILD="clang++"' in content
     """)
     client = TestClient()
     client.save({
diff --git a/test/integration/toolchains/meson/test_mesontoolchain.py b/test/integration/toolchains/meson/test_mesontoolchain.py
index b7a2742f7..d9ca23ea9 100644
--- a/test/integration/toolchains/meson/test_mesontoolchain.py
+++ b/test/integration/toolchains/meson/test_mesontoolchain.py
@@ -1,13 +1,14 @@
 import os
 import platform
+import re
 import textwrap
 
 import pytest
 
 from conan.test.assets.genconanfile import GenConanfile
+from conan.test.utils.tools import TestClient
 from conan.tools.files import load
 from conan.tools.meson import MesonToolchain
-from conan.test.utils.tools import TestClient
 
 
 def test_apple_meson_keep_user_custom_flags():
@@ -104,6 +105,46 @@ def test_extra_flags_via_conf():
     assert "cpp_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content
 
 
+def test_extra_flags_via_toolchain():
+    profile = textwrap.dedent("""
+        [settings]
+        os=Windows
+        arch=x86_64
+        compiler=gcc
+        compiler.version=9
+        compiler.cppstd=17
+        compiler.libcxx=libstdc++
+        build_type=Release
+
+        [buildenv]
+        CFLAGS=-flag0 -other=val
+        CXXFLAGS=-flag0 -other=val
+        LDFLAGS=-flag0 -other=val
+   """)
+    t = TestClient()
+    conanfile = textwrap.dedent("""
+    from conan import ConanFile
+    from conan.tools.meson import MesonToolchain
+    class Pkg(ConanFile):
+        settings = "os", "compiler", "arch", "build_type"
+        def generate(self):
+            tc = MesonToolchain(self)
+            tc.extra_cxxflags = ["-flag1", "-flag2"]
+            tc.extra_cflags = ["-flag3", "-flag4"]
+            tc.extra_ldflags = ["-flag5", "-flag6"]
+            tc.extra_defines = ["define1=0"]
+            tc.generate()
+    """)
+    t.save({"conanfile.py": conanfile,
+            "profile": profile})
+    t.run("install . -pr:h=profile -pr:b=profile")
+    content = t.load(MesonToolchain.native_filename)
+    assert "cpp_args = ['-flag0', '-other=val', '-flag1', '-flag2', '-Ddefine1=0', '-D_GLIBCXX_USE_CXX11_ABI=0']" in content
+    assert "c_args = ['-flag0', '-other=val', '-flag3', '-flag4', '-Ddefine1=0']" in content
+    assert "c_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content
+    assert "cpp_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content
+
+
 def test_linker_scripts_via_conf():
     profile = textwrap.dedent("""
         [settings]
@@ -155,6 +196,29 @@ def test_correct_quotes():
     assert "buildtype = 'release'" in content
 
 
+def test_c_std():
+    profile = textwrap.dedent("""
+       [settings]
+       os=Windows
+       arch=x86_64
+       compiler=gcc
+       compiler.version=9
+       compiler.cstd=11
+       build_type=Release
+       """)
+    t = TestClient()
+    t.save({"conanfile.py": GenConanfile().with_settings("os", "compiler", "build_type", "arch")
+                                          .with_generator("MesonToolchain")
+                                          .with_class_attribute("languages='C'"),
+            "profile": profile})
+
+    t.run("install . -pr:h=profile -pr:b=profile")
+    content = t.load(MesonToolchain.native_filename)
+    assert "c_std = 'c11'" in content
+    assert "backend = 'ninja'" in content
+    assert "buildtype = 'release'" in content
+
+
 def test_deactivate_nowrap():
     # https://github.com/conan-io/conan/issues/10671
     t = TestClient()
@@ -534,3 +598,51 @@ def test_compiler_path_with_spaces():
     conan_meson_native = client.load("conan_meson_native.ini")
     assert "c = 'c compiler path with spaces'" in conan_meson_native
     assert "cpp = 'cpp compiler path with spaces'" in conan_meson_native
+
+
+def test_meson_sysroot_app():
+    """Testing when users pass tools.build:sysroot on the profile with Meson
+
+    The generated conan_meson_cross.ini needs to contain both sys_root property to fill the
+    PKG_CONFIG_PATH and the compiler flags with --sysroot.
+
+    When cross-building, Meson needs both compiler_executables in the config, otherwise it will fail
+    when running setup.
+    """
+    sysroot = "/my/new/sysroot/path"
+    client = TestClient()
+    profile = textwrap.dedent(f"""
+    [settings]
+    os = Macos
+    arch = armv8
+    compiler = apple-clang
+    compiler.version = 13.0
+    compiler.libcxx = libc++
+
+    [conf]
+    tools.build:sysroot={sysroot}
+    tools.build:verbosity=verbose
+    tools.compilation:verbosity=verbose
+    tools.apple:sdk_path=/my/sdk/path
+    """)
+    profile_build = textwrap.dedent(f"""
+    [settings]
+    os = Macos
+    arch = x86_64
+    compiler = apple-clang
+    compiler.version = 13.0
+    compiler.libcxx = libc++
+    """)
+    client.save({"conanfile.py": GenConanfile(name="hello", version="0.1")
+                .with_settings("os", "arch", "compiler", "build_type")
+                .with_generator("MesonToolchain"),
+                 "build": profile_build,
+                 "host": profile})
+    client.run("install . -pr:h host -pr:b build")
+    # Check the meson configuration file
+    conan_meson = client.load(os.path.join(client.current_folder, "conan_meson_cross.ini"))
+    assert f"sys_root = '{sysroot}'\n" in conan_meson
+    assert re.search(r"c_args =.+--sysroot={}.+".format(sysroot), conan_meson)
+    assert re.search(r"c_link_args =.+--sysroot={}.+".format(sysroot), conan_meson)
+    assert re.search(r"cpp_args =.+--sysroot={}.+".format(sysroot), conan_meson)
+    assert re.search(r"cpp_link_args =.+--sysroot={}.+".format(sysroot), conan_meson)
diff --git a/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py b/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py
index 5ea435a3f..e5afa10d7 100644
--- a/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py
+++ b/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py
@@ -130,6 +130,21 @@ def test_cppstd():
     assert "/std:c++17" in env["CXXFLAGS"]
 
 
+def test_cstd():
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings(
+        {"build_type": "Release",
+         "arch": "x86",
+         "compiler": "gcc",
+         "compiler.libcxx": "libstdc++11",
+         "compiler.version": "7.1",
+         "compiler.cstd": "17"})
+    conanfile.settings_build = MockSettings({"os": "Linux", "arch": "x86"})
+    be = AutotoolsToolchain(conanfile)
+    env = be.vars()
+    assert "-std=c17" in env["CFLAGS"]
+
+
 def test_fpic():
     conanfile = ConanFileMock()
     conanfile.settings = MockSettings({"os": "Linux"})
diff --git a/test/unittests/tools/microsoft/test_msbuild.py b/test/unittests/tools/microsoft/test_msbuild.py
index 9f0e5b1bf..3fc984531 100644
--- a/test/unittests/tools/microsoft/test_msbuild.py
+++ b/test/unittests/tools/microsoft/test_msbuild.py
@@ -104,7 +104,8 @@ def test_msbuild_standard():
     conanfile.conf.define("tools.microsoft.msbuild:installation_path", ".")
     conanfile.settings = "os", "compiler", "build_type", "arch"
     conanfile.settings = Settings({"build_type": ["Release"],
-                                   "compiler": {"msvc": {"version": ["193"], "cppstd": ["20"]}},
+                                   "compiler": {"msvc": {"version": ["193"], "cppstd": ["20"],
+                                                         "cstd": ["17"]}},
                                    "os": ["Windows"],
                                    "arch": ["x86_64"]})
     conanfile.settings_build = conanfile.settings
@@ -112,6 +113,7 @@ def test_msbuild_standard():
     conanfile.settings.compiler = "msvc"
     conanfile.settings.compiler.version = "193"
     conanfile.settings.compiler.cppstd = "20"
+    conanfile.settings.compiler.cstd = "17"
     conanfile.settings.os = "Windows"
     conanfile.settings.arch = "x86_64"
 
@@ -119,6 +121,7 @@ def test_msbuild_standard():
     props_file = os.path.join(test_folder, 'conantoolchain_release_x64.props')
     msbuild.generate()
     assert '<LanguageStandard>stdcpp20</LanguageStandard>' in load(props_file)
+    assert '<LanguageStandard_C>stdc17</LanguageStandard_C>' in load(props_file)
 
 
 def test_resource_compile():
diff --git a/test/unittests/util/detect_test.py b/test/unittests/util/detect_test.py
index 28b004230..1ac0e59a9 100644
--- a/test/unittests/util/detect_test.py
+++ b/test/unittests/util/detect_test.py
@@ -1,8 +1,11 @@
 import unittest
 
 import mock
+from unittest.mock import patch
+import pytest
 from parameterized import parameterized
 
+from conan.internal.api.detect_api import _cc_compiler
 from conans.client.conf.detect import detect_defaults_settings
 from conans.model.version import Version
 from conan.test.utils.mocks import RedirectedTestOutput
@@ -56,3 +59,18 @@ class DetectTest(unittest.TestCase):
             with environment_update({"CC": "clang-9 --gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/9"}):
                 detect_defaults_settings()
                 self.assertIn("CC and CXX: clang-9 --gcc-toolchain", output)
+
+
+@pytest.mark.parametrize("version_return,expected_version", [
+    ["cc.exe (Rev3, Built by MSYS2 project) 14.1.0", "14.1.0"],
+    ["g++ (Conan-Build-gcc--binutils-2.42) 14.1.0", "14.1.0"],
+    ["clang version 18.1.0rc (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18.1.0"],
+    ["cc.exe (Rev3, Built by MSYS2 project) 14.0", "14.0"],
+    ["clang version 18 (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18"],
+    ["cc.exe (Rev3, Built by MSYS2 project) 14", "14"],
+])
+@patch("conan.internal.api.detect_api.detect_runner")
+def test_detect_cc_versionings(detect_runner_mock, version_return, expected_version):
+    detect_runner_mock.return_value = 0, version_return
+    compiler, installed_version, compiler_exe = _cc_compiler()
+    assert installed_version == Version(expected_version)