创建TGZ存档时更改布局

时间:2012-12-20 15:25:00

标签: cmake build-system cpack

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

ProjectA/
  include
  doc
  test
ProjectB
  include
  doc
  test

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

include/
ProjectA/
  doc
  test
ProjectB/
  doc
  test

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

我尝试通过CPACK_INSTALL_SCRIPT运行CMake脚本来实现此目的,但此脚本在创建文件之前运行。我在哪里可以挂钩到CPack来获得这种效果?

似乎installmake package_source的作用没有影响,但它对make package有影响。不幸的是,make package也将构建和打包 库,这是我不想发生的事情。我想要一个纯粹的 来源分布ala make dist

3 个答案:

答案 0 :(得分: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)并瞧!生成的包现在有include dir,其中包含来自A/B/的标头,而A/B/ dirs不存在。

答案 1 :(得分: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首先通过在命令模式下使用多个copy_directory命令调用CMake,在构建文件夹内的临时目录中设置所需的存档结构。然后,它使用tar.gz命令模式子命令生成tar存档。

答案 2 :(得分: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的操作添加到相应的项目文件中。

然而:这会将您的include目录安装到顶级include目录,但由于globbing,还会在项目目录中创建另一个副本。您可以为doctest目录创建其他目录对,并跳过CPACK_SOURCE_INSTALLED_DIRECTORIES命令中SET的初始化。如果这样做,您将需要找到一种方法来安装/复制项目特定的CMake文件。

BIG CAVEAT :如果ProjectAProjectB引用项目本地包含目录(例如INCLUDE_DIRECTORIES(...),则会破坏您的CMake代码,呈现源安装(部分)无用。所以你可能想重新考虑你对顶级包含目录的看法。