2

我使用 CMake 管理具有以下布局的项目:

ProjectA/
  include
  doc
  test
ProjectB
  include
  doc
  test

我想使用 CPack 来打包具有以下布局的tar.gz 源存档:

include/
ProjectA/
  doc
  test
ProjectB/
  doc
  test

其中新的顶级包含包含所有包含文件。

我尝试通过运行 CMake 脚本来实现这一点CPACK_INSTALL_SCRIPT,但该脚本在创建文件之前运行。我在哪里可以连接到 CPack 以获得这种效果?

它似乎也install对做什么没有影响make package_source,但它对make package. 不幸的是make package,还将构建和打包库,这是我不希望发生的事情。我想要一个纯源代码分发 ala make dist

4

3 回答 3

4

install(DIRECTORY include DESTINATION include)您可以从两者中调用标头ProjectA并将ProjectB它们安装到同一个目录中。这将导致 CPack 将它们一起放在生成的包中。

更新

好的,我已经设法用CPACK_INSTALL_SCRIPT变量做到了这一点。

我创建了以下脚本:

set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)

execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/A/ ${CMAKE_SOURCE_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/B/ ${CMAKE_SOURCE_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/A)
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/B)

CMakeLists.txt我用实际值填充它CMAKE_SOURCE_DIR

configure_file(CPackScript.cmake CPackScript.cmake @ONLY)

最后,我添加了set(CPACK_INSTALL_SCRIPT ${CMAKE_BINARY_DIR}/CPackScript.cmake),瞧!生成的包现在有includedir,其中包含A/和的标头B/,而A/和dirB/不存在。

于 2012-12-22T19:15:00.390 回答
3

另一种可能的方法是完全绕过 CPack 来生成 TGZ 存档,并简单地使用生成存档的 CMake 自定义目标:

project (MyProject)

set (DIST_TEMP_DIR "${CMAKE_BINARY_DIR}/dist")
make_directory(${DIST_TEMP_DIR})

add_custom_target(dist 
    COMMAND ${CMAKE_COMMAND} -E remove_directory "${DIST_TEMP_DIR}/${PROJECT_NAME}/"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/ProjectA/include" "${DIST_TEMP_DIR}/${PROJECT_NAME}/include"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/ProjectA/test" "${DIST_TEMP_DIR}/${PROJECT_NAME}/ProjectA/test"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/ProjectA/doc" "${DIST_TEMP_DIR}/${PROJECT_NAME}/ProjectB/doc"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/ProjectB/include" "${DIST_TEMP_DIR}/${PROJECT_NAME}/include"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/ProjectB/doc" "${DIST_TEMP_DIR}/${PROJECT_NAME}/ProjectA/doc"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/ProjectB/test" "${DIST_TEMP_DIR}/${PROJECT_NAME}/ProjectB/test"
    COMMAND ${CMAKE_COMMAND} -E tar cvz "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.tar.gz"  "${DIST_TEMP_DIR}/${PROJECT_NAME}/"
    COMMENT "Building ${PROJECT_NAME}.tar.gz"
    WORKING_DIRECTORY "${DIST_TEMP_DIR}"
)

自定义目标dist首先通过在命令模式下使用多个命令调用 CMake,在构建文件夹内的临时目录中设置所需的存档结构copy_directory。然后它tar.gz使用tar命令模式子命令生成存档。

于 2012-12-28T14:11:56.827 回答
2

我不确定什么对你不起作用。

这对我来说适用于 Windows 上的 ZIP 生成器。我将尝试找到一台 linux 机器,看看这是否也适用于 TGZ(编辑:确实如此):

目录结构:

CMakeLists.txt
ProjectA/
    doc
        foo.txt
    include
        foo.h
    test
        foo.test
ProjectB/
    doc
        bar.txt
    include
        bar.h
    test
        bar.test

项目A/CMakeLists.txt

project( ProjectA )

INSTALL( DIRECTORY include DESTINATION . )
INSTALL( DIRECTORY doc DESTINATION ${PROJECT_NAME}/ )
INSTALL( DIRECTORY test DESTINATION ${PROJECT_NAME}/ )

项目B/CMakeLists.txt

project( ProjectB )

INSTALL( DIRECTORY include DESTINATION . )
INSTALL( DIRECTORY doc DESTINATION ${PROJECT_NAME}/ )
INSTALL( DIRECTORY test DESTINATION ${PROJECT_NAME}/ )

CMakeLists.txt:

project( MyProject )

ADD_SUBDIRECTORY(ProjectA)
ADD_SUBDIRECTORY(ProjectB)

INCLUDE(CPack)

如果我创建包,我会得到

MyProject-0.1.1-win32.zip
    MyProject-0.1.1-win32
        include
            bar.h
            foo.h
        ProjectA
            doc
                foo.txt
            test
                foo.test
        ProjectB
            doc
                bar.txt
            test
                bar.test

那是你的意图吗?

源包

对于源包创建,默认情况下 CPack 会忽略安装命令并安装/复制所有在CPACK_SOURCE_INSTALLED_DIRECTORIES. 此变量包含成对的源目录和目标目录。"${CMAKE_SOURCE_DIR};/"如果不手动设置,则默认为。准确地说,它会覆盖这些目录,忽略CPACK_SOURCE_IGNORE_FILES默认为所有主要 VCS 簿记文件的所有文件(参见您CPackSourceConfig.cmake的示例)。

可以执行以下操作:

CMakeLists.txt

project( MyProject )

SET( PROJECTS ProjectA ProjectB )

SET(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};/") 
FOREACH( p ${PROJECTS} ) 
    ADD_SUBDIRECTORY( ${p} )
    LIST( APPEND CPACK_SOURCE_INSTALLED_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR/${p}/include include )
ENDFOREACH()


INCLUDE(CPack)

或将操作添加CPACK_SOURCE_INSTALLED_DIRECTORIES到相应的项目文件中。

但是:这会将您的包含目录安装到顶级包含目录,但由于通配,仍会在项目目录中创建另一个副本。您可能可以为您的doctest目录创建额外的目录对,并跳过命令CPACK_SOURCE_INSTALLED_DIRECTORIES中的初始化SET。如果这样做,您将需要找到一种方法来安装/复制特定于项目的 CMake 文件。

大警告:如果ProjectAProjectB引用项目本地包含目录(例如,INCLUDE_DIRECTORIES(...)您将破坏您的 CMake 代码,使源安装(部分)无用。因此您可能需要重新考虑您对顶级包含目录的想法。

于 2012-12-27T10:06:58.777 回答