-
Notifications
You must be signed in to change notification settings - Fork 372
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
Support Nix depexts with opam env
#5982
base: master
Are you sure you want to change the base?
Conversation
Rebased on master |
9e67415
to
f348b9f
Compare
Looks like I'm running into NixOS/nix#10587 with the Docker image |
phases = [ "buildPhase" ]; | ||
|
||
buildPhase = '' | ||
vars=("NIX_CC" "NIX_CC_FLAGS" "NIX_CFLAGS_COMPILE" "NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu" "NIX_LDFLAGS" "PKG_CONFIG_PATH") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to make these environment variables configurable in order to support new dependencies from Nix, which might require additional environment variables, without cutting a new release of Opam.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think capnproto might use a flag that isn't here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pattern match that NIX_CC_WRAPPER_TARGET_HOST_
- the x86_64_unknown_linux_gnu
presumably doesn't want to stay hard-coded in here?
1a47e83
to
9892788
Compare
Rebased on master -- and could do with another depext CI run if it needs re-approval! |
ff88713
to
2184b56
Compare
Okay! The CI is failing only due to ocaml/opam-repository#26261 (I've got it working locally with my branch of opam-repository) |
src/client/opamSolution.ml
Outdated
OpamSysPkg.(Set.union nf sys.s_not_found) | ||
| None -> avail, nf) | ||
packages (OpamSysPkg.Set.empty, OpamSysPkg.Set.empty) | ||
| None -> avail, req, nf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think it might be worth using a dedicated record instead of a tuple at this point. Otherwise it could become confusing very quickly with all those similar types around
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have opamSysPkg.status
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though, we're also passing around the couple of available
and required
a lot, which perhaps warrants a separate record.
src/state/opamSysInteract.ml
Outdated
|} in | ||
OpamFilename.write drvFile contents; | ||
let envFile = OpamFilename.create dir (OpamFilename.basename (OpamFilename.raw "nix.env")) |> OpamFilename.to_string in | ||
[`AsUser "nix-build", [ OpamFilename.to_string drvFile; "--out-link"; envFile ] ], None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good if we could trigger a re-build of any packages that depend on depexts if the drv path changes, as if they link against a previous derivation it could be GC'd. An alternative might be to keep the old nix.env
files around as Nix GC roots.
Anyone wanting to play around with this on a NixOS system can try:
Or add it to your own overlay with:
This URL is just the https://github.com/RyanGibb/opam/tree/nixos-depexts-2.3.0 branch with vendored dependencies since I couldn't get them working in Nix, |
with pkgs; | ||
stdenv.mkDerivation { | ||
name = "opam-nix-env"; | ||
nativeBuildInputs = with buildPackages; [ |} ^ packages ^ {| ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to update that file for each installed package, like that there is no need to retrieve and pass the whole list of already installed packages and their system packages ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is more ergonomic, as it allows system packages to be uninstalled too. It's bridging opam's imperative mode to nix's declarative model.
David made an observation in today's Opam dev meeting that this PR will not remove depexts from the Nix derivation until the next install. This might effect reproducibility in some circumstances, but this isn't a huge deal as if Nix users want full reproducibility they can use opam2nix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while tracking down NixOS/nixpkgs#388471 i tried this branch and it worked really well in a nixos docker container. I was able to build opam-publish
which requires openssl
and gmp
without any issues at all, like magic.
We support this by including `all_packages` in a switch in a call to `OpamSolution.get_depexts`, including all system packages for the packages in a switch as `required` in a call to `OpamSysInteract.install, and including all of these in the Nix derivation generate by the Nix depext backend.
Co-authored-by: Kate <[email protected]>
also only attempt to read the nix environment file if the os-family = nixos
8222184
to
cecc358
Compare
let dir = OpamPath.Switch.meta st.switch_global.root st.switch in | ||
let drvFile = | ||
OpamFilename.create dir | ||
(OpamFilename.basename (OpamFilename.raw "env.nix")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file seems to be there only as a sort of temporary file for nix-build
. I also find the naming convention a bit confusing when taken together with nix.env
.
env.nix
and nix.env
are way too close in terms of name and it's easy to confuse between them.
Wouldn't some sort of nameless temporary file be more indicated if a file has to be used?
Couldn't we use a constant string together with environment variables for packages
(and possibly vars
) instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have found the env.nix
file useful sometimes in debugging what is actually in the nix environment, but I agree the naming is a bit confusing
Thanks for the comments and commits @kit-ty-kate ! I'm glad it was useful :-) Apologies I haven't had a lot of time to work on this PR recently |
Nix doesn't install packages in the traditional sense -- instead it puts them in a store and makes them available through environment variables. I.e.,
nix-shell -p gcc
will drop us into a shell with gcc in the$PATH
.We can set appropriate environment variables with Opam to make system dependencies (depexts) available with Nix.
Similar to how
nix-shell
works under the hood, we create a Nix derivation such asWhich we can build to output a file with environment variables that make depexts available, in Opam's environment variable format. This file is a Nix store root, so it's dependencies won't be garbage collected by Nix until the file is removed.
This approach came from conversations with @dra27 and is distinct from previous approaches in that it supports providing development environment, which imperative installations with Nix don't #5332 (comment); and doesn't require the user to manage the environment outside of Opam, which would lead to a different workflow #5942.
Initial experiments were done using a package to set such environment variables https://github.com/RyanGibb/nix.opam.
However, in order to work with generic depexts (as opposed to just conf packages), to avoid cyclic dependencies (if conf packages depend on nix.opam but nix.opam depends on conf packages), and due to opam package sandboxing (nix derivation fetching would require opam sandboxing to be disabled or the nix store to be 'primed'), it's better implemented as a depext mechanism.
This has been tested and successfully creates an environment to provide packages
conf-gmp
andconf-libseccomp
, as well as depexts directly.