CMake-没有更改时不需要的重建

问题描述

我正在使用BUILD_IN_SOURCE = TRUE的使用ExternalProject的项目,并且每次都会重建整个项目(所有源和目标),好像make无法看到文件已经存在。我的实现如下所示:

# Need to explicitly enable ExternalProject functionality
include(ExternalProject)

# Download or update library as an external project
ExternalProject_Add(project_bdsg
        GIT_REPOSITORY https://github.com/vgteam/libbdsg-easy.git
        PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/
        CONfigURE_COMMAND ""
        UPDATE_disCONNECTED True
        BUILD_ALWAYS False
        BUILD_IN_SOURCE True
        INSTALL_DIR ${CMAKE_SOURCE_DIR}/external/bdsg/
        INSTALL_COMMAND make INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/external/bdsg/ install
        )

# Define INSTALL_DIR as the install directory for external library
ExternalProject_Get_Property(project_bdsg INSTALL_DIR)

# Create new library for external project (so it can be linked with main library)
add_library(bdsg STATIC IMPORTED)
set_property(TARGET bdsg
        PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libbdsg.a)

add_library(divsufsort STATIC IMPORTED)
set_property(TARGET divsufsort
        PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libdivsufsort64.a)

add_library(libhandlegraph STATIC IMPORTED)
set_property(TARGET libhandlegraph
        PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libhandlegraph.a)

add_library(libsdsl STATIC IMPORTED)
set_property(TARGET libsdsl
        PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libsdsl.a)

# Define library as dependent on the downloaded project
add_dependencies(bdsg
        project_bdsg
        libsdsl
        libhandlegraph
        divsufsort)

# Define main library as dependent on the downloaded project (transitively)
add_dependencies(Bluntifier bdsg)

# Ensure that main library has access to primary dependencies' and secondary dependencies' headers
include_directories(external/bdsg/include/)

并且我有这样定义的目标:

    add_executable(${FILENAME_PREFIX} src/test/${FILENAME_PREFIX}.cpp)
    set_property(TARGET ${FILENAME_PREFIX} PROPERTY INSTALL_RPATH "$ORIGIN")
    target_link_libraries(${FILENAME_PREFIX}
            Bluntifier
            Threads::Threads
            bdsg
            divsufsort
            libhandlegraph
            libsdsl)

通过一些调试输出运行make会给我这样的消息:

Updating goal targets....
Considering target file 'CMakeFiles/Bluntifier.dir/build'.
 File 'CMakeFiles/Bluntifier.dir/build' does not exist.
  Considering target file 'Bluntifier.a'.
    Considering target file 'CMakeFiles/Bluntifier.dir/link.txt'.
     Finished prerequisites of target file 'CMakeFiles/Bluntifier.dir/link.txt'.
    No need to remake target 'CMakeFiles/Bluntifier.dir/link.txt'.
    Considering target file 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
     File 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o' does not exist.
      Considering target file '../src/adjacency_components.cpp'.
       Finished prerequisites of target file '../src/adjacency_components.cpp'.
      No need to remake target '../src/adjacency_components.cpp'.
      Considering target file '../external/bdsg/include/bdsg/internal/packed_structs.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/bdsg/internal/packed_structs.hpp'.
      No need to remake target '../external/bdsg/include/bdsg/internal/packed_structs.hpp'.
      Considering target file '../external/bdsg/include/handlegraph/expanding_overlay_graph.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/handlegraph/expanding_overlay_graph.hpp'.
      No need to remake target '../external/bdsg/include/handlegraph/expanding_overlay_graph.hpp'.
      Considering target file '../external/bdsg/include/handlegraph/handle_graph.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/handlegraph/handle_graph.hpp'.
      No need to remake target '../external/bdsg/include/handlegraph/handle_graph.hpp'.
      Considering target file '../external/bdsg/include/handlegraph/iteratee.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/handlegraph/iteratee.hpp'.
      No need to remake target '../external/bdsg/include/handlegraph/iteratee.hpp'.
      Considering target file '../external/bdsg/include/handlegraph/types.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/handlegraph/types.hpp'.
      No need to remake target '../external/bdsg/include/handlegraph/types.hpp'.
      Considering target file '../external/bdsg/include/handlegraph/util.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/handlegraph/util.hpp'.
      No need to remake target '../external/bdsg/include/handlegraph/util.hpp'.
      Considering target file '../external/bdsg/include/sdsl/bits.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/bits.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/bits.hpp'.
      Considering target file '../external/bdsg/include/sdsl/config.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/config.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/config.hpp'.
      Considering target file '../external/bdsg/include/sdsl/int_vector.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/int_vector.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/int_vector.hpp'.
      Considering target file '../external/bdsg/include/sdsl/int_vector_buffer.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/int_vector_buffer.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/int_vector_buffer.hpp'.
      Considering target file '../external/bdsg/include/sdsl/io.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/io.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/io.hpp'.
      Considering target file '../external/bdsg/include/sdsl/iterators.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/iterators.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/iterators.hpp'.
      Considering target file '../external/bdsg/include/sdsl/memory_management.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/memory_management.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/memory_management.hpp'.
      Considering target file '../external/bdsg/include/sdsl/ram_filebuf.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/ram_filebuf.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/ram_filebuf.hpp'.
      Considering target file '../external/bdsg/include/sdsl/ram_fs.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/ram_fs.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/ram_fs.hpp'.
      Considering target file '../external/bdsg/include/sdsl/sdsl_concepts.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/sdsl_concepts.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/sdsl_concepts.hpp'.
      Considering target file '../external/bdsg/include/sdsl/sfstream.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/sfstream.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/sfstream.hpp'.
      Considering target file '../external/bdsg/include/sdsl/structure_tree.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/structure_tree.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/structure_tree.hpp'.
      Considering target file '../external/bdsg/include/sdsl/uintx_t.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/uintx_t.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/uintx_t.hpp'.
      Considering target file '../external/bdsg/include/sdsl/util.hpp'.
       Finished prerequisites of target file '../external/bdsg/include/sdsl/util.hpp'.
      No need to remake target '../external/bdsg/include/sdsl/util.hpp'.
      Considering target file '../inc/adjacency_components.hpp'.
       Finished prerequisites of target file '../inc/adjacency_components.hpp'.
      No need to remake target '../inc/adjacency_components.hpp'.
      Considering target file '../inc/subtractive_graph.hpp'.
       Finished prerequisites of target file '../inc/subtractive_graph.hpp'.
      No need to remake target '../inc/subtractive_graph.hpp'.
      Considering target file '../inc/utility.hpp'.
       Finished prerequisites of target file '../inc/utility.hpp'.
      No need to remake target '../inc/utility.hpp'.
      Pruning file '../src/adjacency_components.cpp'.
      Pruning file 'CMakeFiles/Bluntifier.dir/flags.make'.
     Finished prerequisites of target file 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
    Must remake target 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
[ 38%] Building CXX object CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o
    Successfully remade target file 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.

其中adjacency_components.cpp是每次我运行make时都会重建的几个源文件之一。为什么得出结论认为需要重建这些目标?

解决方法

在我的调试输出中进一步查找之后,很明显,cmake正在从ExternalProject的下载内容中跟踪文件时间戳。由于每次我重新编译时都会重新下载,因此总会有一个新的时间戳,导致所有受抚养者相对而言过时,然后触发重新编译所有内容。要在开发过程中暂时停止此操作,只需添加以下行:

        DOWNLOAD_COMMAND ""
        UPDATE_COMMAND ""

到ExternalProject参数。理想情况下,这将与开发人员可以调用的标志相关联,这样就不是默认行为。