list(SORT): Add support for SEMVER comparison

Hello, CMake Team.

I hope that list(SORT) command can add support for SEMVER comparison.

Up to version v3.30, the list(SORT) command can use the following three comparison methods for sorting:

  1. STRING: Sorts a list of strings alphabetically.
  2. FILE_BASENAME: Sorts a list of pathnames of files by their basenames.
  3. NATURAL: Sorts a list of strings using natural order (see strverscmp(3) manual).

Although the NATURAL option seems to be able to sort a list of version numbers, I found that it encounters problems when handling the order of release between pre-release. Let’s take CMake’s own version numbering as an example:

  1. Before the releases of the new version v3.29, v3.29.0-rc[n] tags should be released first.
  2. After the release candidates are finished, v3.29.x tags will be released next.

That means, v3.29.0 should be sorted after v3.29.0-rc[n].

However, after executing the following test code:

set(TAG_LIST
    v3.29.6
    v3.29.5
    v3.29.4
    v3.29.3
    v3.29.2
    v3.29.1
    v3.29.0
    v3.29.0-rc4
    v3.29.0-rc3
    v3.29.0-rc2
    v3.29.0-rc1
)
set(BEFORE_TAG_LIST "${TAG_LIST}")
set(AFTER_TAG_LIST  "${TAG_LIST}")
list(SORT AFTER_TAG_LIST COMPARE NATURAL ORDER DESCENDING)
message(STATUS "BEFORE_TAG_LIST = ${BEFORE_TAG_LIST}")
message(STATUS "AFTER_TAG_LIST  = ${AFTER_TAG_LIST}")
if("${BEFORE_TAG_LIST}" STREQUAL "${AFTER_TAG_LIST}")
    message(STATUS "BEFORE and AFTER are the same.")
else()
    message(STATUS "BEFORE and AFTER are not the same.")
endif()

We can see that COMPARE NATURAL sorts v3.29.0 before v3.29.0-rc[n]:

-- BEFORE_TAG_LIST = v3.29.6;v3.29.5;v3.29.4;v3.29.3;v3.29.2;v3.29.1;v3.29.0;v3.29.0-rc4;v3.29.0-rc3;v3.29.0-rc2;v3.29.0-rc1
-- AFTER_TAG_LIST  = v3.29.6;v3.29.5;v3.29.4;v3.29.3;v3.29.2;v3.29.1;v3.29.0-rc4;v3.29.0-rc3;v3.29.0-rc2;v3.29.0-rc1;v3.29.0
-- BEFORE and AFTER are not the same.

If possible, I hope CMake can provide a new comparison method for the list(SORT) command that can sort based on Semantic Versioning:

list(SORT TAG_LIST COMPARE SEMVER)

Of course, it would be best if this SEMVER comparison method could support other types of semantic versioning formats as much as possible, not just CMake.

Should I open an issue as a feature request for this topic?

I’ve seen discussion of version number support in the past, there may already be an open issue you can comment on further. Please search the issue tracker for existing issues before creating a new one for this topic.