1

Prepare the following (erroneous) CMakeLists.txt file:

cmake_minimum_required(VERSION 3.10)
project(foo)
add_executable(foo foo.cpp)
add_compile_definitions(BAR=123)

add_compile_definitions is new in CMake 3.12, so processing the above file in CMake 3.10 will result in an error.

CMake Error at CMakeLists.txt:4 (add_compile_definitions):
  Unknown CMake command "add_compile_definitions".

However, using CMake 3.12 or later, no errors or warnings are output. Therefore, as long as you are using CMake 3.12 or later, you will not notice the error.

(In this case, we can use add_compile_options instead of add_compile_definitions, but that is not the main issue.)

You may say, "you shouldn't write cmake_minimum_required(VERSION 3.10) because you are not using CMake 3.10, you should write the version you are actually using". However, there may be cases where modifications are made to an existing code base.

Is there any way to realize that when you do so, you inadvertently write something that is not usable in the specified version? For example, is there a tool like lint that can check for features that are not available in a given version?

Currently, is the only way to do this is to install the specified version of CMake?

kakkoko
  • 179
  • 10
  • 1
    Not an answer, but you may find [Alex Reinking's advice on picking a CMake version](https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html) useful "_If you're writing an open source project, \[...\] you might assume that you want to use a very old CMake version to build your project. This is nonsense. Recent versions of CMake are available absolutely everywhere. Your build's users are technical: C++ developers, not laypeople. They can upgrade CMake \[...\]. For every major platform, there are easy ways to get a recent CMake version installed\[...\]._" – starball Sep 14 '22 at 06:09
  • @davidfong Which is not true. Building packages for distributions, I regularly face the problem that I can only use the CMake version that are provided by the LTS release. Further, not every potential user that can compile software is willing to compile tons of dependencies. – usr1234567 Sep 14 '22 at 06:13
  • @usr1234567 CMake could be built using a compiler and minimum most common system libraries. It has most of the dependencies included in the distributed tarball. E.g., I can easily build it even for CentOS 6. – zaufi Sep 14 '22 at 07:37
  • The common recommendation -- use the latest version as u can. I have around 100 projects targeted for dozen of platforms. And everywhere (including dead CentOS 6) it's quite possible (and relatively easy) to have the latest CMake (3.24 nowadays). BTW, for the Debina/Ubuntu, they provide `*.deb` packages AFAIR. – zaufi Sep 14 '22 at 07:43
  • @usr1234567 - That's bogus. The recent LTS distros _all_ include relatively recent versions of CMake (even CentOS has 3.20!) and one can always produce binary packages for any distro in a third-party repository (deb or rpm) using whatever build-time dependencies they want. Backporting software is always difficult, but forcing developers to suffer old CMake versions is the wrong side of the scale to put your thumb down on. – Alex Reinking Sep 14 '22 at 14:11
  • 1
    possibly related: [Q: "Finding which CMake version a feature was released in"](https://stackoverflow.com/q/40844358/11107541). – starball Sep 15 '22 at 03:04

2 Answers2

1

You have to test with the minimum required version. But even if no error occurs, your test might be incomplete, because you only test these parts of the code, that you are actually running. If your setup does not provide an optional dependency or you did not set a flag, the code executed for this dependency or flag will not be tested.

Depending on your setup, it makes sense to have a continuous testing (GitLab, Jenkins, GitHub actions) that runs your CMake code with CMake in the minimum required version. Then you get early warning that someone added code that is above the required CMake version and you should revert it or increase the requirements.

It is really not a satisfying answer and in general not a satisfying situation.

usr1234567
  • 21,601
  • 16
  • 108
  • 128
  • 1
    Thank you for your answer! Totally agree with you. Indeed, we will not know if it actually works correctly until we run it, so we will need some kind of coverage test. Nevertheless, I wish cmake had the ability to verify the version specified with the features used. – kakkoko Sep 14 '22 at 06:32
0

usr1234567 wrote a good answer, but let me add an additional point:

I think you (and many others; you're in good company) are misunderstanding the guarantee made by cmake_minimum_required(VERSION X). Many people believe it means the following:

This project will build with version X.

That is not the case at all. What it actually promises is:

If this project builds with version X, then it will build on versions Y > X.

That is to say, it is a backwards compatibility guarantee, not a forwards compatibility guarantee. You cannot author a project with a newer version of CMake and expect it to work with older versions without testing it.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86