简体   繁体   中英

OpenGL extensions not linking on Windows

I'm trying to link OpenGL to an application for Windows (building on Windows).

I'm using Conan as package manager, CMake for building and MSVC as compiler (and CLion as IDE).

The program compiles, but I have linker errors, for what I believe to be extension functions in 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

I think I've been around the entire internet searching for a solution, but I fail to understand what's missing. My hunch is currently that OpenGL extensions are not linked (being an OpenGL rookie, I'm not 100% sure what that even means).

I'm compiling with GL_GLEXT_PROTOTYPES=1 .

This is the linker command being executed:

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

I have tried:

  • Using mingw (results in same linker errors)
  • Adding GLEW
  • Using shared SDL2 lib
  • Finding a glext.lib x64 version (not sure it exists or needed)

This is my 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)

I'm compiling with GL_GLEXT_PROTOTYPES=1 .

Well, don't do that. That is never going to work in a portable way. On windows, the opengl32.dll always exports only the functions which are in OpenGL 1.1, and for everything beyond that, you have to rely to the OpenGL extension loading mechanism at runtime .

I have tried:

  • [...]
  • Adding GLEW

That's a step in the right direction. But this does not make things to magically work. A GL loader like GLEW typically brings its own header as a replacement for GL.h and glext.h etc., and the typical GL loader (like GLEW) simply re-define every GL functions as a macro, like this:

#define glFooFunc() __myloader_FooFunc

where __myloader_FooFunc is just a function pointer which must be initialized with some function provided by your loader (like glewInit ).

Now this has a few effects: If you include the GL loader's header in some source file, the preprocessor will already replace all glSomething function names, and the linker will never see them. But that is only true in that particular source file. If you have another source file without the loader header, the actual GL function names are used, and the linker will not find them.

From your error messages like:

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)

it is easy to see that the function ImGui_ImplOpenGL3_SetupRenderState was not compiled with a GL loader, but used the GL function names directly.

Since ImGui supports OpenGL backends, it has already a way to deal with this, look at the official 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() [...]

So if you want to use ImGui with GLEW, you'll have to use IMGUI_IMPL_OPENGL_LOADER_GLEW

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM