.TH HOLY-RECIPE 5 "2026" "holy" "Holy package format" .SH NAME holy-recipe \- Holy build recipe, phases and build environments .SH SYNOPSIS .nf format holy-recipe-1 name NAME version VERSION release RELEASE arch ARCH libc LIBC summary TEXT source NAME INPUT source-sha256 NAME DIGEST build-depend EXPRESSION [RELATION VERSION] depend EXPRESSION [RELATION VERSION] output NAME KIND split OUTPUT GLOB config PATH [mutable] hook-install INTERPRETER PATH hook-remove INTERPRETER PATH x-KEY VALUE step PHASE INTERPRETER [ARG...] <= ge, <= le, > gt, < lt, = eq. arch maps x86_64, x86 to i686, and noarch or any unchanged; any other list needs review. A source entry has $pkgbase, $pkgname, $pkgver and $pkgrel expanded, and a sha256sums entry becomes source-sha256. A local source is copied next to the recipe and its original PKGBUILD line is recorded. A function body ends at the first closing brace that is not quoted and not part of a command or parameter substitution. .PP prepare, build, check and package keep their bodies in Bash, preceded by a prologue that rebuilds the makepkg variables from the exported Holy paths: $pkgdir becomes $HOLY_DEST, $srcdir becomes $HOLY_SRC, $startdir and $builddir become $HOLY_BUILD, and a $pkgdir inside a split step becomes $HOLY_SPLIT_DEST. $srcdest, $pkgdest, CFLAGS, CXXFLAGS, CPPFLAGS, LDFLAGS and MAKEFLAGS are redefined only when the environment leaves them empty. A single source is lifted out of its own name directory so that HOLY_SRC is the makepkg $srcdir. A package_NAME function becomes split-step for the output NAME, and install= fragments are copied into the payload under /usr/share/holy and recorded as a postinstall hook, so pre_install and post_install arrive as one hook. .PP provides, conflicts and replaces, epoch, groups, noextract, validpgpkeys, options, non-SHA-256 checksums and architecture-specific source lists are preserved as x- records or reported as unknown. .SS Void template pkgname, version, revision, short_desc, homepage, license, maintainer and changelog are carried. distfiles is read as a list and $pkgname, $pkgbase, $version, $revision, $sourcepkg and $pkgver are expanded; a checksum entry becomes source-sha256, a leading @ contents digest is reported as unknown, and a local distfile is copied next to the recipe. hostmakedepends, makedepends and checkdepends become build-depend, and depends becomes depend with the same comparator names as the PKGBUILD converter; a virtual? requirement and a build dependency that carries a version are reported as unknown. conf_files becomes config and mutable_files becomes config mutable, and a path with a wildcard needs review. .PP pre_fetch, do_fetch, post_fetch, the extract, patch, configure, build, check and install families keep their Bash and become the matching Holy phase, each behind a prologue that rebuilds the xbps-src variables from the exported paths: $wrksrc and $build_wrksrc become $HOLY_SRC, $masterdir becomes $HOLY_WORK, $XBPS_BUILDDIR becomes $HOLY_BUILD, $XBPS_MAKEJOBS becomes $HOLY_JOBS, and $DESTDIR becomes $HOLY_DEST with $PKGDESTDIR the same, or $HOLY_SPLIT_DEST in a split step. The step changes into $wrksrc first because xbps-src runs a phase there. A distfile is extracted into HOLY_SRC, which therefore takes the place of the xbps-src $wrksrc directory. The v* helpers a body calls are carried into the prologue; vman, vsv, vsed, vcompletion and vsrccopy are reported as unresolved, as is any use of a cross, verbose or chroot variable. .PP A NAME_package function becomes output NAME plus a split step carrying its pkg_install body, so DESTDIR stays the main tree and PKGDESTDIR becomes the staging tree. depends, replaces, conflicts and short_desc set inside that function are reported with their lines rather than moved into the main output, because a Holy recipe has one depend list. A patches directory is archived next to the recipe and applied in the prepare step with a .args file per patch, and a files directory is archived next to it and named by FILESDIR. An INSTALL or REMOVE file becomes one hook and is reported, because a Holy hook runs with ACTION unset and its pre and post branches are not reproduced. .PP build_options are fixed to build_options_default before they reach the recipe, so vopt_if, vopt_with, vopt_enable, vopt_bool and vopt_feature produce their value and a top level vopt_conflict is checked against that same set. The remaining build variables, such as bootstrap, repository, archs, shlib_provides, nostrip and skip_extraction, are preserved as x- records. A phase the template leaves out is reported as supplied by common/build-style/NAME.sh, which the converter does not run, so its result is review-required. A conditional block, a case block or a vopt_conflict is reported with its line, since the converter evaluates none of them. .SS Aports APKBUILD pkgname, pkgver, pkgrel, pkgdesc, url, license and maintainer are carried. arch maps all and noarch to noarch, x86_64 to x86_64 and x86 to i686; any other machine name and a negated architecture are reported. depends becomes depend and makedepends, makedepends_build, makedepends_host and checkdepends become build-depend with the same comparator names as the PKGBUILD converter; a !NAME conflict becomes x-conflicts, a so: or cmd: prefix is reported, and the per subpackage depends_NAME lists are preserved with their lines because a Holy recipe has one depend list. .PP source is read as a list and $pkgname, $pkgver and $pkgrel are expanded, with $pkgver giving the bare upstream version there and version-rrelease in a dependency; a filename::url target name is preserved. A local source is copied next to the recipe and hashed as SHA-256, and a mismatch against a declared sha256sums entry is reported. A remote source is carried with its declared sha256, or reported when there is none, because aports pins sha512sums, which a Holy source cannot use, and the report names every such source. .PP prepare, build, check and package keep their shell and become the matching Holy phase, each behind a prologue that rebuilds the abuild variables from the exported paths: $srcdir becomes $HOLY_SRC, $startdir becomes $HOLY_WORK, DESTDIR becomes $HOLY_DEST with PKGDESTDIR the same, or $HOLY_SPLIT_DEST in a split step, $pkgdir stays the main tree and $subpkgdir becomes the staging tree. $JOBS, $MAKEFLAGS, $SAMUFLAGS, $CMAKE_BUILD_PARALLEL_LEVEL and the other abuild.conf parallel settings are rebuilt from $HOLY_JOBS. The step changes into $builddir first because abuild runs a phase there; a declared builddir is rebased on the source tree and an absent one is the abuild default of $srcdir/$pkgname-$pkgver, which is reported. The extracted tree therefore takes the place of the abuild $srcdir directory, and that lift replaces default_unpack. .PP Each subpackages entry is NAME, NAME:function or NAME:function:arch, and the split function is the named one or the last dash-separated suffix of NAME, with -bash-completion, -zsh-completion and -fish-completion mapping to bashcomp, zshcomp and fishcomp. A split function with a body becomes output NAME plus a split step carrying it; one without a body is reported as needing the abuild default_dev, default_doc, default_static, default_openrc or default_libs helper, which moves files by pattern, so no output is declared for it and a declared architecture is reported. An install entry is post-install, pre-install, pre-upgrade, post-upgrade, pre-deinstall or post-deinstall; the first and the fourth map onto hook-install and hook-remove, are copied into the payload under usr/share/holy/NAME and are reported as a semantic change, since a Holy hook runs with ACTION unset, and the rest are reported as having no Holy hook stage. .PP options, provider_priority, replaces_priority, triggers, install_if, pkggroups, pkgusers, giturl, pcprefix, sonameprefix, langdir, soname, provides and replaces are preserved as x- records. A conditional block is reported with its line, and so is any other top level statement, since abuild sources the file as a shell script and the converter executes none of it. The default_* helpers, the abuild phases the template leaves out, the cross and chroot variables, $CBUILD, $CHOST, $CTARGET and $CARCH are reported as unresolved or unreproduced. .SS SlackBuild script PRGNAM, VERSION, BUILD, TAG and PKGTYPE are carried, whether they are written as NAME=value or as NAME=${NAME:-value}; a computed value is reported instead of guessed. A SlackBuild script is one linear shell program rather than a set of phase functions, so it becomes a single build step, and the prologue rebuilds the variables the script reads: $ARCH becomes $HOLY_ARCH, $CWD and $TMP become $HOLY_SRC, $PKG becomes $HOLY_DEST with $DESTDIR the same, $OUTPUT becomes $HOLY_OUT, and $SLKCFLAGS, $CFLAGS, $CXXFLAGS, $LDFLAGS and $MAKEFLAGS are rebuilt from $HOLY_JOBS. .PP The body runs from the set -e line to the /sbin/makepkg call, and the cd $PKG before that call is left out, because the engine packs the payload. The engine also fetches and unpacks the recorded archive, so a tar line that reads $CWD is reported and left out, as is the rm -rf $PRGNAM-$VERSION that precedes it. The machine the script picks with uname -m becomes $HOLY_ARCH and the LIBDIRSUFFIX it derives per machine becomes empty on x86_64, both reported. The archive name comes from the tar line with $PRGNAM, $VERSION and $BUILD expanded; an archive that is not beside the script is reported, since this format pins an MD5 sum rather than a SHA-256 digest, and a local one is copied next to the recipe and hashed as SHA-256. Every other file the script reads through $CWD travels beside the recipe and is declared as a source, so the engine stages it where $CWD points during a step. .PP slack-desc beside the script carries the summary, the homepage, and the requires and conflicts lists, which become depend and x-conflicts; the other field keys are preserved with their lines. The info file beside the script carries the upstream DOWNLOAD and its MD5SUM, which is reported as unusable. A doinst.sh the script copies into $PKG/install becomes one hook and is copied into the payload, and the $PKG/install tree itself is reported as packaging metadata that stays in the payload as ordinary files. The strip pass, the ownership rewrite, the user and group creation, the loader cache update and the desktop, mime, icon and font cache helpers are reported as unresolved. .SS RPM spec Name, Version, Release, Summary, License and URL are carried. A Version or Release written with a macro in it keeps only its literal part, and the macro is reported, so the value stays what the spec says; a field with no literal text at all is refused. The distribution suffix on Release is left out, which is reported. BuildArch noarch becomes noarch and any other value becomes any, because the payload decides the machine, and ExclusiveArch is preserved. .PP The %global and %define records are collected, and a macro this converter can resolve is expanded everywhere it appears: the identity fields, the path macros such as _sourcedir, _builddir, _topdir and buildroot, and the directory macros such as _bindir and _libdir. A macro that resolves to nothing and is optional is left out, an unresolved one stays in the text and is reported, and a value that is a pattern rather than a word stays inside the body. .PP BuildRequires becomes build-depend and Requires becomes depend, with the same comparator names as the PKGBUILD converter, and the list is read one record per line because an rpm requirement carries its comparison. Provides becomes x-provides, Conflicts and Obsoletes become x-conflicts, and Recommends, Suggests and Enhances become x-suggests, since none of them is a requirement. A requirement that names a file, a rich dependency or an rpmlib capability is reported rather than turned into a record. .PP Source and Patch records name the files the build needs. A local file beside the spec is copied next to the recipe and hashed as SHA-256, and one that is absent is reported, since a spec normally pins no digest at all. The engine fetches and unpacks the recorded sources, so the extracted tree takes the place of _sourcedir. .PP The prep, build, install and check sections become the prepare, build, package and check phases, each behind a prologue that rebuilds the macros the body reads from the exported paths and changes into _sourcedir/NAME-VERSION when the tree was unpacked under that name. %setup, %autosetup and %autopatch become a cd into that directory followed by a patch pass over the declared patches, and %make_install, %make_build and the __ prefixed helpers become the shell line they stand for. Every other rpm section command is reported and left in the body, so the build fails visibly rather than losing a step. An rpm conditional, which this converter does not choose between, is reported with its section. .PP A %package block becomes an output, and because an rpm subpackage is a file list rather than a body, its split step copies the paths its own %files section named out of the main tree. A path that keeps a macro is reported, a %files option such as -f is reported, and a subpackage with no %files list gets no payload. The main %files list is not carried, since it only checks what the install already placed, and that is reported. The %description blocks are not carried. .SS Debian source package A debian directory is recognized by its basename, or named with .BR "import \-\-format debian" . The version comes from the first record of debian/changelog, which is the distribution version rather than the upstream one. It is split at the last dash: an all-numeric tail is the Debian revision and becomes the Holy release, and a version with no such tail is native, so its release is one. Either outcome is reported, as is an epoch, which names a packaging revision order and is dropped. A changelog with no version on its first line is malformed. The source stanza gives the name, the section gives the summary of the main binary package, and Homepage becomes the homepage. .SH A relationship field is a comma separated list of groups, and a group may offer alternatives with a pipe. One Holy depend record names one package, so the first alternative of each group is carried and the rest are reported. Build-Depends and Build-Depends-Indep become build-depend, Depends and Pre-Depends become depend, with the same comparator names as the PKGBUILD converter; a strict comparison becomes lt or gt, and a Debian version has the same epoch and revision, so the version keeps its upstream part. Provides becomes x-provides, Breaks, Conflicts and Replaces become x-conflicts, and Recommends, Suggests and Enhances become x-suggests. A dpkg substitution variable such as $ {misc:Depends} is filled in by dpkg and is reported, and an entry with an architecture qualifier is reported rather than turned into a record. Only the source stanza and the main binary package reach the recipe; a requirement of a subpackage is reported, since that package is built on its own. .SH Each binary stanza becomes an output. A binary that names a file list beside the control file is a subpackage, and because a debian subpackage is a file list rather than a body, its split step copies the paths that list names out of the main tree, which is reported. A .install line is a source and a destination, and a line with no destination names the source itself, so a directory destination is copied whole. A .docs, .manpages and .links list names a path the same way, and a list that names no path is reported instead of written as a split step that would fill no tree. The binary that names no file list is the main output and owns the whole tree. A source with no binary stanza still builds one output, and more than one binary that names no file list is reported, since the converter cannot tell which one is the main tree. .SH debian/rules becomes the build step, behind a prologue that sets DEB_HOST_MULTIARCH and DEB_BUILD_OPTIONS and changes into the source tree. dh is a macro framework rather than a script, so every debhelper call, every debhelper override and dpkg-buildpackage are reported and left in the body, which means the build fails visibly rather than losing a step. The maintainer scripts, debian/copyright, debian/watch and debian/source/format are copied next to the recipe and reported; a lintian-overrides file is reported as well, since it suppresses a report rather than building anything. Standards-Version is preserved. .SS Gentoo ebuild An ebuild is recognized by its .ebuild suffix, or named with .BR "import \-\-format gentoo" . It states its identity in its file name, which is PN-PV-rPR.ebuild, so the name is the text before the last dash a digit follows and the version is what follows it; a trailing -rN is the revision and becomes the Holy release, and a file name with no revision gets release one. An epoch names a packaging revision order rather than a version, so it is preserved and dropped. A file name that carries no version is malformed. EAPI, LICENSE and SLOT are carried, DESCRIPTION is the summary, and HOMEPAGE is the homepage. KEYWORDS names the machines an ebuild is tested on rather than the machine that builds it, so arch is any. .SH The engine fetches and unpacks the recorded sources, so the extracted tree takes the place of WORKDIR, which is reported. A mirror:// entry names no single address and is reported, and a remote archive is reported too, because a Gentoo Manifest pins a BLAKE2B and a SHA-512 rather than the SHA-256 a Holy source needs. A PATCHES entry, and any other file named beside the ebuild, is copied next to the recipe and hashed as SHA-256. An entry behind a USE flag is a file the converter cannot reach, and is reported. .SH A dependency atom is a category, a package and an optional comparison. The category is dropped and the name is what a record holds, a blocker becomes x-conflicts, and a version keeps its upstream part with the same comparator names as the PKGBUILD converter. A ~ atom is a range and a wildcard is not a version, so both are reported; a slot, a use dependency and a virtual, which names an interface rather than a package, are reported as well. RDEPEND and PDEPEND become depend and DEPEND and BDEPEND become build-depend. A USE conditional and an any-of group are reported, since a Holy recipe has no USE flags and cannot choose between the members of a group, and the atoms inside one are carried anyway so the build still holds them. IUSE, REQUIRED_USE, RESTRICT and PROPERTIES are reported as package manager settings. .SH Each standard phase function becomes the matching phase, and a phase the ebuild leaves out is the one the inherited eclasses supply. A body keeps its own shell behind a prologue that rebuilds EPREFIX, ED, D, DESTDIR, WORKDIR, DISTDIR, T, PN, PV, PR, PF, P, PVR, EAPI and changes into the source tree. An eclass is a helper environment, so every inherited one is reported, and so is every ebuild.sh helper a body calls, which means the build fails visibly rather than losing a step. A pkg_preinst, pkg_postinst, pkg_prerm or pkg_postrm function runs at install time through Portage, and a Holy hook carries a script rather than a function, so each is reported. .SS Pacstall pacscript A pacscript is recognized by its .pacscript suffix, or named with .BR "import \-\-format pacstall" . It is bash with a metadata header written as assignments, so pkgname, pkgver, pkgrel, epoch, pkgdesc, url, license, maintainer, repology, arch and gives are carried, with pkgdesc as the summary and url as the homepage. A value written with $pkgname, ${pkgname}, $pkgver, $pkgrel, $gives, $pkgbase or $epoch, or with a variable the same file states in an assignment of its own, is written out, and one that needs the shell to choose a substring is a computed identity and returns 2. An epoch names a packaging revision order rather than a version, so it is preserved and dropped. amd64 and x86_64 become x86_64, i386 and i686 become i686, any and all become any, and a machine Holy does not carry is written as it stands and reported. A list of machines is reported, because the payload decides the machine the recipe is built for. .SH A source entry is NAME::URL, ?NAME::URL or a plain URL, and a sha256sums entry in the same order becomes source-sha256. The engine fetches and unpacks the recorded sources, so the extracted tree takes the place of srcdir, which is reported. A file named beside the pacscript is copied next to the recipe and hashed as SHA-256. A git address is reported, since a Holy source fetches archives, and so is a remote source with no sha256sums entry and a plain http address, since a Holy source is fetched over https. .SH depends, makedepends and checkdepends become depend and build-depend with the comparator names the PKGBUILD converter uses, and a group of alternatives written with a pipe is reported with the first of them carried, since a Holy record cannot choose one. pacdeps become depend as well, and the fact that they name packages of the same pacstall repository is reported, because a Holy resolver has to find them in a source that has them. provides, conflicts, breaks, replaces, enhances, recommends and suggests name no requirement, so they are preserved as x- records, and an optdepends entry becomes x-optdepend with its description. A backup entry becomes config, an r: prefix becomes config mutable and is reported, since a config record only marks a file. A list written per machine or per distribution under a suffixed name is reported, and so is every setting that steers a Pacstall run: priority, external_connection, incompatible, compatible, mask, noextract, custom_fields and ppa. A digest list other than sha256sums is reported, because a Holy source needs SHA-256. .SH prepare, build, check and package become the matching phase, and a body keeps its own shell behind a prologue that rebuilds pkgdir, pacdir, srcdir, startdir, builddir, TARCH, NCPU, pkgname, pkgbase, pkgver, pkgrel, pacname, gives and epoch from the exported Holy paths and changes into the source tree. Every helper the Pacstall environment supplies that a body calls, such as fancy_message, makepkg, parse_options or ask, is reported, and so is a variable of that environment a body reads: KVER, STAGEDIR, homedir, DISTRO, DIR, full_version and pacstall_root. A list of names with a pkgbase is a split pkgbase: every name becomes an output and its package_NAME function becomes the split step that fills it, and a package function beside those is reported. pre_install, pre_upgrade, post_install and post_upgrade become one install hook, and pre_remove and post_remove one remove hook; each hook is written beside the recipe, declared as a source and installed into the payload, and a Holy hook runs with ACTION unset, so the pre and post bodies arrive in the order Pacstall calls them. A conditional block and an assignment inside one are reported, since the converter evaluates neither. .SS Flatpak manifest A manifest is recognized by its .json, .yml or .yaml suffix, or named with .BR "import \-\-format flatpak" . Only the JSON form is read; another form of the same manifest returns 2 rather than a guess. The package name is the last dotted component of the application id, and an id that names a machine and a branch after a slash keeps that reflex in x-app-id while the branch supplies the machine. A version the manifest states is carried and one it does not state records zero, which is reported. summary, url, runtime, sdk, command, branch and the machine are carried; arch is the machine the manifest or its branch names, and any means the machine the build runs on. .PP The sdk is a build requirement and the runtime a runtime requirement, because the SDK that builds the modules and the runtime the program runs on are two different Flatpak ids, and the fact is reported. Each id loses its leading components, since a record names one package. The command is a path under /app, so it is kept as x-flatpak-command, and the prefix of a module becomes /usr. A /app path inside a build command becomes $DESTDIR, so a converted build writes into the payload and nowhere else. .PP The engine fetches and unpacks the recorded sources, so one top directory inside an extracted archive is lifted into place, which is what a module builds in, and the step changes into that tree. An archive with an https address becomes a source with the sha256 the manifest pins, and one named beside the manifest is copied next to the recipe and hashed there. A file, a patch and an inline source travel beside the recipe as well, an inline body becoming a file of its own. A patch applies with -p1 in a prepare step before its module builds, a shell source runs inside the step of its module, and a sed source, a directory, a git, svn or bzr checkout, strip-components, dest-filename and dest are reported. .PP Each module becomes one step in module order. Its build-options export env, cflags, cxxflags, ldflags and cppflags and prepend append-path, and its pre-commands, build-commands, post-install and post-commands keep their shell. A simple module is exactly its commands. The make, autotools, autogen, cmake and meson templates are replaced by the shell that runs the same tools, which is reported, since the template that normally runs them does not travel with the recipe. The cargo template builds without an install step and is reported, and a buildsystem with no Holy phase is a helper the report names rather than a guess. .PP A finish-args permission, a cleanup step, a build extension and a module cleanup are dropped and counted, since a Flatpak sandbox decision has no Holy equivalent. A manifest with more than one module is reported, because a Flatpak build shares one prefix across its modules while each step here installs into the payload, so a later module cannot read an earlier install. .SS Homebrew formula A formula is recognized by its .rb suffix, or named with .BR "import \-\-format homebrew" . It is Ruby, and it is read as text and never evaluated. The class name becomes the package name, and a class that inherits from a cask is reported, since a cask installs an application bundle rather than building a source tree. The description, homepage and license are carried, the url and its sha256 become one pinned source, the revision becomes the release, and a formula that states no version records the version its source url carries before its archive suffix, or zero, which is reported. .PP A depends_on becomes depend and a :build dependency becomes build-depend, while a :recommended or :optional dependency is reported, since a build cannot promise a feature it did not ask for. A resource or a patch block that pins a url and a digest becomes a fetched source, and a patch applies with -p1 in a prepare step. A block that prepares its content with a Ruby expression is a helper the report names. .PP A system call inside def install or on_linux becomes a build step that runs the same command in the source root, because a Homebrew build runs there and a Holy build step starts in the build directory. The Homebrew prefix is rewritten onto the build root: #{prefix} and HOMEBREW_PREFIX become $HOLY_DEST, #{libexec} becomes $HOLY_DEST/libexec, #{etc} and #{var} become $HOLY_DEST/etc and $HOLY_DEST/var, and #{buildpath} becomes $HOLY_BUILD. An interpolation this reader does not model keeps its text and is reported. An engine lift puts the extracted source root where a Homebrew build runs, since the engine extracts an archive under its own name and a distribution tarball keeps one top directory inside it. .PP Every other statement of an install body is Ruby, so it is not translated. The formula is copied beside the recipe as homebrew-install.rb, the build declares a ruby build requirement, and the report names the file and line of each such statement, since a shell step that pretended to run Ruby would be a lie. A head, a mirror, a uses_from_macos framework, an on_macos, on_arm or on_intel block, a bottle block, a service block, a test block and a def other than install are reported: a bottle is a prebuilt foreign binary, a launchd job has no Linux counterpart, a Homebrew test harness does not exist here and a development checkout is not the pinned source. .SS Guix package definition A definition is recognized by its .scm suffix, or named with .BR "import \-\-format guix" . It is Scheme, and it is read as text and never evaluated. The name, version, synopsis, homepage, license and build system are carried, a definition that states no version records zero, which is reported, and a definition whose package form states no name takes the name of its define-public variable, which is reported as a change. .PP An origin becomes one pinned source. A url-fetch is fetched by its uri, a uri written as a string-append becomes the concatenation of its literals and the expression is reported, and the base32 digest a definition writes is decoded into the hex a Holy source records. An origin that is not a url-fetch is reported, since a git or a local origin is a source this converter does not fetch. A definition that states no origin is refused, since a build has no source to fetch. .PP Each name in inputs becomes depend and each name in native-inputs becomes build-depend. A versioned entry contributes only its name, since a version constraint is not a name a record can hold, and the entry is reported. A requirement a definition writes as a name with a range the reader does not walk is reported. .PP The build system becomes the tools it runs. gnu-build-system becomes autoreconf when the source carries configure.ac or configure.in, then configure with the payload prefix, make and make install, since a guix build configures the package prefix and stages the install with DESTDIR. cmake-build-system and meson-build-system become their three commands, and a build system this reader does not replace, and the trivial one whose procedure is a Scheme body, are reported. An engine lift puts the extracted source root where a guix build runs, since the engine extracts an archive under its own name and a distribution tarball keeps one top directory inside it. .PP A #:configure-flags, #:make-flags or #:install-flags argument whose entries are literal strings becomes the flags of the phase that takes them; an argument whose entry is a Scheme expression keeps its text and is reported. A #:phases argument replaces the build system phases, a #:tests? that turns the suite off is reported as a change, and a patch-shebang and any expression the reader does not evaluate, such as a modulo, are reported. .SH CONVERSION REPORTThe report lists every carried, preserved, helper, unknown and changed item with its source file and line range, and its status is native or review-required. A review-required conversion returns 3 with the recipe written, since review is a statement about execution, not about whether the text could be carried. A missing identity, a computed identity or malformed text returns 2; an unreadable input returns 6. .SH RESULTS Each output artifact is written to the output directory. Its manifest is regenerated from the copied payload. HOLY/meta records format, name, version, release, os, arch, libc, x-version-family holy, x-build-target and installed-size, plus any x- record. HOLY/deps carries declared depend records plus one soname requirement per DT_NEEDED entry, each attributed to the file that needs it and written only into the output that carries that file. HOLY/provides records the package name and the SONAME of every shared object in the payload. HOLY/hooks records a declared hook only in the output whose payload holds its script, and the build fails if an output declares a hook it does not carry. HOLY/origin records the recipe inputs with their pinned digests and verification built-locally. HOLY/transform records the build environment and the declared build dependencies. The finished .holy is installed by a normal transaction; the build itself never writes to the target root. .SH EXAMPLES .nf format holy-recipe-1 name example version 1.0 release 1 arch x86_64 libc glibc summary Example package build-depend "toolchain:x86_64-linux-gnu" build-depend cmd:make source src "https://example.org/example-1.0.tar.xz" source-sha256 src "0000000000000000000000000000000000000000000000000000000000000000" output example runtime output example-doc docs split example-doc usr/share/doc/* step build /bin/sh <