X11 and OpenGL builds on MacOS

Ok…I’m working with an old software package that still uses X11, and OpenGL via X11 on MacOS. X11 and openGL are deprecated anyway, but meantime we’d like to keep the software going.

First problem: FindX11 consistently finds the wrong directories. In a MacOS environment using XQuartz, the X11 system is always in /opt/X11, and is symlinked at /usr/X11 and /usr/X11R6. In addition, I have Homebrew on the system, and it has some of the X11 libraries, but I don’t want to use them at all. find_package(X11) gives a jumble of references to /usr/X11R6, /usr/local/lib/X11, and /usr/local/include/X11. Short of explicitly calling out the appropriate directories, is there a way to direct find_package(X11) to use /opt/X11 only?

Second problem: according to the docs, “On OSX FindOpenGL defaults to using the framework version of OpenGL. People will have to change the cache values of OPENGL_glu_LIBRARY and OPENGL_gl_LIBRARY to use OpenGL with X11 on OSX.” Is there any way I can include this in the CMake scripts? Should I just explicitly call out libraries I want on MacOS?

Does setting the X11_ROOT and OpenGL_ROOT variables to /opt/X11 and whatever prefix OpenGL lives under work? You can use cmake --debug-find to get better information about search details.

Wow, thanks for the quick reply!

Yes, setting X11_ROOT to /opt/X11 works (yay!), but setting OpenGL_ROOT does not (sigh.) For onlookers, the code for X11_ROOT is:

cmake_policy(SET CMP0074 NEW) # cmake 3.12 or later
[…]
  if(APPLE)
    set(X11_ROOT "/opt/X11")
  endif()
  find_package(X11)

Unfortunately,

   if(APPLE AND X11_FOUND)
     set(OpenGL_ROOT "/opt/X11")
   endif()
   find_package(OpenGL)

Still finds the framework versions of the OpenGL libraries, rather than the ones under /opt/X11.

I’ve just noticed some CMake files in the XQuartz distribution; maybe they’re what I need. I’ll experiment further.

No luck; those files are apparently for build scripts. Any further thoughts?

Did --debug-find help at all?

It did. And the answer is the XQuartz include directory and library file names are not what FindOpenGL.cmake expects. In addition, cmake prioritizes frameworks over plain libraries. So the fix is:

  1. Tell cmake not to look for frameworks
  2. Fix FindOpenGL.cmake to look for the proper include file and library names.

Now, when I copy my modified FindOpenGL to a local directory, it cannot find FindPackageHandleStandardArgs.cmake. Do I need to copy that also, and whatever it includes? Is there perhaps a variable that gives the default module directory? Or…?

My code in CMakeLists.txt now reads:

   if(APPLE AND X11_FOUND)
     set(CMAKE_FIND_FRAMEWORK NEVER)
     set(OpenGL_ROOT "/opt/X11")
     find_package(OpenGL)
     set(CMAKE_FIND_FRAMEWORK "")
   else()
     find_package(OpenGL)
   endif()

Here’s a diff of a version of FindOpenGL.cmake which works when in the Modules directory of the app:

210,214c210,216
<   # The OpenGL.framework provides both gl and glu
<   find_library(OPENGL_gl_LIBRARY OpenGL DOC "OpenGL library for OS X")
<   find_library(OPENGL_glu_LIBRARY OpenGL DOC
<     "GLU library for OS X (usually same as OpenGL library)")
<   find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OS X")
---
>   # The OpenGL.framework provides both gl and glu in OpenGL
>   # XQuartz provides libgl and libglu
>   find_library(OPENGL_gl_LIBRARY NAMES OpenGL GL DOC
>     "OpenGL library for OS X")
>   find_library(OPENGL_glu_LIBRARY NAMES OpenGL GLU DOC
>     "GLU library for OS X")
>   find_path(OPENGL_INCLUDE_DIR NAMES OpenGL/gl.h GL/gl.h DOC "Include for OpenGL on OS X")

And, yes, if I copy FindPackageMessage.cmake and FindPackageHandleStandardArgs.cmake to my local module directory, it all works, but what an awful hack, and one which may fail with future versions of CMake. Any suggestions?

Edit those files to just do include(ModName); they probably have include(${CMAKE_ROOT}/ModName.cmake) instead.

The diffs to the Find module seem reasonable to submit as an MR. See the contributing docs.

And, indeed, removing the directory name and “.cmake” makes CMake consider it a module and find it in the Modules directory. Thank you.

Fine point: what’s common practice for naming a local modules directory? I used CMakeModules at the top level of the project, but I’m not sure that’s a good idea; it looks like it might be part of CMake instead of a local directory. Is there a common practice or style recommendation?

I use cmake if I have a choice. Maybe cmake/modules if there’s some difference between include-able or not.

1 Like

Yeah, cmake or CMake is pretty common.
I typically have some sort of hierarchy underneath.

Thanks - I’ll try that.

And…it all works. Thanks for all the help.

Maybe next week I’ll get a Round Tuit and submit an MR. Meantime, here’s my FindOpenGL.cmake which supports XQuartz for anyone who needs it.

FindOpenGL.cmake (25.2 KB)

MR submitted.