Ignorant
Ignorant

Reputation: 2681

How to build an external library downloaded with CMake FetchContent?

I have a program that depends on an external library (SDL for example). I want CMake to take care of that dependency for me, so I was looking into FetchContent. As far as I understand, this module simply downloads the source code so that information on the external library is available at configure time. For example:

include(FetchContent)

FetchContent_Declare(sdl
  GIT_REPOSITORY <...>
)

FetchContent_GetProperties(sdl)

# sdl_POPULATED, sdl_SOURCE_DIR and sdl_BINARY_DIR are ready now

if(NOT sdl_POPULATED)
  FetchContent_Populate(sdl)
endif()

At some point, however, I want to build that source code and link it to my main executable. How to do it the "modern CMake way"?

Upvotes: 8

Views: 12871

Answers (1)

Matt
Matt

Reputation: 385

The recommended way to build external libraries from source as part of your build depends on what the external lib provides build-wise.

External lib builds with cmake

If the external lib builds with cmake then you could add the lib to your build via a add_subdirectory(${libname_SOURCE_DIR}) call. That way cmake will build the external lib as a subfolder ("subproject"). The CMakeLists.txt file of the external lib will have some add_library(ext_lib_name ...) statements in it. In order to then use the external lib in your targets (an application or library that depends on the external lib) you can simply call target_link_libraries(your_application <PRIVATE|PUBLIC|INTERFACE> ext_lib_name) https://cmake.org/cmake/help/latest/command/target_link_libraries.html

I had a quick look at this github repo https://github.com/rantoniello/sdl - (let me know if you are referring to another library) and it actually looks like it is building with cmake and that it allows clients to statically or dynamically link against it: https://github.com/rantoniello/sdl/blob/master/CMakeLists.txt#L1688-L1740

So, ideally your applicaiton should be able to do

add_executable(myapp ...)
target_link_libraries(myapp PRIVATE SDL2-static) // Statically link againt SDL2

Due to their CMakeLists.txt file the SDL2-static comes with properties (include directories, linker flags/commands) that will automatically propergate to myapp.

External lib does not build with cmake

If a external lib doesn't build with cmake then one can try to use add_custom_target https://cmake.org/cmake/help/latest/command/add_custom_target.html to build the library. Something along the lines of:

add_custom_target(myExternalTarget COMMAND <invoke the repo's build system>)

You'd then need to set the target properties that are important for clients yourself via the the proper cmake functions set_target_properties, target_include_directories ... A great writeup how to get started with these kinds of things: https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/

Upvotes: 4

Related Questions