microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
23.16k stars 6.39k forks source link

Linking error with imgui[opengl3-glad-binding] #19231

Open ghost opened 3 years ago

ghost commented 3 years ago

Describe the bug Trying to build an executable with imgui[opengl3-glad-binding] leads to a linking error. As you can see in the log snippet below, for some reason the linker is looking for glew symbols instead of glad symbols. glew and imgui[opengl3-glew-binding] packages are not even installed.

Environment

To Reproduce The minimal example is as follows. main.cpp:

#include <glad/glad.h>
#include <imgui_impl_opengl3.h>

int main()
{
  ImGui_ImplOpenGL3_Init();
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.18)
project(hello)

find_package(glad CONFIG REQUIRED)
find_package(imgui CONFIG REQUIRED)

add_executable(hello main.cpp)
target_link_libraries(hello PRIVATE glad::glad imgui::imgui)

Expected behavior I expect the executable to compile and link correctly. (The same example worked as expected when I tried it on Windows.)

Failure logs

[build] : && /bin/x86_64-linux-gnu-g++-11 -g  CMakeFiles/hello.dir/main.cpp.o -o hello  /home/dylan/repositories/github/Microsoft/vcpkg/installed/x64-linux/debug/lib/libimguid.a  /home/dylan/repositories/github/Microsoft/vcpkg/installed/x64-linux/debug/lib/libglad.a  /home/dylan/repositories/github/Microsoft/vcpkg/installed/x64-linux/debug/lib/libglfw3.a  /usr/lib/x86_64-linux-gnu/librt.so  -lm  -ldl  /usr/lib/x86_64-linux-gnu/libX11.so  -lpthread && :
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/installed/x64-linux/debug/lib/libimguid.a(imgui_impl_opengl3.cpp.o): in function `ImGui_ImplOpenGL3_Init(char const*)':
[build] /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:163: undefined reference to `glGetIntegerv'
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:164: undefined reference to `glGetIntegerv'
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:168: undefined reference to `glGetString'
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:232: undefined reference to `glGetIntegerv'
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/installed/x64-linux/debug/lib/libimguid.a(imgui_impl_opengl3.cpp.o): in function `ImGui_ImplOpenGL3_SetupRenderState(ImDrawData*, int, int, unsigned int)':
[build] /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:251: undefined reference to `glEnable'
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:252: undefined reference to `__glewBlendEquation'
[build] /usr/bin/ld: /home/dylan/repositories/github/Microsoft/vcpkg/buildtrees/imgui/src/v1.83-af20d68e6e.clean/backends/imgui_impl_opengl3.cpp:253: undefined reference to `__glewBlendFuncSeparate'
...
mathisloge commented 3 years ago

Have you defined IMGUI_IMPL_OPENGL_LOADER_GLAD ? Make sure that IMGUI_IMPL_OPENGL_LOADER_GLEW isn't defined somewhere. The CMake wrapper don't add any compile definitions. So that should be on your side.

So if you haven't defined anything, imgui tries to detect the loader by itself. https://github.com/ocornut/imgui/blob/ad5d1a8429ea219d3d34e6a36a48918650402697/backends/imgui_impl_opengl3.h#L68

Not a vcpkg bug

mathisloge commented 3 years ago

And just to expand it a bit further: You might get different results depending on the platform you are using. If some application has installed libglew-dev the headers are present in the global include dir of linux. So the line #if __has_include(<GL/glew.h>) resolves to true and therefore defines IMGUI_IMPL_OPENGL_LOADER_GLEW . But the libraries aren't present in the link defines and resulting in the present link errors.

ghost commented 3 years ago

Have you defined IMGUI_IMPL_OPENGL_LOADER_GLAD ?

Yes, I have thought of this. Adding this define to my source doesn't change anything. But that's not a surprise since the linker errors are emited from libimguid.a not from my object file. There are glew headers in my /usr/include/ directory and maybe they were picked up when libimguid.a was built, but that would be a vcpkg bug.

mathisloge commented 3 years ago

Oh yeah. I see. Sorry for the false info I gave. Actually that will be tricky now. Since the loader have to be known at compile time. I think there was somewhere a discussion to be able to add a custom imgui config file. But that's currently only possible with overlay ports. (would be now the fastest solution to your problem. Copy all sources from the imgui port, add a compile definition to the glad option in the cmake file and add the port as a overlay port)

The long term solution needs discussion I think.

mathisloge commented 3 years ago

Just to help you getting started with overlay ports:

General overlay ports: https://github.com/microsoft/vcpkg/blob/master/docs/specifications/ports-overlay.md

If you are using manifests: https://github.com/microsoft/vcpkg/blob/master/docs/users/manifests.md add the path (could be relative to your projet root) to VCPKG_OVERLAY_PORTS and set the CMAKE_TOOLCHAIN_FILE

NancyLi1013 commented 3 years ago

@Dylan-Davies

You may try to solve the problem refer to this https://github.com/microsoft/vcpkg/issues/14753#issuecomment-782899582.

@mathisloge

Thanks for your help to look into this issue.

ghost commented 3 years ago

Thanks for the suggestions. I have managed to make it work with an overlay port where I just added

target_compile_definitions(${PROJECT_NAME} PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD)

as proposed in the other issue. Any reason why the problem shouldn't be solved just by adding the compile definitions for all backends like that?

BTW, in the related issues some users complain about unable to use multiple bindings side by side. Maybe it would be a good idea to provide separate targets for the backends? That way we would have imgui::imgui with just the core library and then say imgui::opengl3_glad, imgui::opengl3_glew etc. that could just live side by side.

JackBoosY commented 3 years ago

@Dylan-Davies Please see https://github.com/microsoft/vcpkg/issues/14753#issuecomment-889693559 and https://github.com/microsoft/vcpkg/issues/14753#issuecomment-889731841.

NancyLi1013 commented 3 years ago

@Dylan-Davies

As you can see as follows:

If you have installed glewon your machine, namely checks GL/glew.h, it will not check other headers such as glad/glad.h.

We need to confirm with upstream if this is by design.

// Otherwise try to detect supported Desktop OpenGL loaders..
#elif defined(__has_include)
#if __has_include(<GL/glew.h>)
    #define IMGUI_IMPL_OPENGL_LOADER_GLEW
#elif __has_include(<glad/glad.h>)
    #define IMGUI_IMPL_OPENGL_LOADER_GLAD
#elif __has_include(<glad/gl.h>)
    #define IMGUI_IMPL_OPENGL_LOADER_GLAD2
#elif __has_include(<GL/gl3w.h>)
    #define IMGUI_IMPL_OPENGL_LOADER_GL3W
#elif __has_include(<glbinding/glbinding.h>)
    #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3
#elif __has_include(<glbinding/Binding.h>)
    #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2
#else
    #error "Cannot detect OpenGL loader!"
#endif
#else
    #define IMGUI_IMPL_OPENGL_LOADER_GL3W   // Default to GL3W embedded in our repository
#endif
mathisloge commented 3 years ago

@NancyLi1013 please see https://github.com/microsoft/vcpkg/issues/14753#issuecomment-889739471 and https://github.com/microsoft/vcpkg/issues/14753#issuecomment-889741206

ghost commented 3 years ago

@NancyLi1013

If you have installed glewon your machine, namely checks GL/glew.h, it will not check other headers such as glad/glad.h.

Yes, my understanding is that if you don't want the bindings to be auto-detected, you are supposed to define one of the IMGUI_IMPL_OPENGL_LOADER_* macros before including imgui_impl_opengl3.hpp. This is what target_compile_definitions command that I cited accomplishes.