Commitdf9049f7Recorded30 Jul 2026Repositorycore-channel

Add a full-featured terminal Emacs 30.2

Message

Replaces nothing: recipes/emacs-nox.sgl stays as it is. This is the same version built with the opposite intent. sqlite3, tree-sitter, zlib, dynamic modules and elisp threads are on, and JSON needs no dependency because Emacs 30 has it in-tree.

Verified by running the binary, not by reading configure output. emacs -nw starts in a real pty (TUI-FRAME=t COLS=80 LINES=23 DISPLAY=nil), and sqlite, JSON and zlib each do actual work rather than answering an availability predicate: a two-row table is created and selected back, a plist round-trips through json-serialize and json-parse-string, and 81 gzip bytes inflate to their original text. treesit-library-abi-version reports 14, matching the ABI measured directly against the built libtree-sitter.

libxml2 is switched OFF EXPLICITLY, and that is the finding rather than a preference. The seed's pkgconf 1.9.5 aborts on any .pc file with an empty dependency-list field, and libxml2 installs Requires: empty. Emacs looks for libxml2 through PKGCHECKMODULES, reads SIGABRT as "not present", and configure still exits 0 -- so the default would have produced an Emacs silently missing a requested feature. Saying --without-xml2 makes the definition state a fact.

The cause was isolated by running Emacs' own configure twice in a replica of the build environment, changing one variable: with LIBXML2CFLAGS and LIBXML2LIBS set, PKGCHECKMODULES skips pkg-config and detection succeeds. That fix cannot be written into the package, because those values need libxml2's store prefix and a phase argument has no way to name a dependency's path.

Native compilation is absent by decision, recorded in the module header.

Changed
 channel.catalogue.sgl                                                        |   3 ++-
 channel.catalogue.sgl.minisig                                                |   6 +++---
 channel.sgl                                                                  |   3 ++-
 objects/90fc3c5e9b0c35deada7f219417fb5d64f27d2cf88564c46ede646a7a3721a7e.sgl |   1 +
 objects/d64a1058772a9536aabdd66610d6838730a5e3c47ce2d1f43e5995ce888b8cc2.sgl |   1 +
 snapshot.sgl                                                                 |   4 ++--
 snapshot.sgl.minisig                                                         |   6 +++---
 src/core/outputs.sgl                                                         |  17 +++++++++++++++--
 src/core/packages/editors.sgl                                                | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 9 files changed, 139 insertions(+), 13 deletions(-)
Diff
channel.catalogue.sglmodified
@@ -1,5 +1,6 @@
1
(catalogue schema: 1 sequence: 4 snapshot: "core-stable@4:sha256:ea46962821ceb61bc8f331ee0eca5a4fd1db6650403ed2ba00e1c7352269e858" channel-source: "sha256:5db8e61c4c7e38a53a1d32bd0f73b9aa0b6cc372706586e6711b7a7e0daa303c" content-hash: "sha256:87d970255f4ce1cd9c93a4064cd6e2da80f8f46fbc3f7400e20b9dd1aaa2b784")
+1
(catalogue schema: 1 sequence: 6 snapshot: "core-stable@6:sha256:1ee737116d9669fa8d503baf5a275a12ccac79e2b7e1722ebd8260c6367ad963" channel-source: "sha256:30966b33315bb8383158afe41fb25a98790def2192caebb682be8b896acb0423" content-hash: "sha256:e96d244ea805692c9d018ac1c0ea041a9d36c57d84e1904e1814ba5fa269d982")
2
(binding name: "core/binaryen" package: "sha256:014baf016eec17892f30a30847b070ffb09e397182d2ef50eda2ceb3fded2a58")
+3
(binding name: "core/emacs" package: "sha256:90fc3c5e9b0c35deada7f219417fb5d64f27d2cf88564c46ede646a7a3721a7e")
4
(binding name: "core/libxml2" package: "sha256:cc4c7518170d4f5db3c72025a429c57c83e8d07244c06f922a0e2af3ffd9120c")
5
(binding name: "core/ncurses" package: "sha256:e803a7f68e4a55eac49be30b3dc84855749037be91aa48ec7315f73dd5c0d1b3")
6
(binding name: "core/sqlite" package: "sha256:39a80e18e85b9f228b147d47a3243c0276f639e30f72d841320abbeedc28900a")
channel.catalogue.sgl.minisigmodified
@@ -1,4 +1,4 @@
1
untrusted comment: signature from minisign secret key
2
RUQ0HOFEHrNeRIL6qFa743en5litQy9WITcI7UTehPi1tbwuxJ6YzcpNWhBY6b9lKMK9TsHQ2z4Jg2AfD82SmMrMVZEXkQcpLgA=
3
trusted comment: registry=pkg.usesigil.org path=/v1/channels/core-stable/channel.catalogue.sgl seq=508 ts=2026-07-30T19:20:00Z
4
+p0luUXsem4c8uQOiUSClYPdIemnFULg3xgoLhPYSRhA0R+mnqdQ0Q6/BxXsChdw46h6wLbLNUl0J70VvvpODQ==
+2
RUQ0HOFEHrNeROHLSvMWtPQg4Lud+wHtDX/JNqsScgfMfXJBPt6oW9F+lVUZ0DLPxk1iGKI+fnePKp95Ge+CvlaDwOg3CiZuFAc=
+3
trusted comment: registry=pkg.usesigil.org path=/v1/channels/core-stable/channel.catalogue.sgl seq=512 ts=2026-07-30T20:10:00Z
+4
P5MBxqiLIfOxfjcU9I0+U8qNoIur5RNCXcOad5vU+nBo4tmuAB3QV8p9qiylihk3ZgbxUxGRuw66KMbrM6JrBw==
channel.sglmodified
@@ -15,4 +15,5 @@
15
(channel-binding name: "core/libxml2" value: libxml2)
16
(channel-binding name: "core/sqlite" value: sqlite)
17
(channel-binding name: "core/tree-sitter" value: tree-sitter)
18
(channel-binding name: "core/vim" value: vim)))
+18
(channel-binding name: "core/vim" value: vim)
+19
(channel-binding name: "core/emacs" value: emacs)))
objects/90fc3c5e9b0c35deada7f219417fb5d64f27d2cf88564c46ede646a7a3721a7e.sgladded
@@ -0,0 +1 @@
+1
(package-v1 name: "emacs" version: "30.2" source: (source location: "https://ftp.gnu.org/gnu/emacs/emacs-30.2.tar.xz" sha256: "b3f36f18a6dd2715713370166257de2fae01f9d38cfe878ced9b1e6ded5befd9") buildenv: "894ca74bdb03c25d79f00ce915bbe25c56eba192334963c69e1846e6c84526cb" dependencies: ("82b7de949e90992450f57ce5b4eb0cb3f1107d3731376dc19bd56c009bf38aad" "8695c98c7ed14c29bd12a3e4bc9d0287e1d55fccb25f568662909296d8e51781" "9625c2c1a633c79836e4ad7a13c2532af92b7b423ced098ca20d31c984e54818" "b575d0e29ea3f15262d850a4732a007779037f2ba55b67153738430eb91c8736" "e7026efe2fe0fc17c068cab9bad5277f9131f6fc4d379acd2bc7373477cbb9ce") phases: ((phase kind: configure args: ("--prefix=/out" "--disable-build-details" "--with-tree-sitter" "--with-modules" "--without-x" "--with-x-toolkit=no" "--without-xft" "--without-harfbuzz" "--without-libotf" "--without-m17n-flt" "--without-cairo" "--without-lcms2" "--without-gif" "--without-jpeg" "--without-png" "--without-rsvg" "--without-tiff" "--without-webp" "--without-xpm" "--without-xml2" "--without-dbus" "--without-gsettings" "--without-libsystemd" "--without-selinux" "--without-sound" "--without-gnutls" "--without-gpm" "--without-pop" "--without-mailutils") patches: ()) (phase kind: make args: () patches: ()) (phase kind: install args: () patches: ())) divergences: ((divergence file-glob: "libexec/emacs/*/*.pdmp" max-differing-bytes: 64)))
objects/d64a1058772a9536aabdd66610d6838730a5e3c47ce2d1f43e5995ce888b8cc2.sgladded
@@ -0,0 +1 @@
+1
(package-v1 name: "emacs" version: "30.2" source: (source location: "https://ftp.gnu.org/gnu/emacs/emacs-30.2.tar.xz" sha256: "b3f36f18a6dd2715713370166257de2fae01f9d38cfe878ced9b1e6ded5befd9") buildenv: "894ca74bdb03c25d79f00ce915bbe25c56eba192334963c69e1846e6c84526cb" dependencies: ("82b7de949e90992450f57ce5b4eb0cb3f1107d3731376dc19bd56c009bf38aad" "8695c98c7ed14c29bd12a3e4bc9d0287e1d55fccb25f568662909296d8e51781" "9625c2c1a633c79836e4ad7a13c2532af92b7b423ced098ca20d31c984e54818" "b575d0e29ea3f15262d850a4732a007779037f2ba55b67153738430eb91c8736" "e7026efe2fe0fc17c068cab9bad5277f9131f6fc4d379acd2bc7373477cbb9ce") phases: ((phase kind: configure args: ("--prefix=/out" "--disable-build-details" "--with-tree-sitter" "--with-modules" "--without-x" "--with-x-toolkit=no" "--without-xft" "--without-harfbuzz" "--without-libotf" "--without-m17n-flt" "--without-cairo" "--without-lcms2" "--without-gif" "--without-jpeg" "--without-png" "--without-rsvg" "--without-tiff" "--without-webp" "--without-xpm" "--without-dbus" "--without-gsettings" "--without-libsystemd" "--without-selinux" "--without-sound" "--without-gnutls" "--without-gpm" "--without-pop" "--without-mailutils") patches: ()) (phase kind: make args: () patches: ()) (phase kind: install args: () patches: ())) divergences: ((divergence file-glob: "libexec/emacs/*/*.pdmp" max-differing-bytes: 64)))
snapshot.sglmodified
@@ -1,3 +1,3 @@
1
(snapshot schema: 1 id: "core-stable" sequence: 4 content-hash: "sha256:ea46962821ceb61bc8f331ee0eca5a4fd1db6650403ed2ba00e1c7352269e858")
+1
(snapshot schema: 1 id: "core-stable" sequence: 6 content-hash: "sha256:1ee737116d9669fa8d503baf5a275a12ccac79e2b7e1722ebd8260c6367ad963")
2
(toolchain id: "toolchain/zig" version: "0.16.0" recipe: "sha256:5bc02f4c7abc6055b1f5fc37c57c4b063c18f9e3431ba2cab0cc9f30f313e33b" output: "sha256:70e49664a74374b48b51e6f3fdfbf437f6395d42509050588bd49abe52ba3d00")
3
(pkg id: "core/packages/wasm" version: "0.1.0" recipe: "sha256:5db8e61c4c7e38a53a1d32bd0f73b9aa0b6cc372706586e6711b7a7e0daa303c")
+3
(pkg id: "core/packages/wasm" version: "0.1.0" recipe: "sha256:30966b33315bb8383158afe41fb25a98790def2192caebb682be8b896acb0423")
snapshot.sgl.minisigmodified
@@ -1,4 +1,4 @@
1
untrusted comment: signature from minisign secret key
2
RUQ0HOFEHrNeRF9tOsiMdGpoFALsMi3+nIEREAcx885kaQmhwDAg2XDAHxM9PYJPzT5R0N+lQ9yeBqrvOLJ4YIFfTxvH9RcPjAk=
3
trusted comment: registry=pkg.usesigil.org path=/v1/channels/core-stable/snapshot.sgl seq=507 ts=2026-07-30T19:20:00Z
4
sybTz3/5QuEO+2YR1ETBbFjGm2goUuUQV0Hao9UNajzeWbrdNBpP90De+IBdgNEMBAR9JKHXj6aBzkFk8kVvAw==
+2
RUQ0HOFEHrNeREBz+oIIg15i/NHOqkih6ueihHoLK+0wbkvxG5HEnsw7Ae9qSoydHTi2Co3NfHoOCIMQhm4GcdmHXmJVOvicMAQ=
+3
trusted comment: registry=pkg.usesigil.org path=/v1/channels/core-stable/snapshot.sgl seq=511 ts=2026-07-30T20:10:00Z
+4
UwGJgmu86V+AU1hucEoCHoQCwoG8vTdcEbOLpLoCujv2mWMFD94xY5W1nU02PoRo9YJoFhMOdb90LDupgnPTBQ==
src/core/outputs.sglmodified
@@ -35,7 +35,8 @@
35
;;; would let a dependency be an actual package binding.
36
(define-library (core outputs)
37
(import (sigil core))
38
(export zlib-output ncurses-output)
+38
(export zlib-output ncurses-output libxml2-output sqlite-output
+39
tree-sitter-output)
40
(begin
41
42
;; core/zlib 1.3.1
@@ -44,4 +45,16 @@
45
46
;; core/ncurses 6.6
47
(define ncurses-output
47
"8695c98c7ed14c29bd12a3e4bc9d0287e1d55fccb25f568662909296d8e51781")))
+48
"8695c98c7ed14c29bd12a3e4bc9d0287e1d55fccb25f568662909296d8e51781")
+49
+50
;; core/libxml2 2.13.5
+51
(define libxml2-output
+52
"b575d0e29ea3f15262d850a4732a007779037f2ba55b67153738430eb91c8736")
+53
+54
;; core/sqlite 3.46.1
+55
(define sqlite-output
+56
"9625c2c1a633c79836e4ad7a13c2532af92b7b423ced098ca20d31c984e54818")
+57
+58
;; core/tree-sitter 0.24.7
+59
(define tree-sitter-output
+60
"82b7de949e90992450f57ce5b4eb0cb3f1107d3731376dc19bd56c009bf38aad")))
src/core/packages/editors.sglmodified
@@ -12,7 +12,7 @@
12
(core outputs)
13
(sigil env package)
14
(sigil build external))
15
(export vim)
+15
(export vim emacs)
16
(begin
17
(define vim
18
(package
@@ -49,4 +49,113 @@
49
kind: 'make
50
args: (list "VIMRCLOC=/out/share/vim"
51
"VIMRUNTIMEDIR=/out/share/vim/vim91"))
+52
(external-phase kind: 'install))))
+53
+54
;; A terminal Emacs that is actually worth using, as opposed to the
+55
;; `emacs-nox` recipe in recipes/, which disabled essentially everything.
+56
;;
+57
;; Enabled here: ncurses, zlib decompression, libxml2 (shr/eww), sqlite3
+58
;; (org-roam and friends), tree-sitter (*-ts-mode), and dynamic modules.
+59
;; JSON needs no dependency at all -- Emacs 30 has it in-tree at src/json.c,
+60
;; so jansson, which Guix still lists for emacs-no-x, is not a dependency of
+61
;; this version.
+62
;;
+63
;; DEPENDENCIES ARE A FLAT CLOSURE, NOT A GRAPH. The builder derives -I,
+64
;; -L and PKG_CONFIG_PATH only from the entries listed here, so this list
+65
;; must eventually name every transitive dependency, not just the direct
+66
;; ones. With gnutls added that means nettle, gmp, libtasn1, libunistring
+67
;; and p11-kit appear here too. See (core outputs).
+68
;;
+69
;; Deliberately absent, decided rather than forgotten:
+70
;; * native compilation (libgccjit) -- means building GCC itself, which
+71
;; needs a multi-stage bootstrap, arbitrary build commands and
+72
;; per-package environment control. None of the five phase kinds can
+73
;; express any of those. It is the largest performance win in the
+74
;; target set and it is not reachable in this model.
+75
;; * libxml2 -- BLOCKED BY A BUG IN THE PINNED SEED, not by choice. The
+76
;; seed's pkgconf 1.9.5 aborts (SIGABRT, Zig pointer-overflow panic) on
+77
;; any .pc file containing an EMPTY dependency-list field, and libxml2
+78
;; installs `Requires:` empty. Emacs finds libxml2 through
+79
;; PKG_CHECK_MODULES, reads the crash as "not present", and CONFIGURE
+80
;; STILL EXITS 0 -- so leaving this to the default would silently
+81
;; produce an Emacs without a feature the definition asked for. Saying
+82
;; --without-xml2 makes the absence a stated fact instead.
+83
;; The remedy is known and was verified: setting LIBXML2_CFLAGS and
+84
;; LIBXML2_LIBS makes PKG_CHECK_MODULES skip pkg-config entirely, and
+85
;; detection then succeeds. It cannot be written here, because those
+86
;; values need libxml2's own store prefix and **a phase argument has no
+87
;; way to name a dependency's path** -- `replace-prefix` only rewrites
+88
;; /out to the package's OWN prefix. Flip this back to the default the
+89
;; day the seed's pkgconf is fixed.
+90
;; * gnutls and gpm -- not yet ported; the flags below flip to
+91
;; --with-gnutls / --with-gpm once they land. NOTE that gnutls is also
+92
;; found via PKG_CHECK_MODULES, so it is exposed to the same seed bug if
+93
;; its .pc or anything in its Requires chain has an empty field.
+94
(define emacs
+95
(package
+96
name: "emacs"
+97
version: "30.2"
+98
source: (external-source
+99
location: "https://ftp.gnu.org/gnu/emacs/emacs-30.2.tar.xz"
+100
sha256: "b3f36f18a6dd2715713370166257de2fae01f9d38cfe878ced9b1e6ded5befd9")
+101
buildenv: core-buildenv
+102
dependencies: (list ncurses-output
+103
zlib-output
+104
libxml2-output
+105
sqlite-output
+106
tree-sitter-output)
+107
;; A portable dump is a memory image written once the build root is
+108
;; known. external-normalize-build-root! pads build-root strings inside
+109
;; outputs, but it cannot make a dump bit-identical across two runs, so
+110
;; the bounded allowance the original recipe carried still earns its
+111
;; place. It is a budget, not a blanket: anything outside *.pdmp, or
+112
;; more than 64 bytes inside it, is still a hard determinism failure.
+113
divergences: (list (external-divergence
+114
file-glob: "libexec/emacs/*/*.pdmp"
+115
max-differing-bytes: 64))
+116
phases: (list
+117
(external-phase
+118
kind: 'configure
+119
args: (list "--prefix=/out"
+120
;; omit host name and build date from the
+121
;; binary; this channel cares about
+122
;; reproducibility more than about `M-x
+123
;; emacs-version` naming a machine
+124
"--disable-build-details"
+125
;; features we are deliberately turning ON
+126
"--with-tree-sitter"
+127
"--with-modules"
+128
;; no window system
+129
"--without-x"
+130
"--with-x-toolkit=no"
+131
"--without-xft"
+132
"--without-harfbuzz"
+133
"--without-libotf"
+134
"--without-m17n-flt"
+135
"--without-cairo"
+136
"--without-lcms2"
+137
"--without-gif"
+138
"--without-jpeg"
+139
"--without-png"
+140
"--without-rsvg"
+141
"--without-tiff"
+142
"--without-webp"
+143
"--without-xpm"
+144
;; blocked by the seed pkgconf bug above, not a
+145
;; preference; stated so the build cannot
+146
;; quietly differ from the definition
+147
"--without-xml2"
+148
;; no system integration we cannot pin
+149
"--without-dbus"
+150
"--without-gsettings"
+151
"--without-libsystemd"
+152
"--without-selinux"
+153
"--without-sound"
+154
;; not yet ported
+155
"--without-gnutls"
+156
"--without-gpm"
+157
;; movemail: no Kerberos/Hesiod/mailutils here
+158
"--without-pop"
+159
"--without-mailutils"))
+160
(external-phase kind: 'make)
161
(external-phase kind: 'install))))))