Is it possible to use FetchContent or an equivalent to add a library that has no CMakeLists.txt through CMake?

Viewed 5466

I have a small project in the works that requires the use of two libraries, namely ASIO (standalone) and nlohmann/json.

Adding the json library to my CMake project is pretty straight-forward:

include(FetchContent)

FetchContent_Declare(json
  GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent
  GIT_TAG v3.9.1)

FetchContent_GetProperties(json)
if(NOT json_POPULATED)
  FetchContent_Populate(json)
  add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()

target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)

However, since ASIO doesn't have a CMakeLists.txt, it doesn't seem to work. Is there a workaround for this or do I absolutely need to install ASIO externally?

Probably worth mentioning that both libraries are header-only, so I only really need cmake to fetch the library and add the appropriate include paths.

1 Answers

FetchContent can deal with non-CMake projects, too. See the full documentation here and in particular the first sentence, which states it can deal with projects "via any method supported by the ExternalProject module."

In the case of asio, which is a header-only library it is quite simple, as you just need to tell FetchContent that there is no "configure" and no "build" step.

FetchContent_Declare(asio
  GIT_REPOSITORY git@github.com:chriskohlhoff/asio.git
  GIT_TAG master
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  )

This will just download the sources in the populate step.

Now you can setup an asio target yourself with something like

add_library(asio INTERFACE)
target_include_directories(asio INTERFACE ${asio_SOURCE_DIR}/asio/include)
find_package(Threads)
target_link_libraries(asio INTERFACE Threads::Threads)

Here is a complete CMakeLists.txt which I used to build the first example from the asio tutorial.

cmake_minimum_required(VERSION 3.14.7)

project(sample LANGUAGES CXX)

include(FetchContent)

FetchContent_Declare(asio
  GIT_REPOSITORY git@github.com:chriskohlhoff/asio.git
  GIT_TAG master
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  )

FetchContent_GetProperties(asio)
if(NOT asio_POPULATED)
  FetchContent_Populate(asio)
endif()

add_library(asio INTERFACE)
target_include_directories(asio INTERFACE ${asio_SOURCE_DIR}/asio/include)
find_package(Threads)
target_link_libraries(asio INTERFACE Threads::Threads)

add_executable(example example.cc)
target_link_libraries(example asio)
Related