【问题标题】:CMake ExternalProject_add with CMakeLists on subfolderCMake ExternalProject_add 与子文件夹上的 CMakeLists
【发布时间】:2016-10-21 19:38:30
【问题描述】:

我正在尝试从 cmake 下载并使用 ExternalProject_Add 命令构建 DevIL,但由于某种原因,git repo 在项目的子文件夹中包含 CMakeLists.txt 文件。

我似乎找不到让 ExternalProject_add 在正确文件夹上调用 cmake 的方法。 我尝试使用前缀和 source_dir,但仍然失败。

然后,我在网上看到了一个答案,其中涉及创建一个临时 CMakeLists.txt,它将调用正确的 cmake 路径。但由于我不知道如何提供 cmake 调用的路径,这意味着我必须将它放在下载的 git repo 中,后来证明这很痛苦...... 这是我正在使用的当前命令: 包括(“外部项目”)

######### Search for required third-party libraries. If not found, attempt to download and build them ########

set ( DEVIL_ROOT "${THIRD_PARTY_OUTPUT_PATH}/DevIL" )
option ( BUILD_DEVIL "Download and build DevIL" FALSE )

find_package ( Devil )
if ( NOT DEVIL_FOUND )
    message ( STATUS "DevIL not found. Forcing to build own copy...")
    set ( BUILD_DEVIL TRUE )
endif()

if ( BUILD_DEVIL )
set ( DEVIL_BUILD_PATH "${THIRD_PARTY_BUILD_PATH}/DevIL/" )
set ( DEVIL_OUTPUT_PATH "${THIRD_PARTY_OUTPUT_PATH}/DevIL" )

message ( STATUS "Downloading DevIL and building...")
file( WRITE ${DEVIL_BUILD_PATH}/DevilCMakeLists.txt "cmake_minimum_required( VERSION 3.0 ) \n  add_subdirectory ( DevIL )" )
ExternalProject_Add ( ThirdParty_DevIL
    PREFIX "${DEVIL_BUILD_PATH}"
    GIT_REPOSITORY "https://github.com/DentonW/DevIL"
    PATCH_COMMAND cmake -E copy "${DEVIL_BUILD_PATH}/DevilCMakeLists.txt" "${DEVIL_BUILD_PATH}/src/ThirdParty_DevIL/DevIL/"
    INSTALL_DIR ${DEVIL_OUTPUT_PATH}
    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> )

list ( APPEND THIRD_PARTY_DEPENDENCIES ThirdParty_DevIL )
set ( DEVIL_INCLUDE_DIR "${DEVIL_OUTPUT_PATH}/include" )
set ( DEVIL_LIBRARY devil )
add_definitions ( -DDEVIL )
endif()

list ( APPEND THIRD_PARTY_INCLUDE_DIRS "${DEVIL_INCLUDE_DIR}" )
list ( APPEND THIRD_PARTY_LIBRARIES ${DEVIL_LIBRARY} )

我尝试像这样对路径进行硬编码(“/src/ThirdParty_DevIL/”部分),但它非常难看,如果 cmake 决定在将来更改它,它就会中断。 此外,由于这实际上是在 git 树中复制文件,因此 cmake 稍后会抱怨

Failed to unstash changes in:
'<yadda yadda>/ThirdParty/build//DevIL//src/ThirdParty_DevIL/'.


You will have to resolve the conflicts manually

有没有办法让这个解决方案(创建一个临时的 CMakeListst.txt )起作用? 或者更好的是,是否有其他解决方案,仅涉及正确配置 ExternalProject_add ?

我对参数、路径等没有任何要求,所以请随意提出任何建议。 我怎样才能解决这个问题? 谢谢

【问题讨论】:

    标签: git cmake external-project


    【解决方案1】:

    您可以提供 CONFIGURE_COMMAND 选项,而不是修补源代码树,该选项使用正确的目录作为源代码:

    ExternalProject_Add ( ThirdParty_DevIL
        PREFIX "${DEVIL_BUILD_PATH}"
        GIT_REPOSITORY "https://github.com/DentonW/DevIL"
        INSTALL_DIR ${DEVIL_OUTPUT_PATH}
        CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
            <SOURCE_DIR>/DevIL # Tell CMake to use subdirectory as source.
    )
    

    在这种情况下,您应该手动向此命令添加内容,这些内容通常带有 CMAKE_ARGSCMAKE_CACHE_ARGS 等选项。但这不应该是一个真正的问题。


    或者,您可以将ExternalProject_Add 拆分为两个调用:一个只下载包,第二个执行其他所有操作。在这些调用中,您可以使用不同的 SOURCE_DIR 选项:

    ExternalProject_Add ( ThirdParty_DevIL_download
        PREFIX "${DEVIL_BUILD_PATH}"
        SOURCE_DIR "${DEVIL_BUILD_PATH}/src/ThirdParty_DevIL" # Explicitely set
        GIT_REPOSITORY "https://github.com/DentonW/DevIL"
        CONFIGURE_COMMAND "" # Disable all other steps
        BUILD_COMMAND ""
        INSTALL_COMMAND ""
    )
    
    ExternalProject_Add ( ThirdParty_DevIL
        PREFIX "${DEVIL_BUILD_PATH}"
        DOWNLOAD_COMMAND "" # Disable download step
        SOURCE_DIR "${DEVIL_BUILD_PATH}/src/ThirdParty_DevIL/DevIL" # Source dir for configuration
        INSTALL_DIR ${DEVIL_OUTPUT_PATH}
        CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
    )
    
    # Add dependency between to calls
    add_dependencies(ThirdParty_DevIL ThirdParty_DevIL_download)
    

    由于 SOURCE_DIR 基于PREFIX 的计算依赖于外部项目的名称,并且两次调用的名称不同,所以该选项被明确设置。

    这种方法的缺点是构建日志会显示有关许多“未执行”步骤的行(配置、构建和安装用于第一次 ExternalProject_Add() 调用和下载,路径和更新用于第二次调用)。

    【讨论】:

    • 选择了第一个解决方案。不幸的是,我放弃了 DevIL,因为它需要额外的配置步骤,并添加了依赖项,但这仍然是最好的解决方案,它几乎完成了构建。谢谢。
    【解决方案2】:

    我认为使用参数 SOURCE_SUBDIR 可以解决这个问题,例如:

    ExternalProject_Add ( ThirdParty_DevIL
        PREFIX "${DEVIL_BUILD_PATH}"
        GIT_REPOSITORY "https://github.com/DentonW/DevIL"
        SOURCE_SUBDIR "DevIL"
        ....
    )
    

    【讨论】:

    • 是的,SOURCE_SUBDIR 选项提供了比CONFIGURE_COMMAND 的显式设置更简洁的方式。由于 CMake 3.7(出现选项时),这是首选方式。
    猜你喜欢
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多