Right now the only way to specify runtime dependencies is to hard-code an implementation using something like makeWrapper. Although, there are a lot of cases I think it would be useful to encode that a specific file must exist or that a specific binary must exist in $PATH, without tying down the package to a specific implementation.
It even applies much more broadly, you could e.g. delay choosing a libc implementation, or a docker/container runner, or a Python implementation, for an application. Conceptually youād want to build a derivation against an API, then decide on an implementation of that API in a separate derivation. You can then only build the first derivation once, then have a (cheap) build for each combination with an implementation.
Requiring something in $PATH etc is kinda annoying IMHO because it breaks expectations for things like nix run. However you can do a two-level, where the wrapper is in a separate derivation, so you donāt have to rebuild the ābaseā to change the āwrapperā. IIUC things like neovim and clang already use this approach.
xdg-utils is already a good concrete example of this as apps which open URLs assume xdg-open will be on the path, and they can call xdg-open https://example.org/ to open it. handlr was already linked as an example replacement.
Thatās true for most cases, but I think it makes sense in certain circumstances. I feel like for nix run we could just give the same kind of error message pointing out that a runtime dependency is missing.
For certain common tools which one might want to replace, like xdg-open, it seems to me like nixpkgs config, combined with the two-level structure @dramforever suggested, is the right way to handle it. That way you can set in one place what you want to use for that, but you still keep the self-contained nature of a nix derivation closure.
Yep, I think thatās the ideal, but the problem comes when thereās no good default, and it makes more sense to take what the user set on $PATH.
For example, I mentioned doing the exact same thing for texlab (that it should depend on a TeX distribution), but the other reviewers decided against it because they mentioned that many users may have a different TeX distribution installed, and expect that to be used instead:
For these situations Iām suggesting that we have some other mechanism to determine when these dependencies are satisfied, instead of just leaving the dependency off altogether.
Another similar existing example is /run/opengl-drivers. Packages build against mesa, and then at runtime depend on whatever is symlinked in /run/opengl-drivers.
Yeah, but that hook canāt actually verify that /run/opengl-drivers actually exists in the final system profile during build time, it will just fail to load the library at runtime.
Do you think it would help to have some formal way to describe these runtime impurities like what I mentioned in the main description though? Right now we assume these exist at runtime and fail at runtime if they donāt, but I feel like we could verify this earlier during profile generation.
The problem is c-style dynamic linking. Thereās only so much we can do when an environment āassumesā that libraries will be co-located with everything else.
Part of the problem is that even nixos doesnāt actually know for sure whatās in PATH at runtime. It comes from multiple sources, including home-manager and nix-env for user-installed stuff.
Part of the overall philosophy of the nix ecosystem is to use build-time resolution of resources wherever possible. This philosophy isnāt incidental. Itās an important part of getting many of the benefits we get from it. PATH lookups are an exception to this philosophy, because you donāt want to reboot just to get a new package installed, but this doesnāt seem like it qualifies for an exception to me. If the current UX is bad, we need to make the build-time resolutionās configuration process easier, not start trying to guarantee runtime resolution will work. It canāt even be done in environments like nix-env and nix profile anywayā¦ not without a major overhaul to the architecture of nix itself, which I would view as quite detrimental.
With CA derivations, it might be possible to add a hardware drivers stub, and then people donāt have to rely on any runtime hacks to find the more specific hardware libraries.
The stub is just there so that the actual drivers only have a single downstream package. This should make it cheap for the contents to be replaced with something else without having to rebuild the actual immediate downstream dependencies.