I would like to target a specific version of CMake that is older than the version I am using myself (related to this question, i.e. correctly using cmake_minimum_required()
), and it would be nice to be able to determine which features to stay away from, for instance.
Is it possible to find the first version that a certain feature (variable, function, property, ...) was introduced in CMake?
As far as I can tell, the CMake documentation does not directly include this information (except for indirectly via the release notes). A great example of how this could work is the Qt API documentation (e.g. see the documentation for QCryptographicHash).
EDIT: I created a git repo with a modified version of the solution provided by Florian: https://github.com/mbitsnbites/cmake-minver
After reading the comments here is my CMake
version of a command/property/etc. checker:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.5)
function(version_required_by)
set(_keywords ${ARGN})
set(_temp_file "${CMAKE_CURRENT_BINARY_DIR}/download.txt")
foreach(_ver IN ITEMS 2.6 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.8.10 2.8.11 2.8.12 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7)
message(STATUS "Check version required: ${_ver}")
if (_ver VERSION_LESS 2.8)
set(_url "https://cmake.org/cmake/help/cmake${_ver}docs.html")
elseif (_ver VERSION_LESS 3.0)
set(_url "https://cmake.org/cmake/help/v${_ver}/cmake.html")
else()
set(_url "https://cmake.org/cmake/help/latest/release/${_ver}.html")
endif()
file(DOWNLOAD "${_url}" "${_temp_file}")
file(READ "${_temp_file}" _help_text)
foreach(_keyword IN LISTS _keywords)
string(FIND "${_help_text}" "${_keyword}" _found)
if (NOT _found EQUAL -1)
message(STATUS "${_keyword} -> v${_ver}")
list(REMOVE_ITEM _keywords "${_keyword}")
endif()
endforeach()
if (NOT _keywords)
message("cmake_minimum_required(VERSION ${_ver} FATAL_ERROR)")
if (NOT CMAKE_MINIMUM_REQUIRED_VERSION)
cmake_minimum_required(VERSION ${_ver} FATAL_ERROR)
endif()
break()
endif()
endforeach()
if (_keywords)
message(FATAL_ERROR "Check version required error: Not found ${_keywords}")
endif()
endfunction()
if (CMAKE_SCRIPT_MODE_FILE)
foreach(_i RANGE 3 ${CMAKE_ARGC})
list(APPEND _args "${CMAKE_ARGV${_i}}")
endforeach()
else()
list(
APPEND _args
"string(FIND"
"target_include_directories"
"BUILDSYSTEM_TARGETS"
)
endif()
version_required_by(${_args})
Would give for those examples I used for testing it:
-- Check version required: 2.6
...
-- Check version required: 2.8.5
-- string(FIND -> v2.8.5
...
-- Check version required: 2.8.11
-- target_include_directories -> v2.8.11
...
-- Check version required: 3.7
-- BUILDSYSTEM_TARGETS -> v3.7
cmake_minimum_required(VERSION 3.7 FATAL_ERROR)
Edit: Or if you e.g. run the above in script mode:
> cmake -P CMakeLists.txt target_include_directories
-- Check version required: 2.6
...
-- Check version required: 2.8.11
-- target_include_directories -> v2.8.11
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
Reference
- Find the latest script/command line version at https://github.com/mbitsnbites/cmake-minver
I made a firefox plugin, named CSince
, available in https://addons.mozilla.org/firefox/addon/csince/.
When viewing a page of CMake documentation, it checks since which version the corresponding feature exists, and adds the information to the html contents.
A first checking is performed for versions starting with v3.0: the url pattern is checked for prior versions until a 404 error is returned by the server. For example, considering url for property BINARY_DIR
:
https://cmake.org/cmake/help/latest/prop_dir/BINARY_DIR.html
Here urls are tested replacing latest
with a version string:
https://cmake.org/cmake/help/v3.0/prop_dir/BINARY_DIR.html
https://cmake.org/cmake/help/v3.1/prop_dir/BINARY_DIR.html
https://cmake.org/cmake/help/v3.2/prop_dir/BINARY_DIR.html
...
Versions are tested using a dichotomic approach, to limit requests.
If the first checking process returns v3.0, a second pass is performed for older versions using a less reliable test: the single-page documentation is requested, and the feature string is searched in the text.
This two-passes system allows for example to find the right version for the property BINARY_DIR
: the string BINARY_DIR
obviously exists in CMake documentation v2.6, while it exists as a property only since CMake v3.7.
Any bug report or improvement request are welcome. Code source is available on GitHub under license MIT/X11: https://github.com/wasthishelpful/csince.