web-dev-qa-db-ja.com

CMake ExternalProject_Add()およびFindPackage()

FindPackage()でビルドされたライブラリを(ExternalProject_Add()を介して)見つける適切な方法はありますか?

問題は、外部ライブラリがコンパイル時にビルドされるため、CMakeがCMake時にライブラリを見つけられないことです。スーパービルドでライブラリとプロジェクトをビルドするときにこれら2つのCMake関数を組み合わせることができることは知っていますが、通常のCMakeプロジェクトで使用したいと思います。

実際、ExternalProject_Addを使用してVTK 6をビルドし、FindPackageを使用してすべてのCMakeプロジェクト内でVTK 6を見つけたいと思います。

29
Lars Bilke

これを行う方法があります。しかし、それは一種のハックです。基本的に、ビルド中に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 makefiles/Eclipse makefileプロジェクトでうまく機能するようです。 vsは、最初のビルド後にすべてのプロジェクトをリロードするように要求します。

20
user1283078

以下の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()
12
David