Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

cmake

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.

like image 800
Arthur Caputo Avatar asked Jan 05 '21 20:01

Arthur Caputo


People also ask

What is FetchContent?

The FetchContent module also supports defining and populating content in a single call, with no check for whether the content has been populated elsewhere already. This should not be done in projects, but may be appropriate for populating content in CMake's script mode.

What does Add_subdirectory do in CMake?

Add a subdirectory to the build. Adds a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.


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 [email protected]: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 [email protected]: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)
like image 130
havogt Avatar answered Oct 28 '22 19:10

havogt