使用 CMake 在 Mac 上链接静态 GLFW 和 OpenGL

Posted

技术标签:

【中文标题】使用 CMake 在 Mac 上链接静态 GLFW 和 OpenGL【英文标题】:Linking Static GLFW and OpenGL on a Mac with CMake 【发布时间】:2018-06-07 04:22:58 【问题描述】:

我正在尝试在 mac 上测试 glfw3。我无法构建一个简单的项目,因为我无法链接到 OpenGL。

目录结构

├── CMakeLists.txt
├── OpenGL
│   ├── Application.cpp
│   ├── CMakeLists.txt
│   └── dependencies
│       └── GLFW
│           ├── include
│           │   └── GLFW
│           │       ├── glfw3.h
│           │       └── glfw3native.h
│           ├── lib
│           │   └── libglfw3.a
│           └── src
└── bin

CMakeList.txt

*** CMakeList.txt

cmake_minimum_required(VERSION 3.11)

set(CMAKE_CXX_STANDARD 17)
set(EXECUTABLE_OUTPUT_PATH $PROJECT_SOURCE_DIR/bin)

add_subdirectory(OpenGL)

嵌套的 CMakeList.txt

cmake_minimum_required(VERSION 3.11)
project(OpenGL)

find_package(OpenGL REQUIRED)

add_executable(OpenGL Application.cpp)

target_include_directories(OpenGL PUBLIC $CMAKE_CURRENT_SOURCE_DIR/dependencies/GLFW/include)
target_link_libraries(OpenGL $OPENGL_LIBRARIES $CMAKE_CURRENT_SOURCE_DIR/dependencies/GLFW/lib/libglfw3.a)

Applicatin.cpp(直接取自glfw.org here)

#include <iostream>
#include <GLFW/glfw3.h>

int main()

    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", nullptr, nullptr);
    if (!window)
    
        glfwTerminate();
        return -1;
    

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT); <-- this line throws an error

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    

    glfwTerminate();
    return 0;

错误信息

make[3]: *** No rule to make target '../OpenGL/dependencies/GLFW/include/lib/libglfw3.a', needed by '../bin/OpenGL'.  Stop.
make[3]: *** Waiting for unfinished jobs....
[ 50%] Building CXX object OpenGL/CMakeFiles/OpenGL.dir/Application.cpp.o
/Users/dblock/CLionProjects/OpenGL/OpenGL/Application.cpp:27:17: error: use of undeclared identifier 'GL_COLOR_BUFFER_BIT'
        glClear(GL_COLOR_BUFFER_BIT);
                ^
1 error generated.
make[3]: *** [OpenGL/CMakeFiles/OpenGL.dir/build.make:63: OpenGL/CMakeFiles/OpenGL.dir/Application.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:86: OpenGL/CMakeFiles/OpenGL.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:98: OpenGL/CMakeFiles/OpenGL.dir/rule] Error 2
make: *** [Makefile:118: OpenGL] Error 2

我的 IDE (CLion) 显示以下内容

Can't resolve variable 'glClear'
Can't resolve variable 'GL_COLOR_BUFFER_BIT'

请告诉我哪里出错了。

编辑

我添加了#import,但现在出现了一个新错误

/usr/local/Cellar/cmake/3.11.1/bin/cmake --build /Users/dblock/CLionProjects/OpenGL/cmake-build-debug --target OpenGL -- -j 4
make[3]: *** No rule to make target '../OpenGL/dependencies/GLFW/include/lib/libglfw3.a', needed by '../bin/OpenGL'.  Stop.
make[2]: *** [CMakeFiles/Makefile2:86: OpenGL/CMakeFiles/OpenGL.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:98: OpenGL/CMakeFiles/OpenGL.dir/rule] Error 2
make: *** [Makefile:118: OpenGL] Error 2

解决方案

#include <OpenGL/gl.h> //<-- add this included to main.cpp fixed my issue

【问题讨论】:

您的项目中没有文件OpenGL/dependencies/GLFW/include/lib/libglfw3.a。你有OpenGL/dependencies/GLFW/lib/libglfw3.a 一个。顺便说一句,为什么使用find_package(OpenGL) 而不使用它的结果? @Tsyvarev 答案是我对 c++ 和 CMake 都是新手。我正在犯我没有注意到的菜鸟错误。请详细说明如何纠正我的错误。 如果你真的使用#import而不是#include来包含OpenGL头,那肯定是不正确的。 @SeanBurton Id 宁愿做正确的事。我发现这是一个可能的解决方案,所以我尝试了它。我现在正在删除它,请告知链接 OpenGL 的正确方法 您需要使用 GL 加载器,例如 glad 【参考方案1】:

IDE 明确指出没有找到 glClearGL_COLOR_BUFFER_BIT 的声明

由于 OpenGL 是一种标准/规范,因此由驱动程序制造商将规范实施到特定显卡支持的驱动程序。由于OpenGL驱动有很多不同的版本,其大部分函数的位置在编译时是未知的,需要在运行时查询。然后,开发人员的任务是检索他/她需要的函数的位置并将它们存储在函数指针中以供以后使用。

您需要声明 OpenGL 函数的标头和加载这些函数的加载器。值得庆幸的是,还有一些用于此目的的库,其中 GLAD 是一个流行且最新的库。

生成 GLAD 加载器/标题 - http://glad.dav1d.de。

更新目录结构:

├── CMakeLists.txt
├── OpenGL
│   ├── Application.cpp
│   ├── CMakeLists.txt
│   ├── glad.c
│   └── dependencies
│       ├── GLFW
│       │   └── ...
│       ├── glad
│       │   └── glad.h
│       └── KHR
│           └── khrplatform.h
└── bin

更新嵌套的 CMakeList.txt:

set(SOURCES Application.cpp glad.c)
add_executable(OpenGL $SOURCES)
target_include_directories(OpenGL PUBLIC $CMAKE_CURRENT_SOURCE_DIR/dependencies)

更新Applicin.cpp:

#include <glad/glad.h>
#include <GLFW/glfw3.h>
...

glfwMakeContextCurrent(window);

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
 
  // Failed to create GLFW window
  glfwTerminate();
  return -1;

// now you can use OpenGL functions

更多信息在 GLAD github,完成 example。优秀的 OpenGL tutorials.

【讨论】:

感谢您提供的信息。这非常有帮助,因为它是我正在尝试做的下一步。但是,如果有人遇到我的问题。以下导入解决了我的问题。 #include 【参考方案2】:

我怀疑 cmake 解析到的相对路径不正确(不存在)。 我建议你像这样从HomeBrew 安装 glfw3:

brew install --static glfw3

并指定glfw3的绝对路径为“/usr/local/lib”

【讨论】:

谢谢你让我意识到我走错了路。复制和粘贴有时会成为我最好的。我会考虑使用 brew 安装一个选项。但是,由于我更正了路径,因此出现了新错误。知道我的新错误是什么吗?

以上是关于使用 CMake 在 Mac 上链接静态 GLFW 和 OpenGL的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Mac OS X 上链接静态库

在 Mac 上使用 CMake 的 GLFW

CMake 生成的程序无法在 Windows 上链接:尝试链接到不存在的文件

Mac 上的 GLFW 环境配置

C++ Singleton 无法在 Mac OS 上链接

libpng 未在 Mac OSX 10.9.2 上链接