28

I want to define a minimum version to CMake with "cmake_minimum_required" facility. I have seen that some project set minimum version 2.8 some others set 3.0 or 3.2. What's a useful way to decide what to put in my project's call to cmake_minimum_required(VERSION ...)?

starball
  • 20,030
  • 7
  • 43
  • 238
mustafagonul
  • 1,139
  • 1
  • 15
  • 32
  • `Opinions and best practices` often have to do with the answer to the `why?` question. – Shark Feb 22 '16 at 09:38
  • Well choose the maximum (last) version when you can ? – coincoin Feb 22 '16 at 09:38
  • 1
    Not last, but the one you need; last version (or bleeding edge nightly builds) might not be the thing you need. But first you need to identify the reasoning behind such restrictions, and pick the one that satisfies most of your needs - which very well **may not be** the last version. – Shark Feb 22 '16 at 09:39
  • If I would start a new project I would take 3.3 as a minimum. The 3.x versions did introduce a lot of very useful commands (e.g. the `target_...` commands or `if(... IN_LIST ...)`) and it has better consistency checks (configurable through `policies`). And I came across a few bugs (e.g. in conjunction with `ninja`) that were relevant for my environment and were fixed in 3.3. – Florian Feb 22 '16 at 09:59
  • 1
    I was discussing with my colleague. I am on using the minimum version satisfying our requirements side, and he is on using the last version side like Shark. We haven't come to a decision yet :) – mustafagonul Feb 22 '16 at 11:49
  • 2
    @mustafagonul: If you *know* the minimum version satisfying your requirements, and it's a couple of releases back, picking the latest & greatest instead is basically being intentionally annoying. At the time of this writing, cmake.org has 3.4.3. Debian stable has 3.0.2, Ubuntu wily has 3.2.2, and even Gentoo stable has "only" 3.3.1. So, in order to compile your software, basically *everybody* would have to *manually* download & install a newer CMake first (which would then begin to deteriorate since it would **not** be updated via the package manager). I wouldn't like that as a customer. – DevSolar Feb 22 '16 at 12:04
  • Thanks being on my side DevSolar :) – mustafagonul Feb 22 '16 at 12:19
  • In my previous projects, using cmake 2.8 was enough for us. In our current project using 2.8 will also be enough according to my opinion. But there is another concern, cmake version, installed on the build servers, we have no rights to install an update on unfortunately :( We should find an optimal point for our project – mustafagonul Feb 22 '16 at 12:34
  • 1
    @mustafagonul: Apparently your colleague doesn't think it's a problem to set a "minimum required version" that's not supported on your build servers; ask him for his solution. :-D That being said, you *can* compile & install software locally, i.e. your home directory, and use it there. (`--prefix=/home/myuser/local_software` or similar.) – DevSolar Feb 22 '16 at 14:18
  • Thanks for the tip. That was very useful. +1 – mustafagonul Feb 25 '16 at 12:10

2 Answers2

33

The cmake_minimum_required() function is used to avoid any cryptic error messages due to the CMakeLists.txt assuming a later version of CMake than the one installed on the current host.

As an example, failing early, and with a clear message...

CMake 3.2 or higher is required. You are running version 2.8.12.2

...is to be preferred over something more cryptic (much) later on...

In file included from /home/foouser/src/testprj/string.cpp:1:0:
/home/foouser/src/testprj/string.hpp:94:29: error: ‘std::is_same’ has not been declared

...just because, in this example, the older CMake version does not support set( CMAKE_CXX_STANDARD 11 ). I am sure you'll agree.


The ideal setting would be:

  1. The oldest version with all the features your script needs.

Maximal compatibility with people running older versions, as well as with your script. But it requires testing which version exactly it was that first supported your constructs. So it usually boils down to:

  1. The oldest version you have tested that has all the features your script needs.

That's probably good enough for most projects. And if you are the only one actually working on the project, and testing for CMake compatibility is really low on your list, you will probably end up with:

  1. The version you are currently using.

This latter approach has a serious drawback once somebody else attempts to compile your project. Quite a few people are not using the latest version of everything. On Linux in particular, the default is to use whatever the package manager gives you. Ubuntu wily, for example, is currently at version 3.2.2 -- you may have a later version, but unless you need a later version, you shouldn't require it (as that means people won't be able to build your project without first installing a newer version of CMake, manually).

What you should not be doing is...

  • Requiring a very old version, but not actually testing against that old version (NO!).

The reasons should be obvious -- building could fail, without the user getting any hint as to why things went wrong.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 3
    Keeping a comment in CMakeLists.txt to track why exactly it was *this* version of CMake you required helps with later maintenance. – DevSolar Jun 01 '20 at 08:26
  • 1
    I'm kicking myself for not writing a comment as DevSolar suggests. I'm staring at my `cmake_minimum_required` line right now and can't remember why I chose its current version value. – Emile Cormier Dec 04 '20 at 04:08
  • @EmileCormier: If you remember that you *did* choose that number for {reason}, install [an older version of CMake](https://cmake.org/files/) and check what breaks. ;-) Or shrug it off as "it's not *that* important as long as it works". ;-) – DevSolar Dec 04 '20 at 08:37
  • 1
    The ~~perfectionist~~ obsessionist in me will want to do a binary search to find the actual minimal version that works. :-D – Emile Cormier Dec 05 '20 at 18:12
0

For the most part, the effect of what you put there is in what newer features you can use, policies, and the constraint is what you think is appropriate to require the people who are going to work with your project's CMake config to install.

It's a bit of a tradeoff. Sometimes there will be features that you will have good reason to really want from newer CMake versions (that similar desirable behaviour would be much more difficult or impossible to achieve in older versions), such as support for newer programming languages / language versions, and in those cases you should probably at least specify that as a minimum version.

Otherwise, ask yourself what platforms you want to support people being able to use your CMake project on, and then find out what various ways they can get CMake on those platforms, and which ways you want to support. For example, any platform will probably support building the latest CMake from source, but that's not... the most user-friendly experience. You can look at system package managers and what latest version is published on those, and other installation methods. An pretty okay list of installation methods can be found on the official downloads page. The "Alternative Binary Releases" section points to https://apt.kitware.com/, https://snapcraft.io/cmake, and https://pypi.org/project/cmake/. The "Older Releases" section points to https://cmake.org/files and https://github.com/Kitware/CMake/releases. There's also Chocolatey on Windows.

Note that if you have any concerns about accidentally using newer features unsupported by the minimum version your project is written claiming to support, I would say that as a project maintainer, it's (ideally) your job to make sure that you don't do that, or at least to fix it when someone finds out that you're breaking the version support "promise".


Others take an approach of deciding their minimum supported version based on what features they want to use in your CMake project config. That's... fine I guess. It's a maintainer-favouring approach and a possibly-not-very-user-favouring approach.

For example, https://github.com/nlohmann/cmake_min_version. If I understand this correctly from the readme, it just finds out what minimum version the project config supports. That's... backwards in my view. The readme itself says that the constraints are platform-support-based. I do not see this as a good approach or a solution to that problem. If the problem is platform support, the project config should be written to support the platform(s)-based version constraint- not the other way around. It can, however, possibly be a useful tool to check that you're actually satisfying your version constraint.


If you want some extra readings on the subject, I also recommend the following:

starball
  • 20,030
  • 7
  • 43
  • 238