Open wildeyevr opened 2 years ago
I'm running into this as well, my understand that (at least for me) this is due to an issue with how OpenGL is accessed on Wayland and how you technically have to go through libglvnd
.
I took a brief look at this, it does seem to be platform specific. The GLFW build docs explain
Note that the glfw target does not depend on OpenGL, as GLFW loads any OpenGL, OpenGL ES or Vulkan libraries it needs at runtime. If your application calls OpenGL directly, instead of using a modern extension loader library, use the OpenGL CMake package.
find_package(OpenGL REQUIRED)
If OpenGL is found, the
OpenGL::GL
target is added to your project, containing library and include directory paths. Link against this like any other library.target_link_libraries(myapp OpenGL::GL)
That said, since I'm not able to reproduce this error, and am also not personally very familiar with the changes in the OpenGL context scenario, I think those docs are actually a little bit outdated.
-DNANOGUI_BUILD_GLAD=ON
? It defaults to OFF
unless on Windows. Please do this with a clean cmake build directory.Near line 453 of CMakeLists.txt
, just after the add_library(nanogui ...)
call, can you try adding the following?
find_package(OpenGL REQUIRED)
message(STATUS "NanoGUI: gl pref: ${OpenGL_GL_PREFERENCE}")
if (TARGET OpenGL::OpenGL)
message(STATUS "NanoGUI: using OpenGL::OpenGL")
target_link_libraries(nanogui PUBLIC OpenGL::OpenGL)
else()
message(STATUS "NanoGUI: using OpenGL::GL")
target_link_libraries(nanogui PUBLIC OpenGL::GL)
endif()
and report back (a) if it works and (b) which printed, OpenGL::OpenGL
or OpenGL::GL
as well as what gl pref
was? (Please don't set NANOGUI_BUILD_GLAD=ON
for this test, doing so in a clean build directory).
The CMake docs on find_package(OpenGL)
are a bit confusing. The linux specific section verbiage makes me believe that to do it correctly, you need to check the OpenGL_GL_PREFERENCE
, but I'm not sure. They say if legacy is not available, then OpenGL::GL
points to OpenGL::OpenGL
(glvnd), but if both are available then I think you force legacy if you always use OpenGL::GL
?
I'm not sure if I'm experiencing the same exact issue as the OP, as I am not on Ubuntu, but I am getting the same error, so I will try to continue this issue and answer @svenevs questions. If OP is on the latest Ubuntu, which is Wayland, then we might be experiencing the same issue - because this is the problem I am encountering when trying to compile on a Wayland-only machine.
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find OpenGL (missing: OPENGL_glx_LIBRARY)
This issue makes sense in my context - as GLX
does not exist on Wayland.
Replacing the find_package(OpenGL REQUIRED)
line with find_package(OpenGL REQUIRED COMPONENTS OpenGL)
(that is telling FindOpenGL that we only care about the OpenGL core libary, and not GLX or EGL) fixes the issue, and prints
-- Found OpenGL: /usr/lib64/libOpenGL.so found components: OpenGL
-- NanoGUI: gl pref: GLVND
-- NanoGUI: using OpenGL::OpenGL
Of course to actually have the next step, make
, work, we'd need to replace the original problematic list(APPEND NANOGUI_LIBS GL)
line.
Now if OP is indeed running into the same issue as me due to being on Wayland, they will run into another error upon fixing the previous one.
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_get_fd'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_keyboard_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_output_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_compositor_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_buffer_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_proxy_set_user_data'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_proxy_get_user_data'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_disconnect'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_proxy_destroy'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_dispatch_pending'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_pointer_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_proxy_add_listener'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_data_device_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_roundtrip'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_flush'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_callback_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_connect'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_region_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_subsurface_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_subcompositor_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_prepare_read'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_data_device_manager_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_read_events'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_registry_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_seat_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_shm_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_proxy_get_version'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_surface_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_display_cancel_read'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_proxy_marshal_flags'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_data_source_interface'
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/../../../../x86_64-pc-linux-gnu/bin/ld: libnanogui.so: undefined reference to `wl_shm_pool_interface'
Since obviously nanogui
doesn't manually call Wayland functions, I imagine this is something to do with how nanogui
subsumes glfw
into itself (can't find any documentation about why this is done), and although it correctly carries over the X dependencies, it fails to properly select the Wayland dependencies on Wayland systems. I wonder if there's some more elegant way to ensure platform-appropriate GLFW dependencies are used.
Hey all... I appreciate you all looking into the issue... will mess around with this at some point today and report back
Hey svenevs...
I'm on Ubuntu 20.04.3 LTS (Focal Fossa) by the way
FYI Had a friend build on Ubuntu 21.10 impish with success... he has some ideas on the issue will follow up...
Hmmm, ok, thanks for the responses it's very helpful! So it seems like there's potentially two different things going on here, but the solution seems to also be related.
# My understanding is this fixes the original issue on 20.04
find_package(OpenGL REQUIRED COMPONENTS OpenGL)
target_link_libraries(nanogui PUBLIC OpenGL::OpenGL)
# note, not the PR solution, will break superbuild consumers (see below)
What's not clear to me is if this is supposed to be getting avoided on wayland altogether. Maybe the above gets guarded by checking XDG_SESSION_TYPE
environment variable and not doing it if it is Wayland
?
I did some trial and error but am actually failing to obtain a wayland session on this rig (nvidia drivers, wasn't able to get around it...). I will be able to test off a live usb of ubuntu in february if you poke me (away next week). Some additional things worth trying for diagnosing wayland:
cd ext/glfw
and mkdir build; cd build; cmake .. -DGLFW_USE_WAYLAND=ON
after compilation there should be ./examples/gears
or others. Do those run as expected? I anticipate you will hit the same issue.
glfw/glfw
repository? If so the fork of glfw should get updated again. There seem to be some wayland updates in their src/CMakeLists.txt
.I imagine this is something to do with how nanogui subsumes glfw into itself (can't find any documentation about why this is done)
The TL;DR is it's part of "superbuilds", mitsuba-renderer and tev are some examples. There's also historical reasons, but basically dependency management with CXX has always been a nightmare so usually projects vendor their own.
The way the glfw fork works is by patching glfw add_library(glfw_objects OBJECT
, OBJECT
being the key. Then for the most part everything that was target glfw
is now replaced with glfw_objects
so that nanogui consume the $<TARGET_OBJECTS:glfw_objects>
. CMake doesn't let you do this without object libraries. Nanogui does the same thing with object libraries, allowing parent projects to consume its objects directly if they so desire. It is worth mentioning that if you link against something else that also links against glfw, you will get problems and must use an external glfw with nanogui (since the symbols will now be defined twice).
So for consuming projects doing superbuilds, linking against OpenGL::OpenGL
may be something we should avoid in favor of appending the underlying library to the list of nanogui libraries to link against. Right now the nanogui targets are not setup in a way where using those targets on nanogui
is OK, it'll fix nanogui but not the parent projects.
Hope that clarifies things a bit, sorry if it is not clear it's late but wanted to explain a bit of the different moving parts.
Thank you for moving this forward so quickly!
glfw
on Wayland a ton and have never had issues with it, so I am imagining what is going on here is a nanogui
specific issue. top
, just no window appears. Not sure if this is a peculiarity of Wayland or my tiling window manager. But NANOGUI_BUILD_GLFW
is a neat flag, and might help as a temporary workaround on some systems. The name leaves a bit to be desired, though -- wasn't sure if that meant that I somehow had to integrate my own windowing library to get nanogui to work, or what. Perhaps USE_EXTERNAL_GLFW
would be more illustrative of the actual use case. The way the glfw fork works is by patching glfw
add_library(glfw_objects OBJECT
,OBJECT
being the key. Then for the most part everything that was targetglfw
is now replaced withglfw_objects
so that nanogui consume the$<TARGET_OBJECTS:glfw_objects>
. CMake doesn't let you do this without object libraries. Nanogui does the same thing with object libraries, allowing parent projects to consume its objects directly if they so desire. It is worth mentioning that if you link against something else that also links against glfw, you will get problems and must use an external glfw with nanogui (since the symbols will now be defined twice).
Thanks for the explanation, this makes more sense now. Though I'm not convinced this is worth it, given how it becomes harder to stay up to date with the latest glfw
changes, and make sure its platform requirements are appropriately passed through.
So for consuming projects doing superbuilds, linking against
OpenGL::OpenGL
may be something we should avoid in favor of appending the underlying library to the list of nanogui libraries to link against. Right now the nanogui targets are not setup in a way where using those targets onnanogui
is OK, it'll fix nanogui but not the parent projects.
Perhaps then this can be ameliorated by using the Cache variables FindOpenGL provides. OPENGL_opengl_LIBRARY
seems to be set on my system, and I imagine OPENGL_gl_LIBRARY
is set on other ones. FindOpenGL appears to set the variables necessary to tell which one to use.
Try building and using WaylandGUI that is a fork I started focusing only on ARM Linux but it doesn't force ARM on you. At least two of the examples should work for you. Make certain libglvnd isn't installed anywhere on your system. ldd your example binaries to ensure they are linked against the correct libraries.
Hey all... just to followup here... it builds fine on Ubuntu 21.10 impish... so this is solved for me at least
Sorry for joining the party very late -- are there any concrete suggestions on how to change the CMake build system so that it works for Wayland? I am still based on X11 and things are fine there.
I left off with the work I did for WaylandGUI which is a fork of this. Had to drop all of the unnecessary platforms, MAC/Apple, Windows, etc. The Apple/Mac support is what screwed the pooch. I haven't touched it since this thread. My project used Elements for the final product. I used NanoGUI inside of a Docker container for the board verification software and everybody abandoned Wayland.
Having said that.
Another on this thread will be picking up some work on WaylandGUI shortly if they haven't already done so. They hit the same wall in their project and they don't have the option of using a Docker container. Both myself and Toradex advised them on finding the smallest Wayland compatible library they could and wedging it into their existing UI library.
Sadly I don't have my test system set up anymore nor do I currently have the time to devote to WaylandGUI. That's a personal project that got pushed down the queue.
As long as you continue to support Apple/MAC with that custom EGLS (or whatever custom that got added for the platform) you will never work on Wayland. That relies on an API that simply isn't there. If you want Wayland you have to abandon Apple or at least abandon everything currently in place for Apple because it wasn't well done. It's "worked for an application" code not "works for a project" code.
If memory serves, I had at least two of the demo programs working under Wayland with WaylandGUI.
@wjakob #135 should do it, or at least the baseline (building and running without crash) of it.
[ 63%] Linking CXX shared library libnanogui.so /usr/bin/ld: cannot find -lGL collect2: error: ld returned 1 exit status make[2]: [CMakeFiles/nanogui.dir/build.make:629: libnanogui.so] Error 1 make[1]: [CMakeFiles/Makefile2:330: CMakeFiles/nanogui.dir/all] Error 2 make: *** [Makefile:130: all] Error 2