TheLartians / ModernCppStarter

🚀 Kick-start your C++! A template for modern C++ projects using CMake, CI, code coverage, clang-format, reproducible dependency management and much more.
https://thelartians.github.io/ModernCppStarter
The Unlicense
4.33k stars 381 forks source link

Include errors #142

Open shelltitan opened 2 years ago

shelltitan commented 2 years ago

I tried to add multiple libraries to this template project, but all my library includes seem to be failing (eg: #include ). 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"
)
ClausKlein commented 2 years ago

NOTE: spdlog v1.9.2 expects fmt v8.0.1

see https://github.com/gabime/spdlog/commit/b83106bed4af1a1ffa67abc2ac6c31422d3c8e5d

shelltitan commented 2 years ago

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

shelltitan commented 2 years ago

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()
ClausKlein commented 2 years ago

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

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

shelltitan commented 2 years ago

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"
)
ClausKlein commented 2 years ago

I dit it here the same way: https://github.com/ClausKlein/cxx.simplelog/blob/73365bd126ca49ab7bd02e2bd53738f296cdb83a/CMakeLists.txt#L74

shelltitan commented 2 years ago

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

ClausKlein commented 2 years ago

What du you want With empty Option CMAKE_INSTALL_PREFIX

shelltitan commented 2 years ago

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

DeveloperPaul123 commented 1 year ago

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

ClausKlein commented 1 year ago

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()

ClausKlein commented 1 year ago

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"
)
ClausKlein commented 1 year ago
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