提问者:小点点

CMake找不到git子模块的头文件


我有两个带有CMake的git存储库,一个是游戏引擎,另一个是我正在用游戏引擎制作的游戏。

原来,这个游戏引擎有一个子模块包含在项目的cmakelists.txt中,而在游戏存储库中,游戏引擎被添加为一个子模块,也包含在cmakelists.txt中。但是在编译两个项目的时候,游戏引擎编译一切正常,没有错误,我更新游戏知识库更新子模块,而在编译游戏的时候,不知什么原因没有找到游戏引擎子模块。

游戏引擎CMakelists:

cmake_minimum_required(VERSION 3.8)

set(PROJECT_NAME "Enel")

set(CMAKE_CXX_STANDARD 17)

project(${PROJECT_NAME} VERSION 0.1.0)

include_directories(
    "${PROJECT_SOURCE_DIR}/include"
    "${PROJECT_SOURCE_DIR}/src"
    "${PROJECT_SOURCE_DIR}/libs/spdlog/include"
    "${PROJECT_SOURCE_DIR}/libs/spdlog/src"
)

file(GLOB SRC_FILES
    "${PROJECT_SOURCE_DIR}/include/**/*.h"
    "${PROJECT_SOURCE_DIR}/include/**/*.hh"
    "${PROJECT_SOURCE_DIR}/include/**/*.hpp"
    "${PROJECT_SOURCE_DIR}/src/**/*.c"
    "${PROJECT_SOURCE_DIR}/src/**/*.cc"
    "${PROJECT_SOURCE_DIR}/src/**/*.cpp"
)

add_library(${PROJECT_NAME} STATIC ${SRC_FILES})

游戏玩家:

cmake_minimum_required(VERSION 3.8)

set(PROJECT_NAME "Minicraft")

set(CMAKE_CXX_STANDARD 17)

project(${PROJECT_NAME} VERSION 0.1.0)

include_directories(
    "${PROJECT_SOURCE_DIR}/include"
    "${PROJECT_SOURCE_DIR}/src"
    "${PROJECT_SOURCE_DIR}/libs/enel/include"
    "${PROJECT_SOURCE_DIR}/libs/enel/src"
)

link_directories(${PROJECT_SOURCE_DIR}/libs/enel)

file(GLOB SRC_FILES
    "${PROJECT_SOURCE_DIR}/include/**/*.h"
    "${PROJECT_SOURCE_DIR}/include/**/*.hh"
    "${PROJECT_SOURCE_DIR}/include/**/*.hpp"
    "${PROJECT_SOURCE_DIR}/src/**/*.c"
    "${PROJECT_SOURCE_DIR}/src/**/*.cc"
    "${PROJECT_SOURCE_DIR}/src/**/*.cpp"
    "${PROJECT_SOURCE_DIR}/libs/enel/src/**/*.c"
    "${PROJECT_SOURCE_DIR}/libs/enel/src/**/*.cc"
    "${PROJECT_SOURCE_DIR}/libs/enel/src/**/*.cpp"
    "${PROJECT_SOURCE_DIR}/libs/enel/include/**/*.h"
    "${PROJECT_SOURCE_DIR}/libs/enel/include/**/*.hh"
    "${PROJECT_SOURCE_DIR}/libs/enel/include/**/*.hpp"
)

add_executable(${PROJECT_NAME} ${SRC_FILES})

生成输出:

[ 33%] Building CXX object CMakeFiles/Minicraft.dir/src/MC/Game.cc.o
In file included from /home/yorichii/repos/minicraft/libs/enel/include/Enel/Platform/EntryPoint.hh:4,
                 from /home/yorichii/repos/minicraft/src/MC/Game.cc:2:
/home/yorichii/repos/minicraft/libs/enel/include/Enel/Util/Log.hh:3:10: fatal error: spdlog/spdlog.h: Arquivo ou diretório inexistente
    3 | #include <spdlog/spdlog.h>
      |          ^~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/Minicraft.dir/build.make:76: CMakeFiles/Minicraft.dir/src/MC/Game.cc.o] Erro 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/Minicraft.dir/all] Erro 2
make: *** [Makefile:84: all] Erro 2

共1个答案

匿名用户

如果使用基于目录属性,如include_directorylink_directory,则必须重复以下要求:

include_directories(
    "${PROJECT_SOURCE_DIR}/include"
    "${PROJECT_SOURCE_DIR}/src"
    "${PROJECT_SOURCE_DIR}/libs/enel/include"
    "${PROJECT_SOURCE_DIR}/libs/enel/src"
    # Repeat all requirements
    "${PROJECT_SOURCE_DIR}/libs/enel/libs/spdlog/include"
    "${PROJECT_SOURCE_DIR}/libs/enel/libs/spdlog/src"
)

这就是为什么您应该强烈考虑基于目标的属性,因为所有现代构建系统都在使用,包括现代CMAKE:

以Enel表示:

cmake_minimum_required(VERSION 3.8)

set(PROJECT_NAME "Enel")

set(CMAKE_CXX_STANDARD 17)

project(${PROJECT_NAME} VERSION 0.1.0)

# If you can install spdlog in a local directory in the project,
# prefer find_package(spdlog REQUIRED)
add_subdirectrory(libs/spdlog)

file(GLOB SRC_FILES
    "strongly/consider/not/globbing/**/*.cpp"
)

add_library(Enel STATIC ${SRC_FILES})

target_link_libraries(Enel PUBLIC spdlog)
target_include_directories(Enel PUBLIC src include)

然后在你的游戏中,这样做:

cmake_minimum_required(VERSION 3.8)

set(PROJECT_NAME "Minicraft")

set(CMAKE_CXX_STANDARD 17)

project(${PROJECT_NAME} VERSION 0.1.0)

add_subdirectory(libs/enel)

file(GLOB SRC_FILES
   ...
)

add_executable(Minicraft ${SRC_FILES})

# Links to all required libraries, add all required include directories
target_link_libraries(Minicraft PUBLIC Enel)
target_include_directory(Minicraft PUBLIC include src)