我有两个带有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
如果使用基于目录属性,如include_directory
或link_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)