summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorGiacomo Leidi <therewasa@fishinthecalculator.me>2026-06-02 17:32:15 +0200
committerGabriel Wicki <gabriel@erlikon.ch>2026-07-20 11:26:38 +0200
commita6bd9d8369c5c3433df21da09f672a4338deeb1f (patch)
treee69c27e5490b38d85428f1d232b35bc75c2ac887 /doc
parent24979fef66fff8eacc106410a3fd337e067b7eb5 (diff)
doc: Document current policy for vendored code.
* doc/contributing.texi (Dependencies Unbundling): New subsection. Signed-off-by: Gabriel Wicki <gabriel@erlikon.ch>
Diffstat (limited to 'doc')
-rw-r--r--doc/contributing.texi91
1 files changed, 77 insertions, 14 deletions
diff --git a/doc/contributing.texi b/doc/contributing.texi
index 576aee8a816..7e5b9d77a49 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -1128,20 +1128,21 @@ needed is to review and apply the patch.
1128 1128
1129 1129
1130@menu 1130@menu
1131* Software Freedom:: What may go into the distribution. 1131* Software Freedom:: What may go into the distribution.
1132* Package Naming:: What's in a name? 1132* Extracting Bundled Dependencies:: Why do we unbundle dependencies.
1133* Version Numbers:: When the name is not enough. 1133* Package Naming:: What's in a name?
1134* Synopses and Descriptions:: Helping users find the right package. 1134* Version Numbers:: When the name is not enough.
1135* Snippets versus Phases:: Whether to use a snippet, or a build phase. 1135* Synopses and Descriptions:: Helping users find the right package.
1136* Cyclic Module Dependencies:: Going full circle. 1136* Snippets versus Phases:: Whether to use a snippet, or a build phase.
1137* Bulk Updates:: This Little Maneuver's Gonna Cost Us 51 Years. 1137* Cyclic Module Dependencies:: Going full circle.
1138* Emacs Packages:: Your Elisp fix. 1138* Bulk Updates:: This Little Maneuver's Gonna Cost Us 51 Years.
1139* Python Modules:: A touch of British comedy. 1139* Emacs Packages:: Your Elisp fix.
1140* Perl Modules:: Little pearls. 1140* Python Modules:: A touch of British comedy.
1141* Java Packages:: Coffee break. 1141* Perl Modules:: Little pearls.
1142* Rust Crates:: Beware of oxidation. 1142* Java Packages:: Coffee break.
1143* Elm Packages:: Trees of browser code 1143* Rust Crates:: Beware of oxidation.
1144* Fonts:: Fond of fonts. 1144* Elm Packages:: Trees of browser code
1145* Fonts:: Fond of fonts.
1145@end menu 1146@end menu
1146 1147
1147@node Software Freedom 1148@node Software Freedom
@@ -1171,6 +1172,68 @@ package (@pxref{Defining Packages}). This way, @code{guix
1171build --source} returns the ``freed'' source rather than the unmodified 1172build --source} returns the ``freed'' source rather than the unmodified
1172upstream source. 1173upstream source.
1173 1174
1175@node Extracting Bundled Dependencies
1176@subsection Extracting Bundled Dependencies
1177@cindex bundling
1178@cindex vendoring
1179@cindex bundled dependencies
1180@cindex vendored dependencies
1181
1182In Guix every package is supposed to be fully built from source
1183(@pxref{Bootstrapping}). This is at the heart of the security and user
1184freedom guarantees provided by the distribution, and it is what allows
1185Guix to correctly reason about the package graph, to apply transversal
1186changes (say, a security update on a single library) and have them
1187propagate to every dependent package.
1188
1189Some projects have the habit of distributing the source code of their
1190dependencies inside their release tarball or version controlled source
1191tree. This practice is called @dfn{bundling} and the dependencies
1192shipped this way are called @dfn{bundled dependencies} or in some cases
1193@dfn{vendored dependencies}. Common manifestations are a @file{vendor/}
1194directory in Go projects, a checked in @file{node_modules/} for
1195JavaScript, a populated @file{.cargo/vendor/} for Rust, or copies of
1196small C libraries shipped inside another project's tree.
1197
1198Bundling dependencies conflicts with several Guix invariants:
1199
1200@itemize
1201@item When a change must be made in a library---e.g., applying a security fix
1202or removing pre-generated code---that change would need to be repeated
1203in every single package that bundles it.
1204@item Guix mainline ships only free software: bundled trees frequently contain
1205minified blobs whose preferred form for modification is missing
1206(@pxref{Software Freedom}).
1207@item Duplicated source code inflates the closure size and makes
1208@command{guix size} (@pxref{Invoking guix size}) and @command{guix
1209graph} (@pxref{Invoking guix graph}) less useful as auditing tools.
1210@end itemize
1211
1212For these reasons, we do our best to remove bundled dependencies before
1213submitting a package.
1214
1215@subsubheading Removing Bundled Code
1216
1217Bundled dependencies should be removed in the package's @code{origin}
1218record, typically using a snippet or a patch, so that the source
1219returned by @command{guix build --source} corresponds to truly free,
1220unbundled sources (@pxref{Snippets versus Phases}). When the removal is
1221more involved, for example because it requires regenerating build files
1222or rewriting import paths, it is acceptable to do it in a build phase
1223instead.
1224
1225Once the bundled tree is gone, the package must be built against
1226existing Guix packages of the same dependencies. When such packages do
1227not yet exist, they must be added.
1228
1229@subsubheading Exceptions
1230
1231Removing bundled code is the rule, but in case a bundled dependency has
1232been changed up to the point that it isn't possible to build a package
1233with the unbundled version of the dependency, it can be considered as
1234part of the source tree it lives in. In general we don't care about
1235upstream's reason for bundling, only the practicality of the unbundling
1236job.
1174 1237
1175@node Package Naming 1238@node Package Naming
1176@subsection Package Naming 1239@subsection Package Naming