Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{libGL,libGLU}: use the OpenGL framework on Darwin #321800

Merged
merged 20 commits into from
Jun 23, 2024

Conversation

emilazy
Copy link
Member

@emilazy emilazy commented Jun 22, 2024

Description of changes

A redo of #290421 (@K900 and @reckenrode’s work) that eliminates the stubs entirely. The majority of packages that support macOS at all can already handle Apple’s OpenGL framework, so we simply alias libGL and libGLU depending on the platform, add a similar cross‐platform libglut alias, a libGLX alias for the things that explicitly require X11, and play whack‐a‐mole with the relatively few things this breaks. This decimates Mesa’s reverse dependency tree on macOS and will hopefully promote the good cause of positive Linux–Darwin relations.

An earlier version of this PR has been tested on aarch64-darwin against master and confirmed to result in basically no regressions of anything that currently builds successfully on Hydra. The exceptions were xorg.xdriinfo, which is a one‐character fix but is inherently broken and useless on macOS anyway, and volantes-cursors, which is prone to hanging so we’ll just have to see what Hydra makes of it. I am currently running another nixpkgs-review cycle on a master‐based version of this on the community builder, and will address any new failures and report the results when it finishes.

@SuperSandro2000 asked on the previous PR how to know which OpenGL dependencies a package should use. This is a good question, and I’ve attempted to answer it in code comments, but here’s a more complete exposition:

Anything that uses OpenGL probably wants libGL by default. A modern package that supports macOS should Just Work™ with this. If it has trouble finding -lGL, then you may need to pass in a compiler flag, as explained in the comment in all-packages.nix. If it wants <GL/gl.h>, that should be patched to <OpenGL/gl.h> on macOS. However, if it’s clearly an X11‐only package (e.g. explicitly uses the glx* APIs or tries to -lGLX, or depends on an X11‐only toolkit), it should depend on libGLX instead, and shouldn’t require any flags or patching. This will probably not apply to many new packages, as modern software will get an OpenGL context from a toolkit; it should only be relevant when packaging crusty software from the times when OS X had pinstripes and Wayland was just a town in Massachusetts. When in doubt, ping @NixOS/darwin-maintainers for a check.

Anything that also wants glu.h/glu* functions should depend on libGLU, unless it also needs libGLX, in which case it should use mesa_glu (which propagates libGLX). There may be similar issues with linker paths or <GL/glu.h> instead of <OpenGL/glu.h>; using flags and patching is preferable to bringing in mesa_glu unless the software only supports X11. (This bit is ugly: Apple’s GLU should really work fine even for X11‐only software, it’s just that if the package requires libGLX anyway then you might as well use the Mesa implementation and save having to wrangle the headers and linking.)

Anything that wants GLUT should depend on libglut, unless it uses freeglut‐specific APIs or otherwise won’t work with the GLUT framework, in which case it should depend on freeglut if those issues can’t be patched out. (This means it will only work on X11 and might want libGLX too.)

Very little should depend on mesa, mesa_glu, libglvnd, or freeglut except as noted here. The exceptions relate to various random non‐standard headers and internal APIs; when in doubt, consult an expert.

Previously, it was required to have explicit conditionals to use libGL on Linux and darwin.apple_sdk.frameworks.OpenGL on Darwin (and similarly for GLUT). As of this pull request, this is no longer necessary, and it’s fine to clean things up to use lib{GL,GLU,glut} unconditionally. You might still need to add frameworks like Cocoa on Darwin, and conditionalize X11 dependencies on not‐Darwin, but a simple package that gets an OpenGL context from a modern cross‐platform toolkit shouldn’t need any conditionals.

If the workarounds above end up being annoyingly common, separate macOS‐specific stubs packages could be created that provide things like include/GL, lib/libGL.dylib, and lib/pkgconfig/gl.pc using the underlying frameworks. In practice, I only had to deal with a very small number of these, as any software that supports macOS natively without X11 is extremely likely to already handle the framework format, given that it’s what you get from the OS. (One of the exceptions was a direct result of the current Nixpkgs weirdness!)

In general, adding libGL should be all you need a substantial fraction of the time, given that GLU and GLUT are not very popular these days. If you can think of a better way to document all of this in‐tree, please do let me know, and feel free to ping me (disclaimer: no SLA) if you’re ever unsure; I’ve become much more familiar with all this than I ever wanted to be and I may as well put it to good use.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.11 Release Notes (or backporting 23.11 and 24.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

emilazy and others added 20 commits June 22, 2024 18:06
This reduces the reverse closure of Mesa on Darwin considerably. As
a result, we can also drop the Mesa stubs package entirely, as its
output on Linux is functionally identical to libglvnd.

It should no longer be necessary for packages to switch between libGL
and darwin.apple_sdk.frameworks.OpenGL depending on the platform.

A cross‐platform libGLX alias is added for packages that specifically
need it (mostly old X11 applications that barely know what a macOS is).

Co-authored-by: K900 <me@0upti.me>
freeglut requires GLX; this allows more packages to work with the
native macOS GLUT framework without conditionals.
Allow the macOS GLUT framework to be used automatically in many
cases. Packages that specifically search for freeglut or require its
additional APIs should still explicitly depend on it.

Deliberately skip the Haskell package set, which is mostly
automatically generated, and mupdf, which has its own fork of freeglut.
These were now broken on Darwin; most of them were unnecessary,
but best practice for the remaining ones is to use `lib.getDev`.
This requires hacks to build against Apple’s OpenGL framework, and
there’s no point; macOS ships with a GLU implementation already, so
this package should only be used for X11 applications that explicitly
require Mesa’s libGLX and want `<GL/glu.h>`.
The upstream code can already successfully find the system framework
on macOS, and fontconfig isn’t used at all.

Co-authored-by: Randy Eckenrode <randy@largeandhighquality.com>
This isn't really related to this change, but makes nixpkgs-review runs a lot nicer.
Drop the seemingly‐unused CoreServices dependency while we’re at it.
It wants a Mesa‐specific header for some reason, even though it
works without X11.
On Darwin, libGL is the same as libGLU now, and the build system
doesn’t like having the same path passed twice for whatever
reason. Since libGLU always propagates libGL, just specify the former.
@K900
Copy link
Contributor

K900 commented Jun 22, 2024

This is seriously impressive work, everyone. Hugs all around.

@emilazy
Copy link
Member Author

emilazy commented Jun 22, 2024

I can confirm the following regressions from nixpkgs-review (plus manual rebuilds for flaky packages) compared to the corresponding revision of master on Hydra:

  • gramps
  • python311Packages.sphinxcontrib-wavedrom
  • python311Packages.xcffib
  • python311Packages.xpybutil
  • python312Packages.sphinxcontrib-wavedrom
  • python312Packages.xcffib
  • python312Packages.xpybutil
  • xorg.xdriinfo

The Python failures are all downstream of xcffib, and build fine if I disable tests on that package; it uses an Xvfb X server to run tests, which seems inherently flaky, but theoretically could have somehow been legitimately broken by this, I suppose. xorg.xdriinfo is as described in the original post. gramps is some python311Packages.berkeleydb tests issue that didn’t show up before and that I don’t understand at all; could just be flaky (though I can’t get it to go through on a rebuild either), but it seems very unlikely to be the result of these changes. Disabling tests fixes that one too. This should be ready to go.

By the way, I want to make clear that my intention is for Mesa to no longer be a channel blocker on Darwin after this. I don’t know how to confirm whether it is or not (if anyone does, please let me know!), but X11 on macOS is very marginal, so I don’t want it to get in the way of anyone’s work unless they specifically choose to care about it; it should not be a big deal for Mesa to be broken on Darwin. Hopefully this will make things easier on the Linux side as well.

@emilazy
Copy link
Member Author

emilazy commented Jun 22, 2024

(Also, the Linux rebuilds should be totally harmless; libGL now uses libglvnd directly rather than going through a now‐redundant stubs package, but that package just duplicated the headers and .pc files already in libglvnd anyway, with semantically‐identical content; libglvnd is the indirection layer the stubs package was originally created to be.)

@K900 K900 merged commit 97530e9 into NixOS:staging Jun 23, 2024
28 checks passed
@SuperSandro2000
Copy link
Member

I didn't find the time to look at this in the last days but it looks like you did a great work at thinking this through and testing it, so I hope there are minimal breakages. Good job! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants