(I waffled over what section to post this in, before settling on this one. apologies if I got that wrong.)
If, like me, you’re involved in a project that requires build-system compatibility with a wide range of CMake versions (we currently support 3.2...3.17
), then — in addition to being intimately familiar with if(CMAKE_VERSION VERSION_LESS ...)
conditionals in all their various forms — by now you’ve probably done these steps over and over again, the same way I have:
- Need to implement something in a
CMakeLists.txt
or.cmake
file - Head off to https://cmake.org/cmake/help/latest/ for reference on the relevant features/syntax
- Find the information you need
- Use the version dropbox at the top of the page to switch back to {the oldest | an older} version’s documentation
- Cross your fingers that the nifty feature you just read about isn’t going to vanish the moment you switch
- If it does, start thinking how you can make do without it, using only the features in the older release
- Or, if you decide you can’t, start flipping through different versions of the page (bisecting the releases, in an ideal world — more likely just haphazardly guessing, in reality) until you find the release where the feature was introduced.
- Use it when you’ve got it, and write a partial workaround inside one of those
if(CMAKE_VERSION VERSION_LESS ...)
tests for when you haven’t.
“Start from the docs for the oldest version, as your reference” really isn’t a solution. (A) The CMake 3.2 docs are terrible, the formatting sucks and most of the pages are raw blocks of terse prose with nothing hyperlinked. (B) Just because you need to be compatible with older versions doesn’t mean you can’t make use of newer features, with version-gating.
One approach some other large-scale projects have taken, in addressing the problem of what I’ll call “API evolution”, is to mark up their documentation with ‘since’ annotations (along with other related forms of lifetime annotation). They won’t magically solve step 8, but they can make steps 2 through 7 a lot less tedious.
You can see ‘since’ annotations used in the Qt API docs, where I can quickly learn (for example) that QImage::bitPlaneCount() “was introduced in Qt 4.7”, but I should be careful trying to use QImage::applyColorTransform() because just recently it “was introduced in Qt 5.14”.
An even better example of well-employed lifetime annotations can be found throughout the CppReference documentation. (Thanks in no small part to the fact that there are really only 5 major standards levels they need to be concerned with, and those span well over a decade of time.)
Making full use of that luxury, at cppreference small green annotations accompany any classes or concepts introduced in later standards releases, making it clear at a glance when “(C++11)” or “(C++20)” is required to use those APIs.
And where APIs have evolved over time, as in the case of std::map
for example, annotations clearly indicate which parts of that reference are applicable “(since C++11)” or “(until C++17)”, and which APIs have been “(removed in C++20)”.
I’m not suggesting that CMake adopt the cppreference model — I think that would be overkill. It’s merely an example. Qt’s is, IMHO, a far better fit. The primary concern in terms of backwards-compatibility, which the Qt documentation addresses, is the need to know which documented features are more recently introduced, and when they were first made available.
So my question/proposal here (finally!), primarily for the CMake maintainers/developers (i.e. Kitware), is:
Would the devs be receptive to patches that added support for “since” annotations in the CMake documentation, and would they be willing to use them going forward, when documenting newly-added features?
I’m not asking that anyone retroactively mark up CMake’s entire evolution from the beginning, or even just from version 3.0. Even with support for “since” annotations, for features introduced through CMake 3.17 I don’t expect they’ll be put to much use.
(If someone wanted to volunteer to annotate the docs for a command like string()
or file()
that’s seen changes in nearly every release, and they submitted an MR for that work, then great — but it’s not any sort of expectation. I also don’t see a problem if annotations aren’t consistent throughout the docs, for features introduced in earlier releases. Others may disagree, I suppose.)
All I’m proposing is that, starting from CMake 3.18, when new features are documented they get marked as being available “since 3.18” — right on the actual reference pages for those features, not just as line-item blurbs in the CMake 3.18 Release Notes.
And if the only barrier is lack of support for lifetime annotations in the CMake documentation, I’m volunteering to work on contributing that support.