0

I'm trying to include a Github header-only library in my CMake build configuration for my project. I've tried adapting some configuration from:

But I can't make it work. This is what I have so far:

cmake_minimum_required(VERSION 3.7)

project(sdl2_experiments)

set(simple_VERSION_MAJOR 0)
set(simple_VERSION_MINOR 1)

set(CMAKE_CXX_FLAGS "-g -Wall -std=c++17 -pthread")

find_package(SDL2 REQUIRED)

# https://foonathan.net/2016/07/cmake-dependency-handling/
# https://stackoverflow.com/questions/41345844/adding-header-only-dependencies-with-cmake
find_path(
  CPP_SDL2_INCLUDE_DIR
  PATHS "vendor/cpp-sdl2/sources/sdl2-cpp/"
  )

if((NOT CPP_SDL2_INCLUDE_DIR) OR (NOT EXISTS ${CPP_SDL2_INCLUDE_DIR}))
  message("cpp-sdl2 not found")

  message("Updating cpp-sdl2 from Github")
  execute_process(
    COMMAND git submodule update --init -- vendor/cpp-sdl2
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    )

  message("Setting CPP_SDL2_INCLUDE_DIR as \"${CMAKE_CURRENT_SOURCE_DIR}/vendor/cpp-sdl2/sources/sdl2-cpp/\"")
  set(
    CPP_SDL2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/cpp-sdl2/sources/sdl2-cpp/"
    CACHE PATH "sdl2-cpp include"
    )

  message("Installing ${CPP_SDL2_INCLUDE_DIR} into include")
  install(
    DIRECTORY "${CPP_SDL2_INCLUDE_DIR}"
    DESTINATION "include"
    )

  message("Adding cpp_sdl2 library")
  add_library(
    cpp_sdl2 INTERFACE
    )

  message("Setting up include directories")
  target_include_directories(
    cpp_sdl2 INTERFACE
    $<BUILD_INTERFACE:${CPP_SDL2_INCLUDE_DIR}>
    $<INSTALL_INTERFACE:include>
    )

  message("Installing cpp_sdl2 target")
  install(
    TARGETS cpp_sdl2
    EXPORT cpp_sdl2
    DESTINATION include
    )
else()
  message("cpp_sdl2 found")

  message("Add cpp_sdl2 library")
  add_library(
    cpp_sdl2 INTERFACE
    )

  message("Setting up include directories")
  target_include_directories(
    cpp_sdl2 INTERFACE "${CPP_SDL2_INCLUDE_DIR}"
    )
endif()

include_directories(
  "${CPP_SDL2_INCLUDE_DIR}"
  "${SDL2_INCLUDE_DIRS}"
  )

add_executable(
  hello
  hello.cpp
  )

target_link_libraries(
  hello
  ${SDL2_LIBRARIES}
  )

I also have the following .gitmodules:

[submodule "vendor/cpp-sdl2"]
    path = vendor/cpp-sdl2
    url = https://github.com/Edhebi/cpp-sdl2.git

When I run cmake --log-level VERBOSE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . I get the following errors:

cpp-sdl2 not found
Updating cpp-sdl2 from Github
Setting CPP_SDL2_INCLUDE_DIR as "/home/user/code/c/sdl2-experiments/vendor/cpp-sdl2/sources/sdl2-cpp/"
Installing CPP_SDL2_INCLUDE_DIR-NOTFOUND into include
Adding cpp_sdl2 library
Setting up include directories
Installing cpp_sdl2 target
-- Configuring done
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:
CPP_SDL2_INCLUDE_DIR
   used as include directory in directory /home/user/code/c/sdl2-experiments
   used as include directory in directory /home/user/code/c/sdl2-experiments
   used as include directory in directory /home/user/code/c/sdl2-experiments
   used as include directory in directory /home/user/code/c/sdl2-experiments
   used as include directory in directory /home/user/code/c/sdl2-experiments
   used as include directory in directory /home/user/code/c/sdl2-experiments
   used as include directory in directory /home/user/code/c/sdl2-experiments

It looks like it's settings CPP_SDL2_INCLUDE_DIR to NOTFOUND but I don't understand why. I've tried varying the vendor/cpp-sdl2/sources/sdl2-cpp/ as:

  • vendor/cpp-sdl2/sources/sdl2-cpp/
  • vendor/cpp-sdl2/sources/sdl2-cpp/sdl.hpp
  • vendor/cpp-sdl2/sources/

The Github dependency is already cloned as I did that manually.

Ultimately, what I really want is to have a one-step cmake call that adds all the third party dependencies, so I'm open to other approaches. I've seen a few things based on ExternalProject.

ironchicken
  • 754
  • 6
  • 19
  • 2
    The line `Installing CPP_SDL2_INCLUDE_DIR-NOTFOUND into include` should give you a pretty good idea what's wrong. Using `CACHE` in your set call means that the cached value will be used if one exists. You can use `FORCE` to overwrite existing values. – super Nov 15 '20 at 16:32
  • Thanks, @super. I've taken out that `CACHE PATH` altogether and now it works. I don't really understand why a cached value can already have existed, though. Where did it come from? – ironchicken Nov 15 '20 at 20:24
  • Maybe from trying different things in your CMakeList.txt and not clearing the cached between. Or if you used command-line `-DCPP_SDL2_INCLUDE_DIR=value` at some point, that will also create the value in the cache. – super Nov 15 '20 at 21:13
  • "I don't really understand why a cached value can already have existed, though. Where did it come from?" - the line `find_path(CPP_SDL2_INCLUDE_DIR PATHS "vendor/cpp-sdl2/sources/sdl2-cpp/" )` creates the variable, whenever the path has been found or not. BTW, you even check the variable's value with `if` command. – Tsyvarev Nov 15 '20 at 23:35

0 Answers0