“make dist” equivalent in CMake

前端 未结 2 1261
时光取名叫无心
时光取名叫无心 2020-12-31 13:07

According to FAQ, CMake doesn\'t create a make dist target and source package can be created using CPack. But CPack just makes a tarball of the source directory

相关标签:
2条回答
  • 2020-12-31 13:22

    I've been thinking about this for a while and I won't pretend I can simulate a make dist without having this directly supported by CMake itself.

    The problem is that you can add a lot of file dependencies with CMake on the one side (e.g. to pre-build libraries) and on the other side CMake does not know about dependencies directly checked by the generated build environment itself (e.g. any header dependencies).

    So here is a code that just collects all CMakeList.txt and source files given with any build targets:

    function(make_dist_creator _variable _access _value _current_list_file _stack)
        if (_access STREQUAL "MODIFIED_ACCESS")
            # Check if we are finished (end of main CMakeLists.txt)
            if (NOT _current_list_file)
                get_property(_subdirs GLOBAL PROPERTY MAKE_DIST_DIRECTORIES)
                list(REMOVE_DUPLICATES _subdirs)
                foreach(_subdir IN LISTS _subdirs)
                    list(APPEND _make_dist_sources "${_subdir}/CMakeLists.txt")
                    get_property(_targets DIRECTORY "${_subdir}" PROPERTY BUILDSYSTEM_TARGETS)
                    foreach(_target IN LISTS _targets)
                        get_property(_sources TARGET "${_target}" PROPERTY SOURCES)
                        foreach(_source IN LISTS _sources)
                            list(APPEND _make_dist_sources "${_subdir}/${_source}")
                        endforeach()
                    endforeach()
                endforeach()
    
                add_custom_target(
                    dist
                    COMMAND "${CMAKE_COMMAND}" -E tar zcvf "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.tar.gz" -- ${_make_dist_sources}
                    COMMENT "Make distribution ${PROJECT_NAME}.tar.gz"
                    WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
                )
                message("_make_dist_sources = ${_make_dist_sources}")
            else()
                # else collect subdirectories in my source dir
                file(RELATIVE_PATH _dir_rel "${CMAKE_SOURCE_DIR}" "${_value}")
                if (NOT _dir_rel MATCHES "\.\.")
                    set_property(GLOBAL APPEND PROPERTY MAKE_DIST_DIRECTORIES "${_value}")
                endif()
            endif()
        endif()
    endfunction()
    
    variable_watch("CMAKE_CURRENT_LIST_DIR" make_dist_creator)
    

    Note: The used BUILDSYSTEM_TARGETS property needs at least CMake version 3.7

    I see the code above as an starting point and prove of concept. You could add libraries, headers, etc. on a need-by basis, but you should probably just tweak cpack to do your bidding.

    As a starting point see e.g. the link @usr1234567 provided in the comments.

    References

    • Get all source files a target depends on in CMake
    0 讨论(0)
  • 2020-12-31 13:42

    Simon is correct above but does not give a full answer. With git you can generate a compatible tar ball archive with the git archive command.

    This example with the version is compatible with make dist of yesteryear.

    git archive --format=tar.gz -o my-repo-0.01.tar.gz --prefix=my-repo-0.01/ master
    

    See: https://gist.github.com/simonw/a44af92b4b255981161eacc304417368

    0 讨论(0)
提交回复
热议问题