【问题标题】:"make dist" equivalent in CMakeCMake 中的“make dist”等价物
【发布时间】:2012-03-26 09:34:33
【问题描述】:

根据FAQ,CMake 不会创建make dist 目标,可以使用CPack 创建源包。但是 CPack 只是将所有与CPACK_SOURCE_IGNORE_FILES 中的模式不匹配的文件制作成源目录的 tarball。

另一方面,由 autotools 生成的make dist 只捆绑它知道的文件,主要是编译所需的源。

任何人都有一种巧妙的方法来制作仅包含 CMakeLists.txt(及其依赖项)中指定的文件的源包?

【问题讨论】:

  • 不是答案,但您可以使用您的 VCS 来执行此操作,例如 git archive 如果您使用的是 git。
  • 有一篇 2009 年的博文,但还是有点笨拙:agateau.com/2009/cmake-and-make-dist
  • 不是答案,而是暗示您并不孤单:在某些项目中,我们维护并手动和自动生成名为 artefacts.txt 的文本文件,然后我们用它来创建分发(在单独的构建目标)。文本文件包含源(在srcbuild 文件夹中)目标和一些隐式规则(例如py => pyc)
  • 可能明确地install(FILES ... DESTINATION ..) 是要走的路。也许可以生成列表,但我宁愿手动维护它。我结了,这不是聪明的办法。

标签: cmake packaging cpack


【解决方案1】:

我一直在考虑这个问题,我不会假装我可以模拟 make dist 而无需 CMake 本身直接支持。

问题是您可以在一方面使用 CMake 添加大量文件依赖项(例如到预构建库),另一方面 CMake 不知道生成的构建环境本身直接检查的依赖项(例如任何标头依赖项)。

所以这里的代码只收集了所有CMakeList.txt 和任何构建目标给出的源文件:

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)

注意:使用的BUILDSYSTEM_TARGETS属性至少需要CMake 3.7版

我将上面的代码视为起点和概念证明。您可以根据需要添加库、标头等,但您可能只需要调整 来进行投标。

作为起点,请参阅例如the link@usr1234567 在 cmets 中提供。

参考文献

【讨论】:

    【解决方案2】:

    西蒙在上面是正确的,但没有给出完整的答案。使用 git,您可以使用 git archive 命令生成兼容的 tar 球存档。

    此示例与旧版本的make dist 兼容。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-31
      • 2010-10-20
      • 1970-01-01
      • 2019-11-03
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      相关资源
      最近更新 更多