[RFC] Upgrading LLVM's minimum required CMake version

At the moment libc++ ships its dylib using C++20. This is needed since the dylib contains code using C++20. All exceptions are anchored in the dylib and in C++20 std::format_error has been added. Some C++23 features might require libc++ to switch to C++23. (Whether or not it is required, depends on which code end up in the dylib and which code is header only.) The easiest way to switch, is by setting the CMake property CXX_STANDARD to 23. The value 23 requires CMake 3.20.0 or newer. To prepare for this future change I propose to update the CMake requirement from 3.13.4 (released 4 February 2019) to CMake 3.20.0 (23 March 2021). Historically we tried to raise the CMake required version for all subprojects [1] and I propose to do that again. The goal is to make CMake 3.20.0 required in LLVM 17.

The proposal to achieve that goal is:

  • Immediately let CMake issue a diagnostic when the CMake version is less than 3.20.0, this patch will be considered a breaking change.
  • Notify all build bot owners.
  • After LLVM 16 has been branched update the required CMake version in main to 3.20.0, this patch will be considered a breaking change.
  • After all build bots are green all send a message we can use CMake 3.20.0 features.

I volunteer to make these changes.

The current CMake support for the various Linux distributions is (pkgs.org):

CentOS 7 (released 2014-07-07) 2.8.12 (EPEL 3.14.6)
CentOS 8 (released 8 2019-09-24) 3.20.2
CentOS 9 Stream 3.20.2
Debian 10 (released 6 July 2019) 3.13.4
Debian 11 (released 14 August 2021) 3.18.4 (backports has 3.24.2)
FreeBSD 12 (released 11 December 2018) 2.23.2
FreeBSD 13 (released 13 April 2021) 3.24.2
NetBSD 8 (released 17 July 2018) 3.22.3
NetBSD 9 (released 14 February 2020) 3.23.2
Ubuntu 20.04 (release April 2020) 3.16.3
Ubuntu 22.04 (release April 2022) 3.22.1
macOS latest version is readily available through Homebrew
Windows: You can install it yourself or use the one bundled with Visual Studio.

CMake also offers prebuilt binaries for Linux, MacOS, and Windows.

So the proposed change will mean we no longer directly support CentOS 7, Debian 10, and Ubuntu 20.04. All these Distributions have a newer release available.

The are other new interesting features between 3.13.4 and 3.20, the release notes are available here:

I don’t work a lot on our CMake infrastructure so I haven’t looked a which of these features can be interesting for the LLVM Project. However in a previous thread some benefits were listed:
CMake 3.14 (released March 14th 2019):

  • file(CREATE_LINK) to create hard or symbolic links
  • if(DEFINED CACHE{VAR}) for checking if a cache variable is defined
  • $<IN_LIST:…> generator expression correctly handles empty argument
  • Fixes for object library linking propagation
  • Link options to manage position independent executables added automatically

CMake 3.15 (released July 17th 2019):

  • list(PREPEND), list(POP_FRONT) and list(POP_BACK) added
  • New message() types NOTICE, VERBOSE, DEBUG and TRACE
  • string(REPEAT) added
  • MSVC_RUNTIME_LIBRARY target property and CMAKE_MSVC_RUNTIME_LIBRARY variable to select the runtime library type for MSVC
  • $<C_COMPILER_ID:…>, $<CXX_COMPILER_ID:…>, $<COMPILE_LANGUAGE:…>, and $<PLATFORM_ID:…> generator expressions support matching one value from a list
  • $<COMPILE_LANG_AND_ID:…> generator expression added
  • $FILTER:list,INCLUDE|EXCLUDE,regex generator expression added
  • $<REMOVE_DUPLICATES:list> generator expression added
  • New $<TARGET_FILE*> generator expressions added: $<TARGET_FILE_PREFIX:…>, $<TARGET_FILE_BASE_NAME:…>, $<TARGET_FILE_SUFFIX:…>, $<TARGET_LINKER_FILE_PREFIX:…>, $<TARGET_LINKER_FILE_BASE_NAME:…>, $<TARGET_LINKER_FILE_SUFFIX:…>, $<TARGET_PDB_FILE_BASE_NAME:…>
  • $<TARGET_OBJECTS:…> generator expression supports executables and static, shared, and module libraries

CMake 3.16 (released November 26th 2019):

  • Support for generator expressions in BUILD_RPATH and INSTALL_RPATH

CMake 3.17 (released March 20th 2020):

  • Ninja Multi-Config generator, which among other things would greatly simplify LLVM_OPTIMIZED_TABLEGEN
  • foreach(ZIP_LISTS) added to iterate multiple lists simultaneously
  • New message() keywords CHECK_START, CHECK_PASS, and CHECK_FAIL
  • INSTALL_NAME_DIR supports generator expressions

[1] Upgrading LLVM's minimum required CMake version - #10 by petrhosek

5 Likes

I’m in favor of this proposal.

Here is an example from the code base where we would benefit from a newer cmake.

1 Like

We also got bitten quite a few times recently by bugs in CMake 18 (that we worked around in cmakelists.txt) and I ended up upgrading my bots to CMake 23 instead to avoid dealing with these now (but we lost coverage).

CMake is trivial to install, and you can very quickly setup a cmake just for the purpose of building LLVM and keep the build directory hermetic, my script does this:

# Setup CMake because the system one is too old
wget https://github.com/Kitware/CMake/releases/download/v3.23.4/cmake-3.23.4-linux-x86_64.tar.gz
echo "3fbcbff85043d63a8a83c8bdf8bd5b1b2fd5768f922de7dc4443de7805a2670d  cmake-3.23.4-linux-x86_64.tar.gz" | sha256sum -c
tar -xf cmake-3.23.4-linux-x86_64.tar.gz
# Done, cmake is usable, nothing is installed on the system, everything is self-contained *inside* the build directory itself.
export PATH=$PWD/cmake-3.23.4-linux-x86_64/bin/:$PATH

I’d even suggest adding this to our “getting started” documentation.

Worth mentioning that some opposition in the past about upgrading cmake were about (if I remember correctly) that some system are not connected to the internet and where it would be difficult to get a binary deployed.

1 Like

+1 for CMake minimum version bump.

+1

+1

Upgrading cmake would be great.

I would like to hear @mgorny and @sylvestre opinions here before we accept since they need to make this work in their distribution builds.

Is there a Buildbot with CMake 3.13.4?
Will there be a Buildbot with CMake 3.20.0?

We’re fine with any CMake version, up to 3.24.2 at the moment (and we’re generally quite fast to push new versions to Gentoo stable).

By the way, I think you can get a more complete list of distro CMake package versions on Repology: cmake package versions - Repology

The quickstart guide already has some instructions where to download CMake Building LLVM with CMake — LLVM 18.0.0git documentation did you have another place in mind where to add that information?

Both are used according to Buildbot
I intend to update the libc++ Docker file which is used for Linux builds of libc++'s pre-commit CI.

Thanks I didn’t know this site.

No, but the instructions are just linking to the cmake download page, that’s a bit light for a newcomer instructions. Also it says “install cmake” which may not be strictly required.

+1 to upgrading and separating from LTS OS distributed CMake versions. It is trivial to install and for anyone with issues, it is much better time spent for us to distribute install scripts/instructions/etc vs spending time working around the many, many CMake issues in older versions.

Mehdi’s approach to installing works. In addition, if you have a functioning Python in your VM, the following works (you don’t need to actually use Python for anything else other than package delivery):

pip install cmake==3.24.1.1 ninja==1.10.2.4
# Note that depending on your shell environment, the symlinks in $HOME/.local/bin may not be on the path.
# If this is the case, pip will print a warning telling you this and you will need to do:
export PATH=$HOME/.local/bin:$PATH

I use this approach most of the time. When combined with a Python venv, it also is completely ephemeral:

python -m venv ~/.venv/llvm
source ~/.venv/llvm/bin/activate
pip install cmake==3.24.1.1 ninja==1.10.2.4

Also works the same on Windows.

2 Likes

+1

Another +1 to getting Ninja Multi-Config working across the board, that would be great.

I had great success using it when I mostly cared about only clang and clang-tools.

But since I started needing to test libcxx and lldb locally, I had to switch back as their build scripts are not prepared to deal with that yet.

1 Like

+1 I think this is reasonable, thanks a lot @mordante for gathering the information above!

@sylvestre do you have any opinion?

True, maybe it’s good to add a bit more information, especially with the pip install option @stellaraccident suggested. But I would like to do that separately.

Since there were no objections to the version bump I’ve created a review.
This issues a diagnostic when an older CMake version is used
https://reviews.llvm.org/D137724

It also added Unity and PCH builds fwiw.

How exactly?

I’ve just landed the change I’ll mail the buildbot owners with older CMake versions shortly.

I’ve posted ⚙ D144509 [CMake] Bumps minimum version to 3.20.0. to update the minimum CMake version.

1 Like

I noticed that the LLVM installation does not inherit the minimal cmake version requirement in the installed cmake files. For example, the installed LLVMExports.cmake only has these:

# Generated by CMake

if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
   message(FATAL_ERROR "CMake >= 2.8.0 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
   message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...3.24)
...
if(CMAKE_VERSION VERSION_LESS 2.8.12)
  message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.")
endif()

I am not sure how this works, but shouldn’t the installed cmake files require the same version that is required for the in-tree builds? For example, if out-of-tree tools rely on the latest installation of LLVM and include AddLLVM.cmake, then they may trigger cmake code in AddLLVM.cmake that only works with 3.20.0.