[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dependency cycle issues when using a Gexp-based snippet

From: Maxim Cournoyer
Subject: Re: Dependency cycle issues when using a Gexp-based snippet
Date: Wed, 02 Sep 2020 11:08:27 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Hi Ludovic!

Thank you for the reply.

Ludovic Courtès <> writes:

> Hello!
> skribis:
>> While trying to move some of the patching done to qtbase into a snippet,
>> with the goal of having at least the ./configure script runnable in a
>> guix environment without having to manually run patching phases:
> [...]
>> I encountered the following issue, which seems similar to one
>> encountered by Ricardo in 2016 [0]:
>> ice-9/eval.scm:293:34: error: canonical-package: unbound variable
>> hint: Did you forget a `use-modules' form?
>> The origin can be correctly built at the REPL, so the problem indeed
>> seems to be a dependency cycle.
> Indeed: the problem is that when loading this module, we try to resolve
> one of the variables referenced in the snippet, but that variable is not
> defined yet because it comes from a module that’s in a dependency circle
> with the one at hand.
>> Attempting a suggested fix by Ludovic in that same conversation [0],
>> namely, making the snippet field of the <origin> record a thunked one:
>> modified   guix/packages.scm
>> @@ -250,7 +250,8 @@ as base32.  Otherwise, it must be a bytevector."
>>    (patches   origin-patches                       ; list of file names
>>               (default '()) (delayed))
>> -  (snippet   origin-snippet (default #f))         ; sexp or #f
>> +  (snippet   origin-snippet
>> +             (default #f) (thunked))              ; sexp or #f
>>    (patch-flags  origin-patch-flags                ; list of strings
>>                  (default '("-p1")))
> We should check what this change costs in CPU and memory, but it’s
> probably worth it.  As Marius noted before, the snippets for
> ungoogled-chromium and linux-libre are contrived because of this
> limitation.  (Perhaps we can use ‘delayed’ instead of ‘thunked’.)

What is the difference between delayed and thunked? Would a thunked
capture the closure of its environment while delayed not?  Is the
closure useful to access record-bound values such as the version field
of a package?

I checked the usage at compilation and run time, using the 'time'
command (aliased to time+ on my system), and didn't find any meaningful
difference whether the snippet is made a thunked or delayed field, or
none (current situation):

On current master:

--8<---------------cut here---------------start------------->8---
time+ make -j8
2436.29user 56.47system 14:29.36elapsed 286%CPU (0avgtext+0avgdata 
5480inputs+405952outputs (71major+320522minor)pagefaults 0swaps

time+ ./pre-inst-env guix package -A | wc -l
9.87user 0.24system 0:06.51elapsed 155%CPU (0avgtext+0avgdata 
0inputs+0outputs (0major+25636minor)pagefaults 0swaps
--8<---------------cut here---------------end--------------->8---

With delayed source field:

--8<---------------cut here---------------start------------->8---
time+ make -j8
2493.40user 51.16system 16:29.33elapsed 257%CPU (0avgtext+0avgdata 
48888inputs+413640outputs (158major+340632minor)pagefaults 0swaps

time+ ./pre-inst-env guix package -A | wc -l
9.68user 0.26system 0:06.68elapsed 148%CPU (0avgtext+0avgdata 
1008inputs+0outputs (7major+42943minor)pagefaults 0swaps
--8<---------------cut here---------------end--------------->8---

And finally with thunked source field:
--8<---------------cut here---------------start------------->8---
time+ make -j8
2302.67user 27.44system 22:32.82elapsed 172%CPU (0avgtext+0avgdata 
2960inputs+416688outputs (51major+300689minor)pagefaults 0swaps

time+ ./pre-inst-env guix package -A | wc -l
10.02user 0.23system 0:07.46elapsed 137%CPU (0avgtext+0avgdata 
2984inputs+0outputs (101major+24685minor)pagefaults 0swaps
--8<---------------cut here---------------end--------------->8---

Based on this, I would choose the most capable 'mode' for the source
field, which I presume is thunked.

>> It now seems a new cycle is introduced because trying to build anything
>> hangs using the CPU with slowly increasing memory usage:
> Hmm not sure exactly why, but look:
> +              (snippet
> +               (with-imported-modules '((guix build utils))
> +                 #~(begin
> +                     (use-modules (guix build utils))
> +                     ;; corelib uses bundled harfbuzz, md4, md5, sha3
> +                     (with-directory-excursion "src/3rdparty"
> +                       (for-each delete-file-recursively
> +                                 (list "double-conversion" "freetype" 
> "harfbuzz-ng"
> +                                       "libpng" "libjpeg" "pcre2" "sqlite" 
> "xcb"
> +                                       "zlib")))
> +
> +                     (let ((coreutils #+(canonical-package coreutils)))
> +                       (substitute* "configure"
> +                         (("/bin/pwd")
> +                          (string-append coreutils "/bin/pwd")))
> +                       (substitute* "src/corelib/global/global.pri"
> +                         (("/bin/ls")
> +                          (string-append coreutils "/bin/ls"))))
> +                     #t)))))
> Such substitutions are system-dependent; thus, they should be made in a
> phase, not in a snippet.  Perhaps we’ll sidestep the issue altogether?
> :-)

Indeed.  I didn't consider this aspect well.  Apart from being
inefficient (the sources of a package would be different for each
system) it would still technically work, no?

But yeah, that bloat is probably not worth the extra convenience (of
having a source that can be built straight from 'guix build --source').



reply via email to

[Prev in Thread] Current Thread [Next in Thread]