* doc/contributing.texi ("Snippets versus Phases"): Replaced with... ("Modifying Sources"): ... this. List more use cases and some principles. --- doc/contributing.texi | 108 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 13 deletions(-)
diff --git a/doc/contributing.texi b/doc/contributing.texi index 02c7c5ae59..af97d37f34 100644 --- a/doc/contributing.texi +++ b/doc/contributing.texi @@ -441,7 +441,7 @@ needed is to review and apply the patch. * Package Naming:: What's in a name? * Version Numbers:: When the name is not enough. * Synopses and Descriptions:: Helping users find the right package. -* Snippets versus Phases:: Whether to use a snippet, or a build phase. +* Modifying Sources:: When to use patches, snippets, or build phases. * Emacs Packages:: Your Elisp fix. * Python Modules:: A touch of British comedy. * Perl Modules:: Little pearls. @@ -698,20 +698,102 @@ Gettext}): for the X11 resize-and-rotate (RandR) extension. @dots{}") @end lisp -@node Snippets versus Phases -@subsection Snippets versus Phases +@node Modifying Sources +@subsection Modifying Sources +@cindex patches, when to use @cindex snippets, when to use -The boundary between using an origin snippet versus a build phase to -modify the sources of a package can be elusive. Origin snippets are -typically used to remove unwanted files such as bundled libraries, -nonfree sources, or to apply simple substitutions. The source derived -from an origin should produce a source that can be used to build the -package on any system that the upstream package supports (i.e., act as -the corresponding source). In particular, origin snippets must not -embed store items in the sources; such patching should rather be done -using build phases. Refer to the @code{origin} record documentation for -more information (@pxref{origin Reference}). + +Guix has three main ways of modifying the source code of a package, +that you as a packager may use. Each one has its strengths and +drawbacks, along with intended and historically derived use cases. +These are + +@table @b + +@item patches +If your package has a bug that takes multiple lines to fix, or a fix +has already been accepted upstream, patches are the preferred way of +eliminating said bug. Refer to the @code{origin} record documentation +(particularly the fields @code{patches}, @code{patch-inputs}, and +@code{patch-flags}) for more information on how to use patches +(@pxref{origin Reference}). +When adding a patch, do not forget to also list it in +@code{dist_patch_DATA} of @file{gnu/local.mk} + +As patches are applied to the origin of a package, they become part +of the corresponding source. You can retrieve this source by +invoking @code{guix build -S YOUR_PACKAGE}. This also means that +modifying the patch causes two rebuilds: one for the source and one +for the package built from it. + +Patches are limited in that they lack the expressiveness of Guile. +If all changes are constrained to single lines, a patch might be much +larger than the equivalent @code{substitute*}. It is further bad form +to use a single patch to address multiple unrelated issues, whereas +snippets can take ``multiple jobs''. + +@item snippets +If your package contains non-free sources, these need to be removed +through a snippet. This snippet should not only remove the sources in +question, but also references to the removed sources in build scripts, +documentation, and so on. @ref{Software Freedom} + +If your package bundles external libraries, snippets are the preferred +way of removing said them. Unlike with non-free sources, it is not a +requirement to remove @emph{all} bundled libraries, although doing so +is very much preferred. Bundled libraries that are kept should be +clearly indicated, preferrably with a reason as to why the bundled copy +remains. As with non-free sources, references to the removed libraries +should also be updated in the snippet. + +Refer to the @code{origin} record documentation +(particularly the fields @code{snippet} and @code{modules}), for more +information on how to use snippets (@pxref{origin Reference}). + +While snippets have all of Guile's core as well as extra @code{modules} +available, their most useful procedure for @emph{editing} sources +(rather than removing them), is @code{substitute*}, which can not deal +with multi-line changes that well. Like patches, snippets become part +of the corresponding source. + +@item build phases +For modifications that retain the intended functionality of the +package, build phases (usually between @code{unpack} and +@code{configure}, sometimes between @code{configure} and @code{build}) +can be used. Such changes include, but are not limited to, fixes of the +build script(s) or embeddings of store paths (e.g. replacement of +@file{/bin/sh} with @code{(search-input-file inputs "bin/sh")}). + +If you need to embed a store path, do so only inside a build phase. +A workaround for patches that span multiple lines, is to use a variable +such as @code{@@store_path@@} inside the patch and substitute the actual +store path at build time via @code{substitute*}. + +Unlike patches and snippets, build phases do @b{not} become part of +the corresponding source of a package, and should thus be avoided for +changes that result in observably different runtime behaviour. +On the other hand, the reduced overhead of unpacking, repacking and +unpacking again might make for a slightly more pleasant debugging +experience. + +@end table + +If your change does not neatly fit in any of the categories above, it +is usually a matter of preference or convenience. + +As part of a build phase, you may further want to use +@b{auxiliary files}, for instance to add new source files. As a matter +of principle, auxiliary files ought to be preferred over an equivalent +@code{display} or @code{format} when creating non-trivial files, as that +makes them easier to edit. The exact threshold for a non-trivial file +might be subjective, though it should lie somewhere between 10~20 lines. + +Auxiliary files are stored in the @file{gnu/packages/aux-files} +directory and can be retrieved in a snippet or build phase via +@code{search-auxiliary-file}. +When adding an auxiliary file, do not forget to also list it in +@code{AUX_FILES} of @file{Makefile.am}. @node Emacs Packages @subsection Emacs Packages -- 2.37.0