Proposal/RFC: "Since" annotations in CMake documentation

(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:

  1. Need to implement something in a CMakeLists.txt or .cmake file
  2. Head off to https://cmake.org/cmake/help/latest/ for reference on the relevant features/syntax
  3. Find the information you need
  4. Use the version dropbox at the top of the page to switch back to {the oldest | an older} version’s documentation
  5. Cross your fingers that the nifty feature you just read about isn’t going to vanish the moment you switch
  6. If it does, start thinking how you can make do without it, using only the features in the older release
  7. 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.
  8. 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.

3 Likes

https://gitlab.kitware.com/cmake/cmake/issues/19715

1 Like

Thanks, I figured this had probably come up in the past, though it doesn’t look like it’s ever gotten as far as anyone actually submitting any code. (Nor has it gotten that far this time, of course.)

But I gather from that bug report that you’re not particularly keen on the idea?

In terms of your points (and Kyle’s points) regarding making its use mandatory — IMHO it doesn’t need to be mandatory for all contributions any more than documentation period is mandatory for contributions. (It isn’t, is it? I certainly never got that impression, and there’s no mention whatsoever in CONTRIBUTING. Adding the ability/need to annotate the documentation can’t really add any barriers to contributing, insofar as there’s no documentation requirement in the first place.)

I think it would be sufficient to make the use of lifetime annotations “mandatory” (even “strongly encouraged” would be fine, in my mind) only when additions to the documentation are submitted. It doesn’t strike me as that onerous to ask that submitters of new docs try to indicate when the new/updated features they’re documenting was introduced. (With the assumption being that will usually mean “in the latest release”.)

But, as I said (and as the OP also proposed) I don’t personally see it as a problem if this isn’t done consistently and rigorously, on the theory that something is better than nothing. Plus, as I said it’s not unlikely that motivated users could submit MRs to backfill data for older releases, once the basic support is there. (Kyle also mentioned something along those same lines, in that previous discussion.)

If it’s unacceptable that the docs may indefinitely linger in a state of “partially annotated” or “annotated only since this release”, then I guess that’d make this a tough sell.

As someone who very often needs to work out when a particular feature was added to CMake, I have much sympathy with this (and all the similar earlier) requests. It would be a non-trivial undertaking to update the existing docs with the CMake version that added each thing, but I suspect that it could be done (collaboratively with some willing contributors). Certainly it would be helpful for end users to have such information right there in the docs, especially given that there are typically about 3 feature releases a year, so the rate of updates can be a challenge to keep on top of.

If we did go down this path of adding “available since” details to the docs, it would only be worthwhile if we then rigorously enforced that all new contributions that added a new feature would need to specifically state in its accompanying documentation the version in which it was added. That would be something the maintainers could ensure as part of the usual review process, so I have less concerns about that aspect. I don’t think contributors would find it onerous, rather I suspect it would be more a case of reviewers would probably need to frequently ask for such details to be added. As someone who monitors and reviews documentation contributions fairly closely, I’m okay with that personally, but I do suspect it would get a bit tedious/tiresome in time.

The main danger I see is if the “available since” details are not maintained to be in a rigorously complete state, then end users can’t trust them. In particular, if something has no mention of an “available since” version, then does that mean it has always been part of CMake or that it just hasn’t been documented? We would ideally want to back-fill all the existing docs in the one feature release to minimise such cases. There will always be some that slip through the cracks, but I’m sure over time they can be weeded out just like regular code bugs and doc improvements.

I recently had analogous experiences with the Qt documentation. Updating a project to a more recent Qt version, I found I was very reliant on the “available since” details in the docs to understand what minimum Qt version my work was bringing to the project. I’ve had the same experiences working with CMake projects in the past.

Not sure if any of that helps, but as someone fairly heavily involved in CMake’s documentation, I wanted to be clear where I stood on this topic.

2 Likes