While there cannot be circular dependencies between packages, Guile’s lax module loading mechanism allows circular dependencies between Guile modules, which doesn’t cause problems as long as the following conditions are followed for two modules part of a dependency cycle:
Straying away from the above rules may work while there are no dependency cycles between modules, but given such cycles are confusing and difficult to troubleshoot, it is best to follow the rules to avoid introducing problems down the line.
Here is a common trap to avoid:
(define-public avr-binutils (package (inherit (cross-binutils "avr")) (name "avr-binutils")))
In the above example, the
avr-binutils package was defined in the
(gnu packages avr), and the
cross-binutils procedure in
(gnu packages cross-base). Because the
inherit field is not
delayed (thunked), it is evaluated at the top level at load time, which is
problematic in the presence of module dependency cycles. This could be
resolved by turning the package into a procedure instead, like:
(define (make-avr-binutils) (package (inherit (cross-binutils "avr")) (name "avr-binutils")))
Care would need to be taken to ensure the above procedure is only ever used in a package delayed fields or within another procedure also not called at the top level.