15

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.

Arthur Caputo
  • 153
  • 1
  • 4
  • I think all you can do is to either write the CMakeLists.txt file yourself (for asio) or you have to do it externally as you mention – J. Lengel Jan 05 '21 at 22:29
  • Check out this post: (https://stackoverflow.com/questions/60592615/how-would-i-include-asio-library-using-cmake). The asio library has to be made (that means run make) and then you just link against it as you would normally (just no add_subdirectory) – J. Lengel Jan 05 '21 at 22:35
  • @j-lengel Yes, linking against it should be doable, what concerns me is that it would be great for my peers if they didn't have to download the specific version that we're using and then extract it. Also worth noting we're building between Linux and Windows. – Arthur Caputo Jan 06 '21 at 00:44
  • One suggestion would be to write a script to download and extract the library into the dependencies folder and then run make after (still in the script). The script could then also run cmake and all your peers need is this script which you can include in your github repo – J. Lengel Jan 06 '21 at 11:24

1 Answers1

16

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)
havogt
  • 2,572
  • 1
  • 27
  • 37
  • Shouldn't the lines, add_library(asio...) to target_link_libraries(asio...), be at the right below FetchContent_Populate(asio)? – wk_j May 13 '21 at 10:52
  • 1
    According to the documentation, "The configure, build, install and test steps are explicitly disabled and therefore options related to them will be ignored." – Dave F Aug 13 '22 at 20:41