mosra / magnum-integration

Integration libraries for the Magnum C++11 graphics engine
https://magnum.graphics/
Other
99 stars 44 forks source link

ImGui Integration with vcpkg #67

Closed fauder closed 2 months ago

fauder commented 4 years ago

Hi,

I installed Magnum and its dependencies via vcpkg after giving up on the cmake approach. I then installed imgui integration: vcpkg install magnum-integration[imgui] --head I also installed magnum with --head.

When I tried to compile the imgui example in a newly created empty visual studio project (with only single cpp (example) file), I got linker errors (LNK2001 unresolved external symbol) related to imgui integration.

Oh I also slightly modified the example cpp (swapped sdl2application with glfwapplication, for some reason sdl was giving syntax errors).

LNK2001 Unresolved external symbol warnings:

  1. "declspec(dllimport) public: void cdecl ImGuiIO::AddInputCharactersUTF8(char const *)" (_imp?AddInputCharactersUTF8@ImGuiIO@@QEAAXPEBD@Z)
  2. "declspec(dllimport) bool cdecl ImGui::ColorEdit3(char const ,float const,int)" (_imp?ColorEdit3@ImGui@@YA_NPEBDQEAMH@Z)
  3. "declspec(dllimport) void cdecl ImGui::End(void)" (_imp?End@ImGui@@YAXXZ)
  4. "declspec(dllimport) struct ImGuiIO & cdecl ImGui::GetIO(void)" (_imp?GetIO@ImGui@@YAAEAUImGuiIO@@XZ)
  5. "declspec(dllimport) bool cdecl ImGui::SliderFloat(char const ,float ,float,float,char const *,float)" (_imp?SliderFloat@ImGui@@YA_NPEBDPEAMMM0M@Z)
  6. "declspec(dllimport) bool cdecl ImGui::Button(char const *,struct ImVec2 const &)" (_imp?Button@ImGui@@YA_NPEBDAEBUImVec2@@@Z)
  7. "declspec(dllimport) void cdecl ImGui::SetNextWindowPos(struct ImVec2 const &,int,struct ImVec2 const &)" (_imp?SetNextWindowPos@ImGui@@YAXAEBUImVec2@@H0@Z)
  8. "declspec(dllimport) void cdecl ImGui::ShowDemoWindow(bool *)" (_imp?ShowDemoWindow@ImGui@@YAXPEA_N@Z)
  9. "declspec(dllimport) void cdecl ImGui::SetCurrentContext(struct ImGuiContext *)" (_imp?SetCurrentContext@ImGui@@YAXPEAUImGuiContext@@@Z)
  10. "declspec(dllimport) bool cdecl ImGui::Begin(char const ,bool ,int)" (_imp?Begin@ImGui@@YA_NPEBDPEA_NH@Z)
  11. "declspec(dllimport) int cdecl ImGui::GetMouseCursor(void)" (_imp?GetMouseCursor@ImGui@@YAHXZ)
  12. "declspec(dllimport) void cdecl ImGui::Text(char const *,...)" (_imp?Text@ImGui@@YAXPEBDZZ)
  13. "declspec(dllimport) void cdecl ImGui::SetNextWindowSize(struct ImVec2 const &,int)" (_imp?SetNextWindowSize@ImGui@@YAXAEBUImVec2@@H@Z)

Currently installed repos:

C:\Sys\vcpkg>vcpkg list corrade:x64-windows corrade[interconnect]:x64-windows corrade[pluginmanager]:x64-windows corrade[testsuite]:x64-windows corrade[utility]:x64-windows curl:x64-windows curl[non-http]:x64-windows curl[ssl]:x64-windows curl[winssl]:x64-windows glfw3:x64-windows imgui:x64-windows magnum-integration:x64-windows magnum-integration[imgui]:x64-windows magnum:x64-windows magnum[anyaudioimporter]:x64-windows magnum[anyimageconverter]:x64-windows magnum[anyimageimporter]:x64-windows magnum[anysceneimporter]:x64-windows magnum[audio]:x64-windows magnum[debugtools]:x64-windows magnum[gl]:x64-windows magnum[glfwapplication]:x64-windows magnum[meshtools]:x64-windows magnum[primitives]:x64-windows magnum[scenegraph]:x64-windows magnum[sdl2application]:x64-windows magnum[shaders]:x64-windows magnum[text]:x64-windows magnum[texturetools]:x64-windows magnum[trade]:x64-windows openal-soft:x64-windows sdl2:x64-windows zlib:x64-windows

By the way, can I get away with using only vcpkg (no CMake) ? Or do I have to resort to CMake eventually even though I have all Magnum related stuff installed via vcpkg ? I seldom use CMake and I suck at it (last time was 2 years ago, compiling OpenCascade).

mosra commented 4 years ago

Hi!

I'm not a "Windows native" user so I don't know how exactly the package works -- however, if I remember correctly, ImGui had various issues when built dynamically. Can you try using the static build instead (it's the x64-windows-static triplet if I remember correctly)? That one should work.

Also, do you remember what were the errors with SDL? There's a chance I already saw those and could point you in the right direction. Other than that the GLFW and SDL app implementation should have mostly a feature parity, so you're not missing out on anything (the only reason why SDL is default is that it works on phones and the web also, which GLFW doesn't).

You can use Magnum without CMake, yes (and as long as you are directly in the VS IDE, vcpkg should "magically work" for everything, no need to supply link libraries or include directories ... or that was its main selling point, at least). Some things however (such as compiling resources) might be harder than when using Magnum's CMake support tho. Some docs that might be useful.

mosra commented 4 years ago

I dug into the vcpkg package history and it seems that dynamic builds might have worked in the past, but they certainly don't anymore (unless imgui itself is doing something for that, which I doubt): https://github.com/microsoft/vcpkg/commit/050e71d01dc9e65e6cdf1d13534fc14889e4ae38#diff-99430a8c55cefb8a2e543d865102898d

A random idea: could you try putting the set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) line back into your copy of ports/imgui/CMakeLists.txt and installing the package again? I think that could fix it.

Looking at https://github.com/microsoft/vcpkg/pull/5937, from which the above originates, it seems that certain ports reverted this change and I think imgui could do the same ... or some cleaner variant of it. (@Squareys do you think you could have time to do this?)

fauder commented 4 years ago

It already says

Note: imgui only supports static library linkage. Building static library.

when installing imgui through vcpkg. Although I tried it anyways and nothing changed.

Going to try modifying CMakeLists.txt in ports/.

fauder commented 4 years ago

A random idea: could you try putting the set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) line back into your copy of ports/imgui/CMakeLists.txt and installing the package again? I think that could fix it.

This also did not work, same linker errors.

fauder commented 4 years ago

I noticed I have both imgui:x64-windows and imgui:x64-windows-static

So I removed all x64-windows packages and installed all of them with x64-windows-static ones. Now I can build and run the imgui example!

You might want to update magnum-integration build docs, mention this imgui-static issue.

Also, do you remember what were the errors with SDL?

cannot open source file "SDL_keycode.h cannot open source file "SDL_mouse.h cannot open source file "SDL_version.h cannot open source file "SDL_video.h cannot open source file "SDL_scancode.h

Even though I have sdl2:x64-windows-static installed.

You can use Magnum without CMake, yes (and as long as you are directly in the VS IDE, vcpkg should "magically work" for everything, no need to supply link libraries or include directories ... or that was its main selling point, at least). Some things however (such as compiling resources) might be harder than when using Magnum's CMake support tho. Some docs that might be useful.

The link you attached seems a little overwhelming. I hope I can manage.

Thanks for the tip and of course for Magnum!

mosra commented 4 years ago

Regarding the SDL includes -- vcpkg has a patch to fix those (https://github.com/microsoft/vcpkg/blob/master/ports/magnum/001-sdl-includes.patch) but looks like it doesn't apply on current master anymore, which is why you get the errors. That needs to get fixed, a temporary workaround is to add the path to the SDL2/ subdirectory of SDL includes to your Visual Studio project. But GLFW is working just fine and is free of issues like #57, so no need to switch back :)

Note: imgui only supports static library linkage. Building static library.

Good to know -- then Magnum may need an adjustment to work correctly as a dynamic library linked against a static lib. If you can keep using the static build until then, great.

overwhelming

The most scary parts are the library dependency graphs. That dependency ordering is already handled for you by vcpkg, so not really needed :)

fauder commented 4 years ago

I'm happy with GLFW :) I also don't (currently) have a problem with static build. Is there a disadvantage to linking against Magnum statically ?

The most scary parts are the library dependency graphs. That dependency ordering is already handled for you by vcpkg, so not really needed :)

Hmm, what about this then:

Some things however (such as compiling resources) might be harder than when using Magnum's CMake support tho.

Does this mean I may run into problems when compiling shaders into resources ? I apologize if I am not making sense, I'm still trying to learn how Magnum handles anything (including shaders).

More general question: I plan on migrating a codebase of not-insignificant size built upon MFC to Magnum (and ImGui for GUI). Can I get by with vcpkg approach ? For example; I plan on using geometry shaders. Would compiling shaders be a problem with the vcpkg approach (since you mentioned compiling resources) ?

My main issue (compiling ImGui example) is solved by the way, thanks!

mosra commented 4 years ago

There's no disadvantage to linking statically (apart from the usual tradeoffs with static/dynamic builds) :)

You're not forced to use Utility::Resource for anything, but if you would want to use it to embed data in your executable (instead of having external files), you need to manually invoke corrade-rc as part of your build and then add the generated cpp file to your project sources. You are also free to use any other method that suits your workflow (such as Windows *.rc files, if you only need to care about Windows). Go through the Textured Triangle example to get an idea what issues you might run into -- again, the example will work just fine with shader sources loaded directly from files.

I'm keeping this issue open as a reminder to fix the two vcpkg-related issues (otherwise there's high chance those would get forgotten).

fauder commented 4 years ago

Gotcha. Thanks for the help and also for creating Magnum!

mosra commented 4 years ago

The SDL-related issue should be fixed once https://github.com/microsoft/vcpkg/pull/10158 gets merged. ImGui will likely need more work, that's not done yet.

pezcode commented 4 years ago

Just ran into this issue trying to compile magnum-integration from source while linking to libraries from vcpkg with a x64-windows-static triplet. When MAGNUM_IMGUIINTEGRATION_BUILD_STATIC is not defined, it defines IMGUI_API to __declspec(dllimport) which results in linker errors because the vcpkg imgui.lib is a static library.

One solution I could think of would be:

mosra commented 4 years ago

Yep, TYPE target property is a good idea -- does the ImGui CMake config coming from Vcpkg expose this information? For all I know, imported targets usually lack info whether a library is static or dynamic and so I had to always revert to guessing from library filename (which isn't really possible on Windows).

Another alternative, as mentioned in one of the comments above I think, would be always compiling ImGuiIntegration as static, which could prevent issues with global symbols duplicated across DLLs (unless the end-user links the static lib into two DLLs again).

pezcode commented 4 years ago

does the ImGui CMake config coming from Vcpkg expose this information? For all I know, imported targets usually lack info whether a library is static or dynamic and so I had to always revert to guessing from library filename (which isn't really possible on Windows).

The CMake config file installed by vcpkg does this:

# Create imported target imgui::imgui
add_library(imgui::imgui STATIC IMPORTED)

Mildly relevant quote from the CMake docs:

An UNKNOWN library type is typically only used in the implementation of Find Modules. It allows the path to an imported library (often found using the find_library() command) to be used without having to know what type of library it is. This is especially useful on Windows where a static library and a DLL’s import library both have the same file extension.

bigdimboom commented 4 years ago

Is there a definitive solution for issue yet? I have the issue on windows vs 2019.

devpikachu commented 2 years ago

As of now, the solution I've found works best is still explained here: https://github.com/mosra/magnum-examples/issues/97#issuecomment-780830374

TL;DR: Clone imgui and magnum-integration locally and build with bundled ImGui.

CMake:

set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/imgui)
set(WITH_IMGUI ON CACHE BOOL "" FORCE)
add_subdirectory(lib/magnum-integration EXCLUDE_FROM_ALL)

Note that I have mine under ./lib/ - adapt to your own use-case.

mosra commented 2 months ago

This is finally fixed as of ad50841cfec2d1edd0600d5c87e7be9791754b44. Basically doing what @pezcode suggested above, sorry that it took over four years to fix.