【问题标题】:OpenGL extensions not linking on WindowsOpenGL 扩展未在 Windows 上链接
【发布时间】:2021-08-27 12:14:30
【问题描述】:

我正在尝试将 OpenGL 链接到适用于 Windows 的应用程序(在 Windows 上构建)。

我使用 Conan 作为包管理器,使用 CMake 进行构建,使用 MSVC 作为编译器(以及使用 CLion 作为 IDE)。

程序可以编译,但我有链接器错误,我认为这是 OpenGL 中的扩展函数:

imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBlendEquation referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glActiveTexture referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBlendFuncSeparate referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBindBuffer referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glDeleteBuffers referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGenBuffers referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBufferData referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBlendEquationSeparate referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glAttachShader referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glCompileShader referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glCreateProgram referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glCreateShader referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glDeleteProgram referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glDeleteShader referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glDetachShader referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glEnableVertexAttribArray referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetAttribLocation referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetProgramiv referenced in function "bool __cdecl CheckProgram(unsigned int,char const *)" (?CheckProgram@@YA_NIPEBD@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetProgramInfoLog referenced in function "bool __cdecl CheckProgram(unsigned int,char const *)" (?CheckProgram@@YA_NIPEBD@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetShaderiv referenced in function "bool __cdecl CheckShader(unsigned int,char const *)" (?CheckShader@@YA_NIPEBD@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetShaderInfoLog referenced in function "bool __cdecl CheckShader(unsigned int,char const *)" (?CheckShader@@YA_NIPEBD@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetUniformLocation referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glLinkProgram referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glShaderSource referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glUseProgram referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glUniform1i referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glUniformMatrix4fv referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glVertexAttribPointer referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGetStringi referenced in function "bool __cdecl ImGui_ImplOpenGL3_Init(char const *)" (?ImGui_ImplOpenGL3_Init@@YA_NPEBD@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBindVertexArray referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glDeleteVertexArrays referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glGenVertexArrays referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glDrawElementsBaseVertex referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBindSampler referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z)
soundstate.exe : fatal error LNK1120: 34 unresolved externals

我想我一直在整个互联网上寻找解决方案,但我不明白缺少什么。我的直觉是目前没有链接 OpenGL 扩展(作为 OpenGL 新手,我不能 100% 确定这意味着什么)。

我正在使用GL_GLEXT_PROTOTYPES=1进行编译。

这是正在执行的链接器命令:

C:\PROGRA~2\MIB055~1\2019\COMMUN~1\VC\Tools\MSVC\1429~1.300\bin\Hostx86\x64\link.exe /nologo @CMakeFiles\soundstate.dir\objects1.rsp /out:soundstate.exe /implib:soundstate.lib /pdb:<project dir>\cmake-build-debug\soundstate.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console core.lib ..\vendor\fmod\windows\lib\x64\fmodL_vc.lib <user dir>\.conan\data\imgui-docking\1.83\trololo\stable\package\846e49ae2c2d7b4448ca2380ea2b4c7a382d695b\lib\imgui.lib <user dir>\.conan\data\sdl2\2.0.14\bincrafters\stable\package\a5e24820448cb570d848a2e59f317dd7edebe889\lib\SDL2maind.lib <user dir>\.conan\data\sdl2\2.0.14\bincrafters\stable\package\a5e24820448cb570d848a2e59f317dd7edebe889\lib\SDL2d.lib user32.lib gdi32.lib winmm.lib imm32.lib ole32.lib oleaut32.lib version.lib uuid.lib advapi32.lib setupapi.lib shell32.lib <user dir>\.conan\data\libiconv\1.16\_\_\package\d057732059ea44a47760900cb5e4855d2bea8714\lib\iconv.lib C:\Users\simon\.conan\data\libiconv\1.16\_\_\package\d057732059ea44a47760900cb5e4855d2bea8714\lib\charset.lib <user dir>\.conan\data\glew\2.2.0\_\_\package\2cd10aa7b17419a389740c9a9a85afec1178e5cf\lib\libglew32d.lib opengl32.lib Glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\soundstate.dir/intermediate.manifest CMakeFiles\soundstate.dir/manifest.res

我试过了:

  • 使用 mingw(导致相同的链接器错误)
  • 添加 GLEW
  • 使用共享 SDL2 库
  • 查找 glext.lib x64 版本(不确定是否存在或需要)

这是我的 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(soundstate C CXX)
set(CMAKE_CXX_STANDARD 17)

set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})

find_package(imgui REQUIRED CONFIG)
find_package(SDL2 REQUIRED CONFIG)
find_package(immer REQUIRED CONFIG)
find_package(cereal REQUIRED CONFIG)
find_package(Boost REQUIRED CONFIG)
find_package(rxcpp REQUIRED CONFIG)
find_package(range-v3 REQUIRED CONFIG)
find_package(opengl_system REQUIRED CONFIG)
find_package(glew REQUIRED CONFIG)

#
# FMOD
#
set(CMAKE_VERBOSE_MAKEFILE ON)
if (WIN32)
    add_library(fmod STATIC IMPORTED)
    set_target_properties(fmod PROPERTIES
            LINKER_LANGUAGE C
            INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/fmod/linux/inc
            IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/vendor/fmod/windows/lib/x64/fmodL_vc.lib
            )
else ()
    file(COPY vendor/fmod/linux/lib/x86_64/libfmodL.so.12.9 DESTINATION ${CMAKE_BINARY_DIR}/resources/lib)
    set_target_properties(fmod PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/resources/lib/libfmodL.so)
endif ()

#
# Core
#
set(CORE_SOURCES
        core/model.h
        core/actions.h
        core/reducers.h
        core/utils.h core/utils.cpp
        core/reducers.cpp
        core/cursors.h core/cursors.cpp
        core/io.cpp core/io.h
        core/serialization.h
        core/audio/audio_engine.cpp core/audio/audio_engine.h
        core/audio/audio_context.cpp core/audio/audio_context.h)

add_library(core STATIC ${CORE_SOURCES})

target_include_directories(core PUBLIC include)
target_include_directories(core PUBLIC ${CONAN_INCLUDE_DIRS})

set(CORE_LIBS
        immer::immer
        cereal::cereal
        Boost::Boost
        rxcpp::rxcpp
        range-v3::range-v3
        )

set(ALL_LIBS
        imgui::imgui
        SDL2::SDL2
        immer::immer
        cereal::cereal
        Boost::Boost
        rxcpp::rxcpp
        range-v3::range-v3
        opengl::opengl
        GLEW::GLEW
        )

target_link_libraries(core fmod ${CORE_LIBS})


#
# Main
#
set(SOURCES
        ui/imgui/main.cpp
        ui/imgui/panels/panel.cpp ui/imgui/panels/panel.h
        ui/imgui/panels/playables_tree_panel.cpp ui/imgui/panels/playables_tree_panel.h
        ui/imgui/gui_manager.cpp ui/imgui/gui_manager.h
        ui/imgui/panels/playable_editor_panel.cpp ui/imgui/panels/playable_editor_panel.h
        ui/imgui/editors/editor.cpp ui/imgui/editors/editor.h
        ui/imgui/editors/file_playable_editor.cpp ui/imgui/editors/file_playable_editor.h
        ui/imgui/editors/list_playable_editor.cpp ui/imgui/editors/list_playable_editor.h
        ui/imgui/editors/state_editor.cpp ui/imgui/editors/state_editor.h
        ui/imgui/editors/state_option_editor.cpp ui/imgui/editors/state_option_editor.h
        ui/imgui/imgui_extras.h
        ui/imgui/icons_fa5.h
        include/ImGuiFileDialog/ImGuiFileDialog.cpp
        ui/imgui/panels/state_list_panel.cpp
        ui/imgui/panels/state_list_panel.h
        ui/imgui/panels/debug_panel.cpp
        ui/imgui/panels/debug_panel.h
        ui/imgui/panels/controls_panel.cpp
        ui/imgui/panels/controls_panel.h
        bindings/imgui_impl_opengl3.h
        bindings/imgui_impl_opengl3.cpp
        bindings/imgui_impl_sdl.h
        bindings/imgui_impl_sdl.cpp
        bindings/imgui_stdlib.h
        bindings/imgui_stdlib.cpp
        )

add_executable(soundstate ${SOURCES})

target_include_directories(soundstate PUBLIC vendor)
# Configure Imgui to use OpengGL through SDL2
target_compile_definitions(soundstate PUBLIC IMGUI_IMPL_OPENGL_LOADER_CUSTOM=<SDL_opengl.h> GL_GLEXT_PROTOTYPES=1)
target_link_libraries(soundstate core ${ALL_LIBS})

# Copy resources
file(COPY resources/fonts/Roboto-Regular.ttf DESTINATION ${CMAKE_BINARY_DIR}/resources/fonts)
file(COPY resources/fonts/fa-regular-400.ttf DESTINATION ${CMAKE_BINARY_DIR}/resources/fonts)
file(GLOB AUDIO_FILES resources/audio/*)
file(COPY ${AUDIO_FILES} DESTINATION ${CMAKE_BINARY_DIR}/resources/audio)
file(COPY vendor/fmod/windows/lib/x64/fmodL.dll DESTINATION ${CMAKE_BINARY_DIR}/resources/lib)
file(COPY vendor/fmod/windows/lib/x64/fmodL_vc.lib DESTINATION ${CMAKE_BINARY_DIR}/resources/lib)

【问题讨论】:

  • 显示使用你的 CMakeLists.txt,你可能没有链接一些你需要的库。
  • 好点,补充说

标签: c++ windows opengl cmake sdl-2


【解决方案1】:

我正在使用GL_GLEXT_PROTOTYPES=1 进行编译。

好吧,不要那样做。这永远不会以便携的方式工作。在 Windows 上,opengl32.dll always 仅导出 OpenGL 1.1 中的函数,除此之外,您必须依赖 OpenGL extension loading mechanism 运行时

我试过了:

  • [...]
  • 添加 GLEW

这是朝着正确方向迈出的一步。但这并不能使事情神奇地起作用。像 GLEW 这样的 GL 加载器通常会将其 自己的 标头作为 GL.hglext.h 等的 替换,而典型的 GL 加载器(如 GLEW)只需重新将每个 GL 函数定义为一个宏,如下所示:

#define glFooFunc() __myloader_FooFunc

其中__myloader_FooFunc 只是一个函数指针,必须使用加载程序提供的某些函数(如glewInit)对其进行初始化。

现在这有一些影响:如果您在某个源文件中包含 GL 加载器的标头,预处理器将已经替换所有 glSomething 函数名称,并且链接器将永远不会看到它们。但这仅在该特定源文件中是正确的。如果您有另一个没有加载程序头的源文件,则使用实际的 GL 函数名称,链接器将找不到它们。

来自您的错误消息,例如:

imgui_impl_opengl3.cpp.obj : error LNK2019: unresolved external symbol __imp_glBlendEquation referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z)

很容易看出函数ImGui_ImplOpenGL3_SetupRenderState不是用GL加载器编译的,而是直接使用了GL函数名。

由于ImGui支持OpenGL后端,已经有办法处理了,看官方examples:

// About Desktop OpenGL function loaders:
//  Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
//  Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
//  You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h>            // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h>            // Initialize with glewInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h>          // Initialize with gladLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
#include <glad/gl.h>            // Initialize with gladLoadGL(...) or gladLoaderLoadGL()
[...]

因此,如果您想在 GLEW 中使用 ImGui,则必须使用 IMGUI_IMPL_OPENGL_LOADER_GLEW

【讨论】:

  • 谢谢!使用IMGUI_IMPL_OPENGL_LOADER_GLEW 可以编译和链接程序,但会导致运行时错误。我也许可以解决这些问题,但我需要使用 SDL,因为应用程序的其他部分依赖于它。所以现在我很困惑我是否可以同时使用 GLEW 和 SDL?我之前使用的是IMGUI_IMPL_OPENGL_LOADER_CUSTOM=&lt;SDL_opengl.h&gt;,而不是 GLEW 加载器。
  • 如果您遇到运行时错误,您可能忘记初始化 GLEW,或者您的 GL 实现不支持该 ImGui 后端所需的功能。您可以随心所欲地使用 SDL,但 SDL_opengl.h 不会带您到任何地方。这只是GL.h /glext.h 的副本,没有任何加载机制,因此无论如何都需要用 GLEW 的标头替换。
  • 对,我在创建 opengl 上下文之前执行了glewInit。现在一切正常,非常感谢!几天来我一直在尝试调试它,这真是一种解脱:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 2012-07-13
  • 2012-06-04
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多