[CMake] Consuming results of ExternalProject_Add

Andrey Pokrovskiy wonder.mice at gmail.com
Wed Feb 18 16:12:45 EST 2015


Thanks for clarification, JC. The links you provided are a good read.

However, I would like to avoid "super-build" technique. It needlessly
(in my case) complicates and obfuscates things.

> In fact, all FindXXXX.cmake module are slowly been converted to create CMake imported targets.

FindXXXX.cmake modules assume that artifacts (libraries, headers)
already exist and use INTERFACE or/and IMPORTED targets. But there are
problems when headers and libraries generated with the build. See
thread about that specific limitation [1].

* add_library(xxx INTERFACE) - target_link_libraries and
target_include_directories can be used but library xxx can't depend on
anything (but it must depend on external project that will generate
it)
* add_library(xxx IMPORTED GLOBAL) - INTERFACE_INCLUDE_DIRECTORIES and
INTERFACE_LINK_LIBRARIES can be used, but will produce error during
configuration that include dir doesn't exist and associated libraries
will be "_NOT_FOUND".

As for now, I ended up with the following:

  ExternalProject_Add(openssl ...)
  add_library(crypto INTERFACE)
  target_link_libraries(crypto INTERFACE
${OPENSSL_INSTALL_PREFIX}/lib/libcrypto.a)
  target_include_directories(crypto INTERFACE ${OPENSSL_INSTALL_PREFIX}/include)
  add_library(ssl INTERFACE)
  target_link_libraries(ssl INTERFACE ${OPENSSL_INSTALL_PREFIX}/lib/libssl.a)
  target_include_directories(ssl INTERFACE ${OPENSSL_INSTALL_PREFIX}/include)

With the requirement to add_dependencies(... openssl) when target
depends on ssl or crypto libraries, like that:

  add_executable(my_executable ${SOURCES})
  add_dependencies(my_executable openssl)
  target_link_libraries(my_executable crypto ssl)

Quite inconsistent behaviour if you ask me.

Thanks, anyway. I will keep in mind this "super-build" thing in case
my solution will not scale too well.

[1] http://www.cmake.org/pipermail/cmake/2015-February/059885.html

On Tue, Feb 17, 2015 at 9:58 PM, Jean-Christophe Fillion-Robin
<jchris.fillionr at kitware.com> wrote:
> Hi Andrey,
>
> On Tue, Feb 17, 2015 at 5:52 PM, Andrey Pokrovskiy <wonder.mice at gmail.com>
> wrote:
>>
>>
>> I don't see how External_OpenSSL.cmake is used in Slicer (probably
>> some weird scheme is involved).
>
>
> We used "Artichoke" that provides a set of convenience function to managed
> "superbuild" based project.
> See [1] and [2] for mode details.
>
> [1] http://public.kitware.com/pipermail/cmake/2014-June/057735.html
> [2] https://github.com/commontk/Artichoke
>
>
>>
>> But from what I see, it supposed to be used like that:
>>
>>   include(External_OpenSSL)
>>   add_executable(my_executable main.cpp ...)
>>   target_include_directories(my_executable ${OPENSSL_INCLUDE_DIR})
>>   target_link_libraries(my_executable ${OPENSSL_LIBRARIES})
>>
>> That means that I will need to include External_OpenSSL in every
>> CMakeLists.txt that uses OpenSSL. That doesn't sounds right to me.
>
>
>
> One way of using external projects is to consider it automate the following
> steps:
>
>  (1) manual build of OpenSSL
>  (2) configuration of your project Foo passing either
> OPENSSL_CRYPTO_LIBRARY/OPENSSL_SSL_LIBRARY options on unix or
> LIB_EAY_DEBUG/LIB_EAY_RELEASE/SSL_EAY_DEBUG/SSL_EAY_RELEASE on windows, and
> then build of the project
>
>
> And since there are no need to manually rebuild openssl for each
> CMakeLists.txt in your project Foo, there are no need to include
> "External_OpenSSL" in every CMakeLists.txt.
>
> Reading [3] should also be helpful to understand the concepts.
>
> [3]
> http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html
>
>
>
>
>
>
>>
>>
>> And if not, then something adds OPENSSL_INCLUDE_DIR and
>> OPENSSL_LIBRARIES to CACHE which is also doesn't sounds right.
>>
>> Also this will not setup build dependency between target and OpenSSL.
>> I know, I could use additional add_dependencies() for that, but that's
>> clumsy. 3 lines instead of just:
>>
>>   target_link_libraries(my_executable crypto ssl)
>
>
> After doing:
>
>   find_package(OpenSSL)
>
> in your project, you could then do:
>
>   target_link_libraries(my_executable ${OPENSSL_LIBRARIES})
>
>
>
>>
>>
>> CMake already has a concept of "libraries" (added with add_library).
>> There should be a way of saying "Hey, this static library comes from
>> that external project. It also requires such and such include
>> directories".
>
>
> In fact, all FindXXXX.cmake module are slowly been converted to create CMake
> imported targets.
>
> Since the current FindOpenSSL.cmake does not create imported targets, it
> could be updated to do so. For an example, see [4]
>
> [4]
> http://www.cmake.org/cmake/help/v3.1/manual/cmake-developer.7.html#a-sample-find-module
> [5] https://github.com/Kitware/CMake/commit/bcb0e38
>
>
> Hth
> Jc
>
>
>
>
> --
> +1 919 869 8849


More information about the CMake mailing list