Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake ExternalProject_Add() and FindPackage()

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.

like image 960
Lars Bilke Avatar asked Jul 03 '13 11:07

Lars Bilke


2 Answers

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.

like image 142
user1283078 Avatar answered Sep 20 '22 14:09

user1283078


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() 
like image 35
David Avatar answered Sep 16 '22 14:09

David