You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CMake正确链接GLAD/GLFW?子目录头文件引用失败求助

问题描述

折腾数日用CMake配置带OpenGL上下文的窗口,卡在路径引用问题上:src根目录可正常引用GLAD/GLFW,但子目录中无法引用。作为CMake新手,不清楚问题根源。

文件结构

├── CMakeLists.txt
├── README.md
├── build.sh
├── configure.sh
├── lib
│	└── external
│		├── glad
│		│	├── CMakeLists.txt
│		│	├── include
│		│	└── src
│		└── glfw
│			├── CMake
│			├── CMakeLists.txt
│			├── CONTRIBUTORS.md
│			├── LICENSE.md
│			├── README.md
│			├── deps
│			├── docs
│			├── examples
│			├── include
│			├── src
│			└── tests
├── run.sh
└── src
	├── CMakeLists.txt
	├── Engine
	│	├── CMakeLists.txt
	│	├── gameManager.cpp
	│	└── gameManager.h
	├── Entities
	├── RenderEngine
	│	├── CMakeLists.txt
	│	├── displayManager.cpp
	│	└── displayManager.h
	└── main.cpp

在displayManager.h中引用GLAD/GLFW时,报错:cannot open source file "glad/glad.h"和cannot open source file GLFW/glfw3.h。

现有CMake配置

顶层CMakeLists.txt

cmake_minimum_required(VERSION 3.25.0)
project(Opengl_tut VERSION 0.1.0)

# For loop add subdirectories
foreach (sub "src" "${GLFW_DIR}" "${GLAD_DIR}" "src/RenderEngine")
    add_subdirectory("${sub}")
endforeach ()

lib/external/glad/CMakeLists.txt

cmake_minimum_required(VERSION 3.25.0)
project(Glad)

add_library(glad include/glad/glad.h src/glad.c)
target_include_directories(glad PUBLIC include/)

lib/external/glfw/CMakeLists.txt

使用官方仓库的标准配置文件。

src/CMakeLists.txt

add_executable(${PROJECT_NAME} main.cpp)

# Get these files
target_link_libraries(${PROJECT_NAME}
    glfw
    glad
)

该配置可让main.cpp正常#include <glad/glad.h>和<GLFW/glfw3.h>,因此尝试给RenderEngine配置类似内容:

src/RenderEngine/CMakeLists.txt

add_library(displayManager "displayManager.cpp" "displayManager.h")

# Get these files
target_link_libraries(${PROJECT_NAME}
    glfw
    glad
)

需要解决的问题:

  1. 如何让displayManager.h识别GLAD/GLFW?
  2. 需在src/Engine/gameManager.h中#include "displayManager.h",是否适用相同方案?

解决方案

1. 修复RenderEngine的CMake配置

你当前src/RenderEngine/CMakeLists.txt中的target_link_libraries错误地使用了${PROJECT_NAME}(指向顶层项目Opengl_tut),正确做法是将依赖链接到displayManager库本身,并且使用PUBLIC关键字传递依赖:

add_library(displayManager "displayManager.cpp" "displayManager.h")

# 将glfw和glad链接到displayManager,PUBLIC确保依赖传递
target_link_libraries(displayManager
    PUBLIC glfw
    PUBLIC glad
)

PUBLIC的作用是:所有链接displayManager的目标(如主程序、gameManager)会自动继承GLFW和GLAD的包含路径,无需重复配置。

2. 主程序链接displayManager库

修改src/CMakeLists.txt,将displayManager链接到主可执行文件,确保主程序能调用displayManager的功能:

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME}
    glfw
    glad
    displayManager  # 添加该行
)

3. 处理gameManager引用displayManager的情况

对于gameManager.h引用displayManager.h的需求,遵循同样的依赖传递规则:

  • 修改src/Engine/CMakeLists.txt:
add_library(gameManager "gameManager.cpp" "gameManager.h")

# 链接displayManager,PUBLIC传递依赖
target_link_libraries(gameManager
    PUBLIC displayManager
)
  • 在src/CMakeLists.txt中把gameManager链接到主程序:
target_link_libraries(${PROJECT_NAME}
    glfw
    glad
    displayManager
    gameManager  # 添加该行
)

额外优化建议

顶层CMake的foreach循环可简化,改为由src目录的CMake管理子目录,结构更清晰:

  • 修改顶层CMakeLists.txt:
cmake_minimum_required(VERSION 3.25.0)
project(Opengl_tut VERSION 0.1.0)

# 先添加外部依赖
add_subdirectory(lib/external/glfw)
add_subdirectory(lib/external/glad)

# 添加src目录,子目录由src的CMake管理
add_subdirectory(src)
  • 在src/CMakeLists.txt中添加子目录:
# 管理src下的子模块
add_subdirectory(RenderEngine)
add_subdirectory(Engine)

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME}
    glfw
    glad
    displayManager
    gameManager
)

这种方式避免手动维护子目录列表,层级更合理。


内容的提问来源于stack exchange,提问作者ngurnard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 06:20:35