Finding which CMake version a feature was introduced in

后端 未结 2 529
情歌与酒
情歌与酒 2020-12-10 06:30

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_requi

相关标签:
2条回答
  • 2020-12-10 06:47

    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.

    0 讨论(0)
  • 2020-12-10 06:52

    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
    0 讨论(0)
提交回复
热议问题