Next: , Previous: , Up: Packaging Guidelines   [Contents][Index]


22.8.6 Cyclic Module Dependencies

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:

  1. Macros are not shared between the co-dependent modules
  2. Top-level variables are only referenced in delayed (thunked) package fields: arguments, native-inputs, inputs, propagated-inputs or replacement
  3. Procedures referencing top-level variables from another module are not called at the top level of a module themselves.

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 module (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.


Next: Emacs Packages, Previous: Snippets versus Phases, Up: Packaging Guidelines   [Contents][Index]