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

Building on Guix #46

Open
roptat opened this issue Nov 11, 2020 · 4 comments
Open

Building on Guix #46

roptat opened this issue Nov 11, 2020 · 4 comments

Comments

@roptat
Copy link

roptat commented Nov 11, 2020

Hi :)

I'm trying to build opam2nix on Guix, using existing Guix packages (and importing dependencies that are not yet in the distribution). I tried to build v1.2.0 as well as the latest commit, and get the following error:

File "src/opam_metadata.ml", line 30, characters 28-44:
30 | 	| ExternalDependencies of (OpamSysPkg.Set.t * OpamTypes.filter) list
                                 ^^^^^^^^^^^^^^^^
Error: Unbound module OpamSysPkg
  version_ml src/version.ml

Am I missing a dependency? Am I using something that's too old/too recent?

@timbertson
Copy link
Owner

The opam libraries are defined in nix/opam.nix, but the source comes from wrangle.json - each of those libraries comes from the opam repo, which I've currently pinned to version 2.1.0-beta:

"opam": {
"fetch": {
"owner": "ocaml",
"repo": "opam",
"rev": "11fcbc9e4bd7cca322f3020ed414531737012bd4",
"sha256": "04042ayhpi76g0zp4fihsy1da7szmfhykii892wq2307r8y886wv"
},
"owner": "ocaml",
"ref": "2.1.0-beta",
"repo": "opam",
"type": "github"
},

Fair warning: I do have a rather invasive script to rip out some dependencies for opam-client: https://github.com/timbertson/opam2nix/blob/f6b45ed9e95e468f2971f7fee9dd5abbbc1d7577/nix/opam-client-minimal.sh
That's just to eliminate the need for dose, etc, but if you have those packaged already you should be fine to just use the full opam-client, at least to get started with. I should probably just vendor the functions I need from opam-client, but I worked hard to get them upstreamed in the first place 😆

@roptat
Copy link
Author

roptat commented Nov 12, 2020

ah, thanks! the package builds with opam 2.1.0-beta2. I was looking at the opam2nix.opam file, where there is no constraint. you might want to add one :). Now I managed to build it, but I'm not sure how to run it on the build side. I found this opam2nix invoke patch (build, install), but I get Missing environment variable: out. Is this supposed to be the output of the derivation? Also, how do I pass the name of the opam file I want to build the sources with?

@timbertson
Copy link
Owner

Yeah, the .opam file is not actually used (aside from some experiments I was trying), I should probably just delete it.

out is set by nix to the derivation's output / destination path, but it's only set when building a derivaiton. Are you running tis inside a derivation or just testing it out in a shell for now? I assume guix also sets $out during build, but maybe it uses something different. If you just want to try it outside a derivation, setting it to /tmp/whatever should get you a bit further.

Once you get past that, you'll also need to set opamEnv, which is a JSON serialization of all dependencies. That's set up here in the nix code:

opam2nix/nix/api.nix

Lines 116 to 124 in f6b45ed

opamEnv = builtins.toJSON {
inherit (args) version;
name = args.pname;
deps = mapAttrs (name: impl:
if isPseudo impl then impl else {
path = impl;
inherit (impl) version;
}
) ({ inherit ocaml; } // args.opamInputs);

And it's loaded here in ocaml code, if that's useful:

opam2nix/src/invoke.ml

Lines 73 to 120 in f6b45ed

let () = match json with
| `Assoc pairs -> begin
pairs |> List.iter (function
| "deps", `Assoc (attrs) -> begin
debug "adding packages from opamEnv\n";
attrs |> List.iter (fun (pkgname, value) ->
match value with
| `Null -> add_package pkgname Absent
(* Bool is used for base packages, which have no corresponding path *)
| `Bool b -> add_package pkgname (if b then Provided else Absent)
| `Assoc attrs -> (
let path = ref None in
let version = ref None in
attrs |> List.iter (fun (key, value) ->
match (key, value) with
| "path", `String value -> path := Some value
| "version", `String value -> version := Some (Version.of_string value)
| "version", `Null -> version := None
| _, other -> unexpected_json ("deps." ^ pkgname) other
);
add_package pkgname (Installed {
(* path is optional in the type, but by `invoke` time all paths
* should be defined *)
path = Some (!path
|> Option.or_failwith "missing `path` in deps"
|> OpamFilename.Dir.of_string);
version = !version;
})
)
| other -> unexpected_json "deps value" other
)
end
| "deps", other -> unexpected_json "deps" other
| "name", `String name -> self_name := Some name;
| "name", other -> unexpected_json "name" other
| "version", `String version -> self_version := Some (Version.of_string version);
| "version", other -> unexpected_json "version" other
| other, _ -> failwith ("unexpected opamEnv key: " ^ other)
)
end
| other -> unexpected_json "toplevel" other
in

@timbertson
Copy link
Owner

(ugh tabs render so ugly in github UI...)

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

No branches or pull requests

2 participants