[CMake] To include external libraries using Cmake

Matthew Woehlke matthew.woehlke at kitware.com
Thu Jan 5 14:21:40 EST 2017


On 2017-01-05 05:10, aishwarya selvaraj wrote:
> Thanks for feedback :
> 
>> IF (${ARMADILLO} STREQUAL “ARMADILLO-NOTFOUND”)
>>   # do what you want
>> ENDIF ()
>> I tried this way of writing :
> 
> IF (${ARMADILLO} STREQUAL "ARMADILLO-NOTFOUND")
>     include(ExternalProject)
>     ExternalProject_Add(armadillo
>     URL https://github.com/lsolanka/armadillo/archive/master.zip
>      PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-latest)
> ENDIF()
> 
> and
> 
> IF (ARMADILLO STREQUAL ARMADILLO-NOTFOUND)
>    include(ExternalProject)
>    MESSAGE(STATUS "Trying to install armadillo...")
>     ExternalProject_Add(armadillo
>     URL https://github.com/lsolanka/armadillo/archive/master.zip
>     PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-latest)
> ENDIF()

`if(NOT ARMADILLO)` is probably better...

> ​But both of them gave me an error :
>   CMake Error: The following variables are used in this project, but
>   they are set to NOTFOUND. Please set them or make sure they are set
>   and tested correctly in the CMake files:
>   ARMADILLO
>     linked by target "tsm" in directory /home/computing9/TSM_cmake
>   SNDFILE
>     linked by target "tsm" in directory /home/computing9/TSM_cmake

Ah... I was mostly replying to Parag; I hadn't actually looked that
closely at your original problem.

What you're trying to do is similar to a "superbuild" with optional
components. The usual way to do this is to treat *your own project* as
one of several external projects, so that the "superbuild" consists
solely of external projects. Something like:

  set(mydeps)
  if(NOT armadillo)
    externalproject_add(armadillo ...)
    list(APPEND mydeps armadillo
  endif()
  # similar for other externals
  externalproject_add(myproject ... DEPENDS ${mydeps})

This way, by the time your project configures, the library exists.
(You'll probably end up looking for the library twice; once in the
superbuild to decide whether to build it, and again in your project
proper where you'll a) assume it exists and hard error otherwise, and b)
want to specify as an additional search path where the superbuild will
produce it.)

Without this, trying to set up the rules so that you can both link the
library that will be created, and also get the dependencies correct so
that the build knows how to produce it when needed, is probably going to
be tricky. (Read: I'm not convinced it's impossible, but I've never seen
someone actually doing this and wouldn't recommend it.)

An alternative that may work is to set up the externals as subprojects
and have CMake fetch them at configure time if they are needed, and then
incorporate their builds directly in your own build (i.e. using
add_subdirectory rather than externalproject_add); then you can link to
the library target names when you build them yourself, and everything
will work.

p.s. I don't recommend always obtaining the current master of externals.
It's usually safer to pick a SHA and bump it as needed, so that you are
insulated against breaking changes upstream. I'm also not sure why you
are fetching snapshots instead of just using the git repositories directly.

-- 
Matthew


More information about the CMake mailing list