1

I've made my Guix system entirely declarative, always adding packages through guix package -m mymanifest.scm.

Sometimes this fails because of conflicting dependencies. E.g. right now I have gcc-toolchain in my manifest, amongst dozens of other packages, and this message shows up:

guix package: error: profile contains conflicting entries for gcc-toolchain guix package: error: first entry: [email protected] /gnu/store/rfm800pq3q2midj29a4xlikdzjp1ps2l-gcc-toolchain-12.3.0 guix package: error: second entry: [email protected] /gnu/store/ks87cpc36kh8hqwr569pks4yrzfl7mnv-gcc-toolchain-11.3.0 hint: You cannot have two different versions or variants of `gcc-toolchain' in the same profile. 

I suppose gcc-toolchain that is included in the manifest is 12.3.0, and some other package has [email protected] as an (indirect) dependency. But I don't know which package that is.

In this particular case, the problem was easily resolved, because I also included gcc in the manifest, and that resulted in the warning that package 'gcc' has been superseded by 'gcc-toolchain', and removing gcc seems to have fixed the issue.

However, I'd like a more general applicable method to find the 'offending' package. That is, given a manifest file, say mymanifest.scm, how can I figure out through which dependency chain a given package, say [email protected], ends up in the profile?

I usually do a binary search, by simply commenting out (or back in) half of the packages and see when the problem disappears (or reappears), but this is a manual and tedious process.

The ugly naive way I can automate this myself would be to loop through all the packages, call guix graph on each package, and then grep for the problematic dependency. Better would be to figure out what guix graph is doing, and do that for a whole manifest. Or perhaps convert a manifest into a package (empty, except for dependencies), and then call guix graph on that. But there is probably a better way.

1
  • right now, pyportmidi is failing, seemingly related to a Python / Qt upgrade in Guix, and again, not sure how pyportmidi got into my profile, but maybe I can patch it Commented May 30, 2023 at 7:16

1 Answer 1

0

In summary: you could temporarily prevent conflicts by building subsets of the manifest separately, obtain from guix build -m manifest.scm the store addresses of the packages listed in each manifest, loop over them and grep guix gc --requisites to search their recursive dependencies.

Since your profile currently won't build, you should separate the new packages you're trying to add from the old packages they are conflicting with. Or if the conflicts are within the new packages, split those. It doesn't matter how the packages are distributed, the point is to have all packages you want to inspect successfully installed in the store (so you can use guix gc --requisites) and a handful of manifests from which you can obtain their paths programmatically.

Run guix build once on each manifest first, to ensure it builds successfully and avoid dealing with parsing the compilation log. Then the second time, it will only output the path to the packages contained in the manifest:

$ guix build -m manifest.scm /gnu/store/jsk7igg8kd48blg5d6psb0rg120v68gw-xdot-1.1 /gnu/store/4dzv8avq7jyzybqvn3bj3c3bildi2pcc-graphviz-7.0.1-doc /gnu/store/vsnrha979rs4sgmv2ynqvzd9dr5mj2mc-graphviz-7.0.1 

Then you can loop over this list to call guix gc --requisites on each package, and search for the dependency you're interested in (its name in the store, as given in the error message). Here's an example in fish:

for manifest in manifest1.scm manifest2.scm for package in (guix build -m $manifest) if guix gc -R $package | grep -q '/gnu/store/ks87cpc36kh8hqwr569pks4yrzfl7mnv-gcc-toolchain-11.3.0' echo $package end end end 

It will list all packages in your manifests recursively depending on [email protected].

Probably not directly relevant to the question, but for completeness:

If you need to search the dependencies of a profile which is already in the store, and you can't / don't want to use guix build (if you don't have its manifest, or guix needs to re-download gigabytes of build tools, etc): you can also recover the original package list from the profile.

In general, if a profile wasn't garbage collected, there will be a link to it in /var/guix/profiles/per-user/. If you're looking for the profile used by guix package -m mymanifest.scm (its last successful build, which won't contain the conflicting packages), you can find the address in the store with:

$ readlink -f ~/.guix-profile /gnu/store/…-profile 

Once you have the path to your profile, the second step is to find the paths to the packages that were in your original manifest. guix gc --references /gnu/store/…-profile seems to list also some of their dependencies. To get only the packages you explicitly installed, my trick is to use the indentation of the package list in /gnu/store/…-profile/manifest: first-level packages have 6 spaces, their dependencies 10, etc:

grep -E '^ {6}"/gnu/store/' /gnu/store/…-profile/manifest | cut -d'"' -f 2 

Then you get the same list as with guix build, minus the doubles caused by packages with several outputs (such as graphviz in the example above).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.