TheLartians/ModernCppStarter

Include errors

shelltitan opened this issue · 13 comments

I tried to add multiple libraries to this template project, but all my library includes seem to be failing (eg: #include <SDL.h>
). I am not sure if I did something wrong. Could you take a look for me? The other problem I had when I tried to use spdlog with the

"SPDLOG_FMT_EXTERNAL YES"

option, the spdlog was not able to find fmt which was downloaded by CPMAddPackage already.
Here is my CMakeList.txt:

cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

# ---- Project ----

# Note: update this to your new project's name and version
project(
  ArcaneLords
  VERSION 0.1
  LANGUAGES CXX
)


set(OpenGL_GL_PREFERENCE "GLVND")


# ---- Include guards ----

if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
  message(
    FATAL_ERROR
      "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
  )
endif()

# ---- Add dependencies via CPM ----
# see https://github.com/TheLartians/CPM.cmake for more info

include(cmake/CPM.cmake)

# PackageProject.cmake will be used to make our target installable
CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.6.0")

CPMAddPackage(
  NAME fmt
  GIT_TAG 7.1.3
  GITHUB_REPOSITORY fmtlib/fmt
  OPTIONS "FMT_INSTALL YES" # create an installable target
)
CPMAddPackage(
  NAME SDL2
  VERSION 2.0.12
  URL https://libsdl.org/release/SDL2-2.0.16.zip
)
CPMAddPackage(
  NAME glm
  GITHUB_REPOSITORY g-truc/glm
  OPTIONS "GLM_STATIC_LIBRARY_ENABLE"
  GIT_TAG 0.9.9.8
)

CPMAddPackage(
  NAME spdlog
  GITHUB_REPOSITORY gabime/spdlog
  OPTIONS "SPDLOG_INSTALL YES"
  GIT_TAG v1.9.2
)

# GLFW
CPMAddPackage(
  NAME glfw
  GITHUB_REPOSITORY glfw/glfw
  GIT_TAG 3.3.2
  OPTIONS
	"GLFW_BUILD_TESTS Off"
	"GLFW_BUILD_EXAMPLES Off"
	"GLFW_BUILD_DOCS Off"
    "GLFW_INSTALL Off"
    "GLFW_USE_HYBRID_HPG On"
)

# ---- Add source files ----

# Note: globbing sources is considered bad practice as CMake's generators may not detect new files
# automatically. Keep that in mind when changing files, or explicitly mention them here.
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")

# ---- Create library ----

# Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface
# target: add_library(ArcaneLords INTERFACE)
add_library(ArcaneLords ${headers} ${sources})

set_target_properties(ArcaneLords PROPERTIES CXX_STANDARD 17)

# being a cross-platform target, we enforce standards conformance on MSVC
target_compile_options(ArcaneLords PUBLIC "$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/permissive->")

# Link dependencies
target_link_libraries(ArcaneLords PRIVATE ${SDL2_LIBRARIES} ${GLEW_LIBRARIES} fmt::fmt OpenGL32 spdlog::spdlog)

target_include_directories(
    ArcaneLords PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
                 $<INSTALL_INTERFACE:include/${PROJECT_NAME}-${PROJECT_VERSION}>
)

# ---- Create an installable target ----
# this allows users to install and find the library via `find_package()`.

# the location where the project's version header will be placed should match the project's regular
# header paths
string(TOLOWER ${PROJECT_NAME}}/version.h VERSION_HEADER_LOCATION)

packageProject(
  NAME ${PROJECT_NAME}
  VERSION ${PROJECT_VERSION}
  NAMESPACE ${PROJECT_NAME}
  BINARY_DIR ${PROJECT_BINARY_DIR}
  INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
  INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
  VERSION_HEADER "${PROJECT_NAME}version.h"
  EXPORT_HEADER "${PROJECT_NAME}/source/export.h"
  COMPATIBILITY SameMajorVersion
  DEPENDENCIES "fmt 7.1.3"; "SDL2"; "glm"; "spdlog"
)

NOTE: spdlog v1.9.2 expects fmt v8.0.1

see gabime/spdlog@b83106b

Thank you, I did not see that! I still have the problem that the includes to the libraries seem to be broken.

I think this is related to CPM, because I was able to fix the SDL include issue.

if (SDL2_ADDED)
  add_library(SDL2::SDL2 ALIAS SDL2)
endif()

I think this is related to CPM, because I was able to fix the SDL include issue.

why not use the git repo link instead of the tar file? see
https://github.com/libsdl-org/SDL/blob/0e294e90ae6953777cc78b5d09dd5c8966dc96ab/CMakeLists.txt#L2639

That seems to work, I still cannot figure out glew, spdlog and glm.

cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

# ---- Project ----

# Note: update this to your new project's name and version
project(
  Arcanelords
  VERSION 0.1
  LANGUAGES CXX
)


set(OpenGL_GL_PREFERENCE "GLVND")


# ---- Include guards ----

if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
  message(
    FATAL_ERROR
      "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
  )
endif()

# ---- Add dependencies via CPM ----
# see https://github.com/TheLartians/CPM.cmake for more info

include(cmake/CPM.cmake)

# PackageProject.cmake will be used to make our target installable
CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.6.0")

CPMAddPackage(
  NAME fmt
  GIT_TAG 8.0.1
  GITHUB_REPOSITORY fmtlib/fmt
  OPTIONS "FMT_INSTALL YES" # create an installable target
)

CPMAddPackage(
  NAME SDL2
  GIT_TAG release-2.0.16
  GITHUB_REPOSITORY libsdl-org/SDL
)

CPMAddPackage(
  NAME glm
  GITHUB_REPOSITORY g-truc/glm
  OPTIONS "GLM_STATIC_LIBRARY_ENABLE"
  GIT_TAG 0.9.9.8
)

CPMAddPackage(
  NAME spdlog
  GITHUB_REPOSITORY gabime/spdlog
  OPTIONS "SPDLOG_INSTALL YES"
  "SPDLOG_FMT_EXTERNAL YES"
  GIT_TAG v1.9.2
)

# GLFW
CPMAddPackage(
  NAME glew
  GITHUB_REPOSITORY nigels-com/glew
  GIT_TAG glew-2.2.0
  OPTIONS "GLEW_STATIC"
  "CMAKE_INSTALL_PREFIX"
)

CPMAddPackage(
  NAME EnTT
  VERSION 3.8.1
  GITHUB_REPOSITORY skypjack/entt
)

# ---- Add source files ----

# Note: globbing sources is considered bad practice as CMake's generators may not detect new files
# automatically. Keep that in mind when changing files, or explicitly mention them here.
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")

# ---- Create library ----

# Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface
# target: add_library(ArcaneLords INTERFACE)
add_library(Arcanelords ${headers} ${sources})

set_target_properties(Arcanelords PROPERTIES CXX_STANDARD 17)

# being a cross-platform target, we enforce standards conformance on MSVC
target_compile_options(Arcanelords PUBLIC "$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/permissive->")

# Link dependencies
target_link_libraries(Arcanelords PRIVATE SDL2 glew fmt::fmt OpenGL32 spdlog::spdlog EnTT)

target_include_directories(
  Arcanelords PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
                 $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src>
                 $<INSTALL_INTERFACE:include/${PROJECT_NAME}-${PROJECT_VERSION}>
)

# ---- Create an installable target ----
# this allows users to install and find the library via `find_package()`.

# the location where the project's version header will be placed should match the project's regular
# header paths
string(TOLOWER ${PROJECT_NAME}}/version.h VERSION_HEADER_LOCATION)

packageProject(
  NAME ${PROJECT_NAME}
  VERSION ${PROJECT_VERSION}
  NAMESPACE ${PROJECT_NAME}
  BINARY_DIR ${PROJECT_BINARY_DIR}
  INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
  INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
  VERSION_HEADER "${PROJECT_NAME}version.h"
  EXPORT_HEADER "${PROJECT_NAME}/source/export.h"
  COMPATIBILITY SameMajorVersion
  DEPENDENCIES "fmt 8.0.1"; "SDL2 2.0.12"; "glm 0.9.9.8"; "spdlog 1.9.2"; "entt"
)

Spdlog seems to work now, just GLM and glew has issues. I use #include <GL/glew.h> and #include <glm/glm.hpp>.

What du you want With empty Option CMAKE_INSTALL_PREFIX

Nothing, I don't get what I miss for GLM and Glew to work.

Do glm and glew provide CMake targets? It seems that the CMake support for Glew is community based and is not in the root directory. I think you would need to manually add targets that include the GLEW libraries and the include directories for this work properly. The same goes for glm

Do glm and glew provide CMake targets? It seems that the CMake support for Glew is community based and is not in the root directory. I think you would need to manually add targets that include the GLEW libraries and the include directories for this work properly. The same goes for glm

HINT: use the SOURCE_SUBDIR options of CPMAddPackage()

This build and install the targets on my iMac, but the exported SDL CMake config package is NOT usable!

cmake_minimum_required(VERSION 3.14...3.26 FATAL_ERROR)

# ---- Project ----

# Note: update this to your new project's name and version
project(
  Arcanelords
  VERSION 0.1
  LANGUAGES CXX
)

set(OpenGL_GL_PREFERENCE "GLVND")

# ---- Include guards ----

if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
  message(
    FATAL_ERROR
      "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
  )
endif()

# ---- Add dependencies via CPM ----
# see https://github.com/TheLartians/CPM.cmake for more info

include(cmake/CPM.cmake)

# PackageProject.cmake will be used to make our target installable
CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.6.0")

CPMAddPackage(
  NAME fmt
  GIT_TAG 8.0.1
  GITHUB_REPOSITORY fmtlib/fmt
  OPTIONS "FMT_INSTALL YES" # create an installable target
)

CPMAddPackage(
  NAME SDL2
  GIT_TAG release-2.0.16
  GITHUB_REPOSITORY libsdl-org/SDL
)

CPMAddPackage(
  NAME glm
  GITHUB_REPOSITORY g-truc/glm
  GIT_TAG 0.9.9.8
  SOURCE_SUBDIR glm
  OPTIONS "GLM_STATIC_LIBRARY_ENABLE"
)

CPMAddPackage(
  NAME spdlog
  GITHUB_REPOSITORY gabime/spdlog
  GIT_TAG v1.9.2
  OPTIONS "SPDLOG_INSTALL YES" "SPDLOG_FMT_EXTERNAL YES"
)

# GLFW
CPMAddPackage(
  NAME glew
  GITHUB_REPOSITORY nigels-com/glew
  GIT_TAG glew-2.2.0
  SOURCE_SUBDIR glew
  OPTIONS "GLEW_STATIC YES"
  # XXX "CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}"
)

CPMAddPackage(
  NAME EnTT
  VERSION 3.8.1
  GITHUB_REPOSITORY skypjack/entt
)

# ---- Add source files ----

# Note: globbing sources is considered bad practice as CMake's generators may not detect new files
# automatically. Keep that in mind when changing files, or explicitly mention them here.
# XXX file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
# XXX file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")

# ---- Create library ----

# Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface
# target:
add_library(${PROJECT_NAME} INTERFACE)
# XXX add_library(${PROJECT_NAME} ${headers} ${sources})

set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17)

# being a cross-platform target, we enforce standards conformance on MSVC
target_compile_options(${PROJECT_NAME} INTERFACE "$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/permissive->")

# Link dependencies
target_link_libraries(${PROJECT_NAME} INTERFACE SDL2 glew fmt::fmt OpenGL32 spdlog::spdlog EnTT)

target_include_directories(
  ${PROJECT_NAME}
  INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
            #FIXME: $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src>
            $<INSTALL_INTERFACE:include/${PROJECT_NAME}-${PROJECT_VERSION}>
)

# ---- Create an installable target ----
# this allows users to install and find the library via `find_package()`.

# the location where the project's version header will be placed should match the project's regular
# header paths
string(TOLOWER ${PROJECT_NAME}}/version.h VERSION_HEADER_LOCATION)

packageProject(
  NAME ${PROJECT_NAME}
  VERSION ${PROJECT_VERSION}
  NAMESPACE ${PROJECT_NAME}
  BINARY_DIR ${PROJECT_BINARY_DIR}
  INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
  INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
  VERSION_HEADER "${PROJECT_NAME}version.h"
  EXPORT_HEADER "${PROJECT_NAME}/source/export.h"
  COMPATIBILITY SameMajorVersion
  DEPENDENCIES "fmt 8.0" "SDL2 2.0" "glm 0.9" "spdlog 1.9" "entt 3.8"
)
tree ../stagedir/lib/cmake/
../stagedir/lib/cmake/
|-- Arcanelords-0.1
|   |-- ArcanelordsConfig.cmake
|   |-- ArcanelordsConfigVersion.cmake
|   `-- ArcanelordsTargets.cmake
|-- SDL2
|   |-- SDL2Config.cmake
|   |-- SDL2ConfigVersion.cmake
|   |-- SDL2Targets-debug.cmake
|   `-- SDL2Targets.cmake
|-- fmt
|   |-- fmt-config-version.cmake
|   |-- fmt-config.cmake
|   |-- fmt-targets-debug.cmake
|   `-- fmt-targets.cmake
`-- spdlog
    |-- spdlogConfig.cmake
    |-- spdlogConfigTargets-debug.cmake
    |-- spdlogConfigTargets.cmake
    `-- spdlogConfigVersion.cmake

5 directories, 15 files