CMake ExternalProject_Add()和FindPackage()

时间:2013-07-03 11:40:10

标签: c++ build cmake vtk external-project

是否有正确的方法来查找使用FindPackage()构建的库(通过ExternalProject_Add())?

问题是CMake无法在CMake时找到库,因为外部库在编译时生成。我知道在构建库和superbuild中的项目时可以组合这两个CMake函数,但我想在普通的CMake项目中使用它。

事实上,我想用ExternalProject_Add构建VTK 6,并在我的CMake项目中找到FindPackage

3 个答案:

答案 0 :(得分:20)

有一种方法可以做到这一点。但这有点像黑客。 你基本上添加了一个自定义目标,在构建期间重新运行cmake。

你必须在一个小型测试项目中尝试这个,以确定它是否适合你

find_package(Beaengine)


############################################
#
#    BeaEngine
#
include(ExternalProject)
externalproject_add(BeaEngine
    SOURCE_DIR            ${PROJECT_SOURCE_DIR}/beaengine   
    SVN_REPOSITORY        http://beaengine.googlecode.com/svn/trunk/
    CMAKE_ARGS            -DoptHAS_OPTIMIZED=TRUE -DoptHAS_SYMBOLS=FALSE -DoptBUILD_64BIT=FALSE -DoptBUILD_DLL=FALSE -DoptBUILD_LITE=FALSE
    INSTALL_COMMAND       ""
 )


if(NOT ${Beaengine_FOUND})
    #rerun cmake in initial build
    #will update cmakecache/project files on first build
    #so you may have to reload project after first build
    add_custom_target(Rescan ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} DEPENDS BeaEngine)
else()
    #Rescan becomes a dummy target after first build
    #this prevents cmake from rebuilding cache/projects on subsequent builds
    add_custom_target(Rescan)
endif()




add_executable(testapp testapp.cpp )
add_dependencies(testapp Rescan)
if(${Beaengine_FOUND})
    target_link_libraries(testapp ${Beaengine_LIBRARY})
endif()

这似乎适用于mingw makefile / eclipse makefile项目。 vs将在首次构建后请求重新加载所有项目。

答案 1 :(得分:11)

您可以使用下面的 build_external_project 功能强制构建。

它的工作原理是在构建树中生成一个简单的帮助项目,然后在帮助程序上调用cmake配置和cmake构建。

随意自定义实际的ExternalProject_add命令。

请注意,尾随参数用于传递CMAKE_ARGS。 Furthur增强功能留给读者练习: - )

# This function is used to force a build on a dependant project at cmake configuration phase.
# 
function (build_external_project target prefix url) #FOLLOWING ARGUMENTS are the CMAKE_ARGS of ExternalProject_Add

    set(trigger_build_dir ${CMAKE_BINARY_DIR}/force_${target})

    #mktemp dir in build tree
    file(MAKE_DIRECTORY ${trigger_build_dir} ${trigger_build_dir}/build)

    #generate false dependency project
    set(CMAKE_LIST_CONTENT "
        cmake_minimum_required(VERSION 2.8)

        include(ExternalProject)
        ExternalProject_add(${target}
            PREFIX ${prefix}/${target}
            URL ${url}
            CMAKE_ARGS ${ARGN}
            INSTALL_COMMAND \"\"
            )

        add_custom_target(trigger_${target})
        add_dependencies(trigger_${target} ${target})
    ")

    file(WRITE ${trigger_build_dir}/CMakeLists.txt "${CMAKE_LIST_CONTENT}")

    execute_process(COMMAND ${CMAKE_COMMAND} ..
        WORKING_DIRECTORY ${trigger_build_dir}/build
        )
    execute_process(COMMAND ${CMAKE_COMMAND} --build .
        WORKING_DIRECTORY ${trigger_build_dir}/build
        )

endfunction()

答案 2 :(得分:4)

时间已经过去,CMake实现了本机版本,允许从ExternalProject_Add引用目标。

此功能在FetchContent模块中实现。它允许下载并立即使用在配置时定义的目标。

它使用我的previous answer所提示的草稿生成目录,但使用的是集成程度更高的API。