Repository: conan-io/conan
Pull request #11780 (2022-08-04 14:36:14)

add clang 16
Changelog: (Feature | Fix | Bugfix): Add clang 16
Docs: https://github.com/conan-io/docs/pull/XXXX

- [x] Refer to the issue that supports this Pull Request.
- [x] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).
- [x] 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. 

<sup>**Note:** By default this PR will skip the slower tests and will use a limited set of python versions. Check [here](https://github.com/conan-io/conan/blob/develop/.github/PR_INCREASE_TESTING.md) how to increase the testing level by writing some tags in the current PR body text.</sup>


paulocoutinhox: @czoido done
czoido: Hi @paulocoutinhox,

Thanks for the contribution. Could you check that the the cppstd keeps being "gnu++14" for clang 16?
paulocoutinhox: > Hi @paulocoutinhox,
> 
> Thanks for the contribution. Could you check that the the cppstd keeps being "gnu++14" for clang 16?

According to their website:
https://clang.llvm.org/cxx_status.html

```
By default, Clang builds C++ code according to the C++14 standard. You can use Clang in C++14 mode with the -std=c++14 option (use -std=c++1y in Clang 3.4 and earlier).
```

Patch:
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 5db4af04e..9d698dd50 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -313,7 +313,7 @@ class AndroidSystemBlock(Block):
         android_ndk_path = android_ndk_path.replace("\\", "/")
 
         ctxt_toolchain = {
-            'android_platform': self._conanfile.settings.os.api_level,
+            'android_platform': 'android-' + str(self._conanfile.settings.os.api_level),
             'android_abi': android_abi,
             'android_stl': libcxx_str,
             'android_ndk_path': android_ndk_path,
diff --git a/conan/tools/meson/helpers.py b/conan/tools/meson/helpers.py
index 28cb09822..f3da633ee 100644
--- a/conan/tools/meson/helpers.py
+++ b/conan/tools/meson/helpers.py
@@ -58,7 +58,7 @@ _cppstd_map = {
     '11': "c++11", 'gnu11': "gnu++11",
     '14': "c++14", 'gnu14': "gnu++14",
     '17': "c++17", 'gnu17': "gnu++17",
-    '20': "c++1z", 'gnu20': "gnu++1z"
+    '20': "c++20", 'gnu20': "gnu++20"
 }
 
 
diff --git a/conan/tools/scm/__init__.py b/conan/tools/scm/__init__.py
index 9d4097bc7..59846cc18 100644
--- a/conan/tools/scm/__init__.py
+++ b/conan/tools/scm/__init__.py
@@ -1,2 +1,200 @@
 from conan.tools.scm.git import Git
-from conans.model.version import Version
+# develop2 uncomment the next line
+# from conans.model.version import Version
+
+
+# ######## DEVELOP2: Delete all the contents from here, this is copy-paste from the Version model
+# ######## at conans.model.version (for an easier migration)
+from functools import total_ordering
+from conans.errors import ConanException
+
+
+@total_ordering
+class _VersionItem:
+    """ a single "digit" in a version, like X.Y.Z all X and Y and Z are VersionItems
+    They can be int or strings
+    """
+    def __init__(self, item):
+        try:
+            self._v = int(item)
+        except ValueError:
+            self._v = item
+
+    @property
+    def value(self):
+        return self._v
+
+    def __str__(self):
+        return str(self._v)
+
+    def __add__(self, other):
+        # necessary for the "bump()" functionality. Other aritmetic operations are missing
+        return self._v + other
+
+    def __eq__(self, other):
+        if not isinstance(other, _VersionItem):
+            other = _VersionItem(other)
+        return self._v == other._v
+
+    def __hash__(self):
+        return hash(self._v)
+
+    def __lt__(self, other):
+        """
+        @type other: _VersionItem
+        """
+        if not isinstance(other, _VersionItem):
+            other = _VersionItem(other)
+        try:
+            return self._v < other._v
+        except TypeError:
+            return str(self._v) < str(other._v)
+
+
+@total_ordering
+class Version:
+    """
+    This is NOT an implementation of semver, as users may use any pattern in their versions.
+    It is just a helper to parse "." or "-" and compare taking into account integers when possible
+    """
+    def __init__(self, value):
+        value = str(value)
+        self._value = value
+
+        items = value.rsplit("+", 1)  # split for build
+        if len(items) == 2:
+            value, build = items
+            self._build = Version(build)  # This is a nested version by itself
+        else:
+            value = items[0]
+            self._build = None
+
+        items = value.rsplit("-", 1)  # split for pre-release
+        if len(items) == 2:
+            value, pre = items
+            self._pre = Version(pre)  # This is a nested version by itself
+        else:
+            value = items[0]
+            self._pre = None
+        items = value.split(".")
+        items = [_VersionItem(item) for item in items]
+        self._items = tuple(items)
+        while items and items[-1].value == 0:
+            del items[-1]
+        self._nonzero_items = tuple(items)
+
+    def bump(self, index):
+        """
+           Increments by 1 the version field at the specified index, setting to 0 the fields
+            on the right.
+           2.5 => bump(1) => 2.6
+           1.5.7 => bump(0) => 2.0.0
+        """
+        # this method is used to compute version ranges from tilde ~1.2 and caret ^1.2.1 ranges
+        # TODO: at this moment it only works for digits, cannot increment pre-release or builds
+        # better not make it public yet, keep it internal
+        items = list(self._items[:index])
+        try:
+            items.append(self._items[index]+1)
+        except TypeError:
+            raise ConanException(f"Cannot bump '{self._value} version index {index}, not an int")
+        items.extend([0] * (len(items) - index - 1))
+        v = ".".join(str(i) for i in items)
+        # prerelease and build are dropped while bumping digits
+        result = Version(v)
+        return result
+
+    def upper_bound(self, index):
+        items = list(self._items[:index])
+        try:
+            items.append(self._items[index] + 1)
+        except TypeError:
+            raise ConanException(f"Cannot bump '{self._value} version index {index}, not an int")
+        items.extend([0] * (len(items) - index - 1))
+        v = ".".join(str(i) for i in items)
+        v += "-"  # Exclude prereleases
+        result = Version(v)
+        return result
+
+    @property
+    def pre(self):
+        return self._pre
+
+    @property
+    def build(self):
+        return self._build
+
+    @property
+    def main(self):
+        return self._items
+
+    @property
+    def major(self):
+        try:
+            return self.main[0]
+        except IndexError:
+            return None
+
+    @property
+    def minor(self):
+        try:
+            return self.main[1]
+        except IndexError:
+            return None
+
+    @property
+    def patch(self):
+        try:
+            return self.main[2]
+        except IndexError:
+            return None
+
+    @property
+    def micro(self):
+        try:
+            return self.main[3]
+        except IndexError:
+            return None
+
+    def __str__(self):
+        return self._value
+
+    def __repr__(self):
+        return self._value
+
+    def __eq__(self, other):
+        if other is None:
+            return False
+        if isinstance(other, str):
+            other = Version(other)
+
+        return (self._nonzero_items, self._pre, self._build) ==\
+               (other._nonzero_items, other._pre, other._build)
+
+    def __hash__(self):
+        return hash((self._nonzero_items, self._pre, self._build))
+
+    def __lt__(self, other):
+        if other is None:
+            return False
+        if not isinstance(other, Version):
+            other = Version(other)
+
+        if self._pre:
+            if other._pre:  # both are pre-releases
+                return (self._nonzero_items, self._pre, self._build) < \
+                       (other._nonzero_items, other._pre, other._build)
+            else:  # Left hand is pre-release, right side is regular
+                if self._nonzero_items == other._nonzero_items:  # Problem only happens if both equal
+                    return True
+                else:
+                    return self._nonzero_items < other._nonzero_items
+        else:
+            if other._pre:  # Left hand is regular, right side is pre-release
+                if self._nonzero_items == other._nonzero_items:  # Problem only happens if both equal
+                    return False
+                else:
+                    return self._nonzero_items < other._nonzero_items
+            else:  # None of them is pre-release
+                return (self._nonzero_items, self._build) < (other._nonzero_items, other._build)
+
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index 4e1212307..25768c904 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -118,7 +118,7 @@ _t_default_settings_yml = Template(textwrap.dedent("""
         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",
-                      "8", "9", "10", "11", "12", "13", "14", "15"]
+                      "8", "9", "10", "11", "12", "13", "14", "15", "16"]
             libcxx: [None, libstdc++, libstdc++11, libc++, c++_shared, c++_static]
             cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
             runtime: [None, MD, MT, MTd, MDd, static, dynamic]
diff --git a/conans/client/migrations_settings.py b/conans/client/migrations_settings.py
index 3ade307f4..db3ec951d 100644
--- a/conans/client/migrations_settings.py
+++ b/conans/client/migrations_settings.py
@@ -3718,4 +3718,155 @@ settings_1_50_1 = settings_1_50_0
 settings_1_51_0 = settings_1_50_1
 settings_1_51_1 = settings_1_51_0
 
-settings_1_52_0 = settings_1_51_1
+settings_1_52_0 = """
+# Only for cross building, 'os_build/arch_build' is the system that runs Conan
+os_build: [Windows, WindowsStore, Linux, Macos, FreeBSD, SunOS, AIX, VxWorks]
+arch_build: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7]
+
+# Only for building cross compilation tools, 'os_target/arch_target' is the system for
+# which the tools generate code
+os_target: [Windows, Linux, Macos, Android, iOS, watchOS, tvOS, FreeBSD, SunOS, AIX, Arduino, Neutrino]
+arch_target: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+
+# Rest of the settings are "host" settings:
+# - For native building/cross building: Where the library/program will run.
+# - For building cross compilation tools: Where the cross compiler will run.
+os:
+    Windows:
+        subsystem: [None, cygwin, msys, msys2, wsl]
+    WindowsStore:
+        version: ["8.1", "10.0"]
+    WindowsCE:
+        platform: ANY
+        version: ["5.0", "6.0", "7.0", "8.0"]
+    Linux:
+    iOS:
+        version: &ios_version
+                 ["7.0", "7.1", "8.0", "8.1", "8.2", "8.3", "9.0", "9.1", "9.2", "9.3", "10.0", "10.1", "10.2", "10.3",
+                  "11.0", "11.1", "11.2", "11.3", "11.4", "12.0", "12.1", "12.2", "12.3", "12.4",
+                  "13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7",
+                  "14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7", "14.8",
+                  "15.0", "15.1", "15.2", "15.3", "15.4"]
+        sdk: [None, "iphoneos", "iphonesimulator"]
+        sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
+                      "13.0", "13.1", "13.2", "13.4", "13.5", "13.6", "13.7",
+                      "14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "15.0", "15.2", "15.4"]
+    watchOS:
+        version: ["4.0", "4.1", "4.2", "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2",
+                  "7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6", "8.0", "8.1", "8.3", "8.4", "8.5"]
+        sdk: [None, "watchos", "watchsimulator"]
+        sdk_version: [None, "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2",
+                      "7.0", "7.1", "7.2", "7.4", "8.0", "8.0.1", "8.3", "8.5"]
+    tvOS:
+        version: ["11.0", "11.1", "11.2", "11.3", "11.4", "12.0", "12.1", "12.2", "12.3", "12.4",
+                  "13.0", "13.2", "13.3", "13.4", "14.0", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7",
+                  "15.0", "15.1", "15.2", "15.3", "15.4"]
+        sdk: [None, "appletvos", "appletvsimulator"]
+        sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
+                      "13.0", "13.1", "13.2", "13.4", "14.0", "14.2", "14.3", "14.5", "15.0", "15.2", "15.4"]
+    Macos:
+        version: [None, "10.6", "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", "10.14", "10.15", "11.0", "12.0", "13.0"]
+        sdk: [None, "macosx"]
+        sdk_version: [None, "10.13", "10.14", "10.15", "11.0", "11.1", "11.3", "12.0", "12.1", "12.3"]
+        subsystem:
+            None:
+            catalyst:
+                ios_version: *ios_version
+    Android:
+        api_level: ANY
+    FreeBSD:
+    SunOS:
+    AIX:
+    Arduino:
+        board: ANY
+    Emscripten:
+    Neutrino:
+        version: ["6.4", "6.5", "6.6", "7.0", "7.1"]
+    baremetal:
+    VxWorks:
+        version: ["7"]
+arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+compiler:
+    sun-cc:
+        version: ["5.10", "5.11", "5.12", "5.13", "5.14", "5.15"]
+        threads: [None, posix]
+        libcxx: [libCstd, libstdcxx, libstlport, libstdc++]
+    gcc: &gcc
+        version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9",
+                  "5", "5.1", "5.2", "5.3", "5.4", "5.5",
+                  "6", "6.1", "6.2", "6.3", "6.4", "6.5",
+                  "7", "7.1", "7.2", "7.3", "7.4", "7.5",
+                  "8", "8.1", "8.2", "8.3", "8.4",
+                  "9", "9.1", "9.2", "9.3", "9.4",
+                  "10", "10.1", "10.2", "10.3",
+                  "11", "11.1", "11.2",
+                  "12"]
+        libcxx: [libstdc++, libstdc++11]
+        threads: [None, posix, win32]  # Windows MinGW
+        exception: [None, dwarf2, sjlj, seh]  # Windows MinGW
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+    Visual Studio: &visual_studio
+        runtime: [MD, MT, MTd, MDd]
+        version: ["8", "9", "10", "11", "12", "14", "15", "16", "17"]
+        toolset: [None, v90, v100, v110, v110_xp, v120, v120_xp,
+                  v140, v140_xp, v140_clang_c2, LLVM-vs2012, LLVM-vs2012_xp,
+                  LLVM-vs2013, LLVM-vs2013_xp, LLVM-vs2014, LLVM-vs2014_xp,
+                  LLVM-vs2017, LLVM-vs2017_xp, v141, v141_xp, v141_clang_c2, v142,
+                  llvm, ClangCL, v143]
+        cppstd: [None, 14, 17, 20, 23]
+    msvc:
+        version: [170, 180, 190, 191, 192, 193]
+        update: [None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        runtime: [static, dynamic]
+        runtime_type: [Debug, Release]
+        cppstd: [98, 14, 17, 20, 23]
+        toolset: [None, v110_xp, v120_xp, v140_xp, v141_xp]
+    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",
+                  "8", "9", "10", "11", "12", "13", "14", "15", "16"]
+        libcxx: [None, libstdc++, libstdc++11, libc++, c++_shared, c++_static]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, MD, MT, MTd, MDd, static, dynamic]
+        runtime_type: [None, Debug, Release]
+    apple-clang: &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"]
+        libcxx: [libstdc++, libc++]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20]
+    intel:
+        version: ["11", "12", "13", "14", "15", "16", "17", "18", "19", "19.1"]
+        update: [None, ANY]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exception: [None]
+            Visual Studio:
+                <<: *visual_studio
+            apple-clang:
+                <<: *apple_clang
+    intel-cc:
+        version: ["2021.1", "2021.2", "2021.3"]
+        update: [None, ANY]
+        mode: ["icx", "classic", "dpcpp"]
+        libcxx: [None, libstdc++, libstdc++11, libc++]
+        cppstd: [None, 98, gnu98, 03, gnu03, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, static, dynamic]
+        runtime_type: [None, Debug, Release]
+    qcc:
+        version: ["4.4", "5.4", "8.3"]
+        libcxx: [cxx, gpp, cpp, cpp-ne, accp, acpp-ne, ecpp, ecpp-ne]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]
+    mcst-lcc:
+        version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exceptions: [None]
+
+build_type: [None, Debug, Release, RelWithDebInfo, MinSizeRel]
+
+
+cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]  # Deprecated, use compiler.cppstd
+"""


Test patch:
diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 08262873f..d22ee397a 100644
--- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -491,7 +491,16 @@ def test_android_c_library():
 
         """)
     client.save({"conanfile.py": conanfile})
-    client.run("create . foo/1.0@ -s os=Android -s os.api_level=23 -c tools.android:ndk_path=/foo")
+    # Settings
+    settings = "-s arch=x86_64 -s os=Android -s os.api_level=23 -c tools.android:ndk_path=/foo"
+    # Checking the Android variables created
+    # Issue: https://github.com/conan-io/conan/issues/11798
+    client.run("install . " + settings)
+    conan_toolchain = client.load(os.path.join(client.current_folder, "conan_toolchain.cmake"))
+    assert "set(ANDROID_PLATFORM android-23)" in conan_toolchain
+    assert "set(ANDROID_ABI x86_64)" in conan_toolchain
+    assert "include(/foo/build/cmake/android.toolchain.cmake)" in conan_toolchain
+    client.run("create . foo/1.0@ " + settings)
 
 
 def test_user_presets_version2():
diff --git a/conans/test/unittests/tools/scm/test_version.py b/conans/test/unittests/tools/scm/test_version.py
index bdb83344a..7c52bb49e 100644
--- a/conans/test/unittests/tools/scm/test_version.py
+++ b/conans/test/unittests/tools/scm/test_version.py
@@ -16,8 +16,17 @@ def test_version():
             def configure(self):
                 v = Version(self.settings.compiler.version)
                 assert v > "10"
+
+                v = Version("1.2.3")
+                self.output.warning(f"The major of 1.2.3 is {v.major}")
+                self.output.warning(f"The minor of 1.2.3 is {v.minor}")
+                self.output.warning(f"The patch of 1.2.3 is {v.patch}")
         """)
     c.save({"conanfile.py": conanfile})
     settings = "-s compiler=gcc -s compiler.libcxx=libstdc++11"
     c.run("create . {} -s compiler.version=11".format(settings))
+    assert "The major of 1.2.3 is 1" in c.out
+    assert "The minor of 1.2.3 is 2" in c.out
+    assert "The patch of 1.2.3 is 3" in c.out
+
     c.run("create . {} -s compiler.version=9".format(settings), assert_error=True)