Is there are proper way to find a library (via FindPackage()
) which was built with ExternalProject_Add()
?
The problem is that CMake cannot find the library at CMake-time because the external library gets build at compile time. I know that it is possible to combine these two CMake function when building the library and the project in a superbuild but I want to use it in a normal CMake project.
In fact I would like to build VTK 6 with ExternalProject_Add
and find it with FindPackage
all inside my CMake project.
there is a way to do this. but it´s kind of hackish.
you basically add a custom target, that reruns cmake during build.
you will have to try this in a small test project, to decide if it works for you
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()
this seems to work well for mingw makefiles / eclipse makefile projects.
vs will request to reload all projects after first build.
You can force a build using the build_external_project function below.
It works by generating a simple helper project inside the build tree and then calling the cmake configuration and the cmake build on the helper.
Customize at will for the actual ExternalProject_add command.
Note that the trailing arguments are used to pass CMAKE_ARGS. Furthur enhancements are left as an exercise to the reader :-)
# 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()