From c23eb401cf3dd9f7ae8402a0a59258e4f6ebefa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Sep 2023 10:30:49 +0200 Subject: [PATCH] Platform: properly link GLX apps to libGLX on an GLES + EGL build. It fails on a linker error otherwise. There's a bit of annoying logic needed for pre-GLVND systems as there it's not possible to link to GLX without dragging the whole libGL in as well, causing bad conflicts with libGLES. Which means I can't test this on the CI yet as there CMake is forced to version 3.5 and finding GLVND is only in 3.10. --- modules/FindMagnum.cmake | 7 +++++++ package/ci/circleci.yml | 6 ++++++ src/Magnum/Platform/CMakeLists.txt | 29 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index afd12518c..566238990 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -810,6 +810,13 @@ foreach(_component ${Magnum_FIND_COMPONENTS}) # *not* found. WTF. Also can't just check for # OPENGL_opengl_LIBRARY because that's set even if # OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + # + # If MAGNUM_TARGET_GLES and MAGNUM_TARGET_EGL is set, these + # applications can be built only if GLVND is available as + # otherwise there would be a conflict between libGL and + # libGLES. Thus, if GLVND is not available, it won't link + # libGLX here, but that shouldn't be a problem since the + # application library won't exist either. find_package(OpenGL) if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) set_property(TARGET Magnum::${_component} APPEND PROPERTY diff --git a/package/ci/circleci.yml b/package/ci/circleci.yml index be09f70ba..630c06e85 100644 --- a/package/ci/circleci.yml +++ b/package/ci/circleci.yml @@ -374,6 +374,9 @@ jobs: CMAKE_CXX_FLAGS: --coverage LCOV_EXTRA_OPTS: --gcov-tool /usr/bin/gcov-4.8 CONFIGURATION: Debug + # TODO enable also GlxApplication, WindowlessGlxApplication and + # GlxContext once CMake 3.10+ is used to test correct libGLES + libGLX + # linking EXTRA_OPTS: > -DMAGNUM_WITH_XEGLAPPLICATION=ON -DMAGNUM_WITH_WINDOWLESSEGLAPPLICATION=ON @@ -403,6 +406,9 @@ jobs: CMAKE_CXX_FLAGS: --coverage LCOV_EXTRA_OPTS: --gcov-tool /usr/bin/gcov-4.8 CONFIGURATION: Debug + # TODO enable also GlxApplication, WindowlessGlxApplication and + # GlxContext once CMake 3.10+ is used to test correct libGLES + libGLX + # linking EXTRA_OPTS: > -DMAGNUM_WITH_XEGLAPPLICATION=ON -DMAGNUM_WITH_WINDOWLESSEGLAPPLICATION=ON diff --git a/src/Magnum/Platform/CMakeLists.txt b/src/Magnum/Platform/CMakeLists.txt index 92aa8b8ec..83e1ffc58 100644 --- a/src/Magnum/Platform/CMakeLists.txt +++ b/src/Magnum/Platform/CMakeLists.txt @@ -422,6 +422,17 @@ if(MAGNUM_WITH_GLXAPPLICATION) message(FATAL_ERROR "X11 library, required by some applications, was not found. Set MAGNUM_WITH_*X*APPLICATION to OFF to skip building them.") endif() + # If we're targeting GLES and EGL, only the libGLES library is looked for + # by default. Here we need libGLX from GLVND in addition. If GLVND is not + # available however (or CMake < 3.10 is used), fail, as GLX symbols are + # only in libGL in that case, which would conflict with libGLES. + if(MAGNUM_TARGET_GLES AND MAGNUM_TARGET_EGL) + find_package(OpenGL) + if(NOT OpenGL_FOUND OR NOT OPENGL_opengl_LIBRARY OR NOT OpenGL_GL_PREFERENCE STREQUAL GLVND) + message(SEND_ERROR "Without GLVND, GlxApplication is available only if MAGNUM_TARGET_EGL is disabled. Use XEglApplication on EGL instead.") + endif() + endif() + set(MagnumGlxApplication_SRCS GlxApplication.cpp $ @@ -446,6 +457,9 @@ if(MAGNUM_WITH_GLXAPPLICATION) # Can't use OpenGL_OpenGL_FOUND, because that one is set also if GLVND is # *not* found. WTF. Also can't just check for OPENGL_opengl_LIBRARY because # that's set even if OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + # + # See also the logic above for preventing libGL and libGLES conflicts. If + # there's no conflict, this branch is taken and libGLX is linked. if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) target_link_libraries(MagnumGlxApplication PUBLIC OpenGL::GLX) endif() @@ -479,6 +493,10 @@ if(MAGNUM_WITH_XEGLAPPLICATION) message(FATAL_ERROR "X11 library, required by some applications, was not found. Set MAGNUM_WITH_*X*APPLICATION to OFF to skip building them.") endif() + # Unlike with GlxApplication above, here no conflict between libGLES and + # libGL can happen -- we only either link libGLES and libEGL or libGL and + # libEGL. + set(MagnumXEglApplication_SRCS XEglApplication.cpp $ @@ -557,6 +575,17 @@ if(MAGNUM_WITH_WINDOWLESSGLXAPPLICATION) message(FATAL_ERROR "X11 library, required by some applications, was not found. Set MAGNUM_WITH_*X*APPLICATION to OFF to skip building them.") endif() + # If we're targeting GLES and EGL, only the libGLES library is looked for + # by default. Here we need libGLX from GLVND in addition. If GLVND is not + # available however (or CMake < 3.10 is used), fail, as GLX symbols are + # only in libGL in that case, which would conflict with libGLES. + if(MAGNUM_TARGET_GLES AND MAGNUM_TARGET_EGL) + find_package(OpenGL) + if(NOT OpenGL_FOUND OR NOT OPENGL_opengl_LIBRARY OR NOT OpenGL_GL_PREFERENCE STREQUAL GLVND) + message(SEND_ERROR "Without GLVND, WindowlessGlxApplication is available only if MAGNUM_TARGET_EGL is disabled. Use WindowlessEglApplication on EGL instead.") + endif() + endif() + set(MagnumWindowlessGlxApplication_SRCS WindowlessGlxApplication.cpp $)