Recover dev-tool packages for Fruix

This commit is contained in:
2026-04-08 19:03:31 +02:00
parent 60ac1c0b85
commit dc1c3fa33d
4 changed files with 402 additions and 3 deletions
+158 -2
View File
@@ -53,6 +53,11 @@
freebsd-zlib
freebsd-sh
freebsd-bash
freebsd-nodejs
freebsd-npm
freebsd-ripgrep
freebsd-tmux
freebsd-neovim
freebsd-native-kernel
freebsd-native-world
freebsd-native-runtime
@@ -97,6 +102,23 @@
(make-freebsd-package name version build-system inputs home-page synopsis
description license install-plan))
(define (path-directory path)
(let ((index (string-index-right path #\/)))
(if index
(substring path 0 index)
".")))
(define (file-install-plan source target)
`((file ,source ,target)))
(define (shared-library-install-plan source target)
(let ((link-target (false-if-exception (readlink source))))
(if link-target
(list `(file ,(string-append (path-directory source) "/" link-target)
,(string-append (path-directory target) "/" link-target))
`(file ,source ,target))
(file-install-plan source target))))
(define freebsd-release "15.0-STABLE")
(define-record-type <freebsd-source>
@@ -585,6 +607,133 @@ library for profile experiments."
#:install-plan
'((file "/lib/libz.so.6" "lib/libz.so.6"))))
(define freebsd-nodejs
(freebsd-package
#:name "freebsd-nodejs"
#:version "24.14.0_2"
#:build-system 'copy-build-system
#:inputs (list freebsd-libc freebsd-openssl freebsd-zlib)
#:home-page "https://nodejs.org/"
#:synopsis "Node.js runtime staged from FreeBSD packages"
#:description
"Host-staged Node.js package definition that copies the FreeBSD package
manager build into the Fruix store, including the shared libraries and
headers needed to run Node and build native modules."
#:license 'expat
#:install-plan
(append
'((file "/usr/local/bin/node" "bin/node")
(directory "/usr/local/include/node" "include/node")
(file "/usr/local/share/man/man1/node.1.gz" "share/man/man1/node.1.gz"))
(shared-library-install-plan "/usr/local/lib/libada.so.3" "lib/libada.so.3")
(shared-library-install-plan "/usr/local/lib/libbrotlicommon.so.1" "lib/libbrotlicommon.so.1")
(shared-library-install-plan "/usr/local/lib/libbrotlidec.so.1" "lib/libbrotlidec.so.1")
(shared-library-install-plan "/usr/local/lib/libbrotlienc.so.1" "lib/libbrotlienc.so.1")
(shared-library-install-plan "/usr/local/lib/libcares.so.2" "lib/libcares.so.2")
(shared-library-install-plan "/usr/local/lib/libgtest.so.1.16.0" "lib/libgtest.so.1.16.0")
(shared-library-install-plan "/usr/local/lib/libhdr_histogram.so.6" "lib/libhdr_histogram.so.6")
(shared-library-install-plan "/usr/local/lib/libicudata.so.76" "lib/libicudata.so.76")
(shared-library-install-plan "/usr/local/lib/libicui18n.so.76" "lib/libicui18n.so.76")
(shared-library-install-plan "/usr/local/lib/libicuuc.so.76" "lib/libicuuc.so.76")
(shared-library-install-plan "/usr/local/lib/libllhttp.so.9.3" "lib/libllhttp.so.9.3")
(shared-library-install-plan "/usr/local/lib/libmerve.so.1" "lib/libmerve.so.1")
(shared-library-install-plan "/usr/local/lib/libnbytes.so" "lib/libnbytes.so")
(shared-library-install-plan "/usr/local/lib/libnghttp2.so.14" "lib/libnghttp2.so.14")
(shared-library-install-plan "/usr/local/lib/libnghttp3.so.9" "lib/libnghttp3.so.9")
(shared-library-install-plan "/usr/local/lib/libngtcp2.so.16" "lib/libngtcp2.so.16")
(shared-library-install-plan "/usr/local/lib/libsimdjson.so.32" "lib/libsimdjson.so.32")
(shared-library-install-plan "/usr/local/lib/libsimdutf.so.33" "lib/libsimdutf.so.33")
(shared-library-install-plan "/usr/local/lib/libsqlite3.so.0" "lib/libsqlite3.so.0")
(shared-library-install-plan "/usr/local/lib/libuv.so.1" "lib/libuv.so.1")
(shared-library-install-plan "/usr/local/lib/libuvwasi.so" "lib/libuvwasi.so")
(shared-library-install-plan "/usr/local/lib/libzstd.so.1" "lib/libzstd.so.1"))))
(define freebsd-npm
(freebsd-package
#:name "freebsd-npm"
#:version "11.11.0"
#:build-system 'copy-build-system
#:inputs (list freebsd-nodejs freebsd-bash)
#:home-page "https://www.npmjs.com/"
#:synopsis "npm CLI staged from FreeBSD packages"
#:description
"Host-staged npm package definition that copies the npm CLI, bundled
Node modules, and default configuration needed for local project installs and
npm exec workflows inside Fruix."
#:license 'artistic2.0
#:install-plan
'((file "/usr/local/bin/npm" "bin/npm")
(file "/usr/local/bin/npx" "bin/npx")
(file "/usr/local/bin/node-gyp" "bin/node-gyp")
(file "/usr/local/etc/npmrc" "etc/npmrc")
(file "/usr/local/etc/man.d/npm.conf" "etc/man.d/npm.conf")
(directory "/usr/local/lib/node_modules/npm" "lib/node_modules/npm"))))
(define freebsd-ripgrep
(freebsd-package
#:name "freebsd-ripgrep"
#:version "15.1.0_4"
#:build-system 'copy-build-system
#:inputs (list freebsd-libc)
#:home-page "https://github.com/BurntSushi/ripgrep"
#:synopsis "ripgrep staged from FreeBSD packages"
#:description
"Host-staged ripgrep package definition that copies the rg executable,
manual page, and PCRE2 shared library dependency into the Fruix store."
#:license 'expat
#:install-plan
(append
'((file "/usr/local/bin/rg" "bin/rg")
(file "/usr/local/share/man/man1/rg.1.gz" "share/man/man1/rg.1.gz"))
(shared-library-install-plan "/usr/local/lib/libpcre2-8.so.0" "lib/libpcre2-8.so.0"))))
(define freebsd-tmux
(freebsd-package
#:name "freebsd-tmux"
#:version "3.6a"
#:build-system 'copy-build-system
#:inputs (list freebsd-libc)
#:home-page "https://github.com/tmux/tmux"
#:synopsis "tmux staged from FreeBSD packages"
#:description
"Host-staged tmux package definition that copies the tmux terminal
multiplexer, example configuration, manual page, and libevent dependency into
the Fruix store."
#:license 'isc
#:install-plan
(append
'((file "/usr/local/bin/tmux" "bin/tmux")
(file "/usr/local/share/examples/tmux/example_tmux.conf"
"share/examples/tmux/example_tmux.conf")
(file "/usr/local/share/man/man1/tmux.1.gz" "share/man/man1/tmux.1.gz"))
(shared-library-install-plan "/usr/local/lib/libevent_core-2.1.so.7"
"lib/libevent_core-2.1.so.7"))))
(define freebsd-neovim
(freebsd-package
#:name "freebsd-neovim"
#:version "0.12.0"
#:build-system 'copy-build-system
#:inputs (list freebsd-libc)
#:home-page "https://neovim.io/"
#:synopsis "Neovim staged from FreeBSD packages"
#:description
"Host-staged Neovim package definition that copies the editor binary,
runtime files, parser modules, Lua modules, and shared libraries needed to run
Neovim from a Fruix profile."
#:license 'asl2.0
#:install-plan
(append
'((file "/usr/local/bin/nvim" "bin/nvim")
(file "/usr/local/share/man/man1/nvim.1.gz" "share/man/man1/nvim.1.gz")
(directory "/usr/local/share/nvim" "share/nvim")
(directory "/usr/local/lib/nvim" "lib/nvim")
(file "/usr/local/lib/lua/5.1/lpeg.so" "lib/lua/5.1/lpeg.so"))
(shared-library-install-plan "/usr/local/lib/libintl.so.8" "lib/libintl.so.8")
(shared-library-install-plan "/usr/local/lib/libluv.so.1" "lib/libluv.so.1")
(shared-library-install-plan "/usr/local/lib/libutf8proc.so.3" "lib/libutf8proc.so.3")
(shared-library-install-plan "/usr/local/lib/libuv.so.1" "lib/libuv.so.1"))))
(define default-native-world-prune-paths
'("usr/share/doc"
"usr/share/examples"
@@ -765,7 +914,12 @@ FreeBSD base input."
freebsd-openssl
freebsd-zlib
freebsd-sh
freebsd-bash))
freebsd-bash
freebsd-nodejs
freebsd-npm
freebsd-ripgrep
freebsd-tmux
freebsd-neovim))
(define %freebsd-host-staged-system-packages
(list freebsd-kernel
@@ -797,7 +951,9 @@ FreeBSD base input."
(second-wave . (freebsd-runtime freebsd-libc freebsd-userland freebsd-rc-scripts))
(third-wave . (freebsd-networking freebsd-openssh))
(fourth-wave . (freebsd-kernel-headers freebsd-clang-toolchain))
(fifth-wave . (freebsd-gmake freebsd-autotools freebsd-openssl freebsd-zlib freebsd-sh freebsd-bash))))
(fifth-wave . (freebsd-gmake freebsd-autotools freebsd-openssl freebsd-zlib
freebsd-sh freebsd-bash freebsd-nodejs freebsd-npm
freebsd-ripgrep freebsd-tmux freebsd-neovim))))
(define (freebsd-native-system-packages-for base)
(list (freebsd-native-runtime-for base)))
+12 -1
View File
@@ -1093,6 +1093,11 @@
"export CFLAGS=\"-I$profile/usr/include\"\n"
"export CXXFLAGS=\"-I$profile/usr/include\"\n"
"export LDFLAGS=\"-L$profile/lib\"\n"
"export LD_LIBRARY_PATH=\"$profile/lib:$profile/usr/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\"\n"
"export MANPATH=\"$profile/share/man:$profile/usr/share/man${MANPATH:+:$MANPATH}\"\n"
"export NODE_PATH=\"$profile/lib/node_modules${NODE_PATH:+:$NODE_PATH}\"\n"
"export VIMRUNTIME=\"$profile/share/nvim/runtime\"\n"
"export LUA_CPATH=\"$profile/lib/lua/5.1/?.so${LUA_CPATH:+;$LUA_CPATH};;\"\n"
"export MAKEFLAGS=\"-m $profile/usr/share/mk\"\n"
"export PATH=\"/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$profile/bin:$profile/sbin:$profile/usr/bin:$profile/usr/sbin\"\n"
"EOF\n"))
@@ -1106,7 +1111,8 @@
" exit 1\n"
"}\n"
"cat <<EOF\n"
"unset MAKEOBJDIRPREFIX MAKEFLAGS CC CXX AR RANLIB NM CPPFLAGS CFLAGS CXXFLAGS LDFLAGS\n"
"unset MAKEOBJDIRPREFIX MAKEFLAGS CC CXX AR RANLIB NM CPPFLAGS CFLAGS CXXFLAGS LDFLAGS LD_LIBRARY_PATH\n"
"unset MANPATH NODE_PATH VIMRUNTIME LUA_CPATH\n"
"unset FRUIX_DEVELOPMENT_PROFILE FRUIX_DEVELOPMENT_INCLUDE FRUIX_DEVELOPMENT_LIB FRUIX_DEVELOPMENT_SHARE_MK\n"
"unset FRUIX_DEVELOPMENT_BIN FRUIX_DEVELOPMENT_USR_BIN FRUIX_CC FRUIX_CXX FRUIX_AR FRUIX_RANLIB FRUIX_NM FRUIX_BMAKE\n"
"export FRUIX_BUILD_PROFILE=\"$profile\"\n"
@@ -1121,6 +1127,11 @@
"export FRUIX_BUILD_RANLIB=\"$profile/bin/ranlib\"\n"
"export FRUIX_BUILD_NM=\"$profile/bin/nm\"\n"
"export FRUIX_BMAKE=\"make\"\n"
"export LD_LIBRARY_PATH=\"$profile/lib:$profile/usr/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\"\n"
"export MANPATH=\"$profile/share/man:$profile/usr/share/man${MANPATH:+:$MANPATH}\"\n"
"export NODE_PATH=\"$profile/lib/node_modules${NODE_PATH:+:$NODE_PATH}\"\n"
"export VIMRUNTIME=\"$profile/share/nvim/runtime\"\n"
"export LUA_CPATH=\"$profile/lib/lua/5.1/?.so${LUA_CPATH:+;$LUA_CPATH};;\"\n"
"export PATH=\"/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$profile/bin:$profile/sbin:$profile/usr/bin:$profile/usr/sbin\"\n"
"EOF\n"))
(define (render-self-hosted-native-build-script os)
+217
View File
@@ -0,0 +1,217 @@
(use-modules (ice-9 hash-table)
(ice-9 match)
(srfi srfi-1)
(srfi srfi-13)
(srfi srfi-64)
(guix build utils)
(fruix packages freebsd)
(fruix system freebsd)
(fruix system freebsd build)
(fruix system freebsd render)
(fruix system freebsd utils))
(define dev-tool-packages
(list freebsd-nodejs
freebsd-npm
freebsd-ripgrep
freebsd-tmux
freebsd-neovim))
(define os
(operating-system #:development-packages dev-tool-packages
#:build-packages dev-tool-packages))
(define generated-files
(operating-system-generated-files os
#:guile-store "/tmp/test-guile"
#:guile-extra-store "/tmp/test-guile-extra"
#:shepherd-store "/tmp/test-shepherd"
#:guile-newt-store "/tmp/test-guile-newt"))
(define development-script
(assoc-ref generated-files "usr/local/bin/fruix-development-environment"))
(define build-script
(assoc-ref generated-files "usr/local/bin/fruix-build-environment"))
(define (install-targets package)
(map (lambda (entry)
(match entry
((_ _ target) target)))
(freebsd-package-install-plan package)))
(define (package-present? package packages)
(member (freebsd-package-name package)
(map freebsd-package-name packages)))
(define (path-directory path)
(let ((index (string-index-right path #\/)))
(if index
(substring path 0 index)
".")))
(define (symlink-target-exists? path)
(let ((target (false-if-exception (readlink path))))
(and target
(file-exists? (string-append (path-directory path) "/" target)))))
(define (path-present? path)
(or (file-exists? path)
(false-if-exception (readlink path))))
(define (merge-node source destination)
(let ((kind (stat:type (lstat source))))
(case kind
((directory)
(mkdir-p destination)
(for-each (lambda (entry)
(merge-node (string-append source "/" entry)
(string-append destination "/" entry)))
(directory-entries source)))
((symlink)
(unless (path-present? destination)
(mkdir-p (path-directory destination))
(symlink (readlink source) destination)))
(else
(unless (file-exists? destination)
(copy-node source destination))))))
(define (merge-package-output source-root target-root)
(mkdir-p target-root)
(for-each (lambda (entry)
(unless (string-prefix? "." entry)
(merge-node (string-append source-root "/" entry)
(string-append target-root "/" entry))))
(directory-entries source-root)))
(define (with-directory directory thunk)
(let ((cwd (getcwd)))
(dynamic-wind
(lambda () (chdir directory))
thunk
(lambda () (chdir cwd)))))
(test-begin "dev-tools-packages")
(test-assert "development profile includes nodejs"
(package-present? freebsd-nodejs %freebsd-host-staged-development-profile-packages))
(test-assert "development profile includes npm"
(package-present? freebsd-npm %freebsd-host-staged-development-profile-packages))
(test-assert "development profile includes ripgrep"
(package-present? freebsd-ripgrep %freebsd-host-staged-development-profile-packages))
(test-assert "development profile includes tmux"
(package-present? freebsd-tmux %freebsd-host-staged-development-profile-packages))
(test-assert "development profile includes neovim"
(package-present? freebsd-neovim %freebsd-host-staged-development-profile-packages))
(test-assert "nodejs stages key paths"
(every (lambda (target)
(member target (install-targets freebsd-nodejs)))
'("bin/node" "include/node" "share/man/man1/node.1.gz")))
(test-assert "npm stages key paths"
(every (lambda (target)
(member target (install-targets freebsd-npm)))
'("bin/npm" "bin/npx" "bin/node-gyp" "etc/npmrc" "lib/node_modules/npm")))
(test-assert "ripgrep stages key paths"
(every (lambda (target)
(member target (install-targets freebsd-ripgrep)))
'("bin/rg" "share/man/man1/rg.1.gz")))
(test-assert "tmux stages key paths"
(every (lambda (target)
(member target (install-targets freebsd-tmux)))
'("bin/tmux" "share/examples/tmux/example_tmux.conf" "share/man/man1/tmux.1.gz")))
(test-assert "neovim stages key paths"
(every (lambda (target)
(member target (install-targets freebsd-neovim)))
'("bin/nvim" "share/nvim" "lib/nvim" "lib/lua/5.1/lpeg.so")))
(test-assert "development helper exports runtime library path"
(string-contains development-script "export LD_LIBRARY_PATH=\"$profile/lib:$profile/usr/lib"))
(test-assert "development helper exports node path"
(string-contains development-script "export NODE_PATH=\"$profile/lib/node_modules"))
(test-assert "development helper exports vimruntime"
(string-contains development-script "export VIMRUNTIME=\"$profile/share/nvim/runtime\""))
(test-assert "build helper exports runtime library path"
(string-contains build-script "export LD_LIBRARY_PATH=\"$profile/lib:$profile/usr/lib"))
(let* ((store-dir (mktemp-directory "/tmp/fruix-dev-tools-store.XXXXXX"))
(profile-dir (mktemp-directory "/tmp/fruix-dev-tools-profile.XXXXXX"))
(cache (make-hash-table))
(source-cache (make-hash-table))
(package-stores
(map (lambda (package)
(cons (freebsd-package-name package)
(materialize-freebsd-package package store-dir cache source-cache)))
dev-tool-packages))
(node-store (assoc-ref package-stores "freebsd-nodejs"))
(npm-store (assoc-ref package-stores "freebsd-npm"))
(ripgrep-store (assoc-ref package-stores "freebsd-ripgrep"))
(tmux-store (assoc-ref package-stores "freebsd-tmux"))
(neovim-store (assoc-ref package-stores "freebsd-neovim"))
(npm-workdir (mktemp-directory "/tmp/fruix-npm-local.XXXXXX"))
(home-dir (string-append npm-workdir "/home"))
(pkg-dir (string-append npm-workdir "/pkg-a")))
(for-each (lambda (store)
(merge-package-output (cdr store) profile-dir))
package-stores)
(test-assert "nodejs materialization copies libuv target"
(symlink-target-exists? (string-append node-store "/lib/libuv.so.1")))
(test-assert "ripgrep materialization copies pcre2 target"
(symlink-target-exists? (string-append ripgrep-store "/lib/libpcre2-8.so.0")))
(test-assert "tmux materialization copies libevent target"
(symlink-target-exists? (string-append tmux-store "/lib/libevent_core-2.1.so.7")))
(test-assert "neovim materialization copies libluv target"
(symlink-target-exists? (string-append neovim-store "/lib/libluv.so.1")))
(mkdir-p home-dir)
(mkdir-p pkg-dir)
(write-file (string-append pkg-dir "/package.json")
"{\"name\":\"pkg-a\",\"version\":\"1.0.0\",\"main\":\"index.js\"}\n")
(write-file (string-append pkg-dir "/index.js")
"module.exports = 42;\n")
(write-file (string-append npm-workdir "/package.json")
"{\"name\":\"rootproj\",\"version\":\"1.0.0\",\"dependencies\":{\"pkg-a\":\"file:./pkg-a\"}}\n")
(setenv "HOME" home-dir)
(setenv "PATH" (string-append profile-dir "/bin:/bin:/usr/bin"))
(setenv "LD_LIBRARY_PATH" (string-append profile-dir "/lib:" profile-dir "/usr/lib:/lib:/usr/lib"))
(setenv "NODE_PATH" (string-append profile-dir "/lib/node_modules"))
(setenv "VIMRUNTIME" (string-append profile-dir "/share/nvim/runtime"))
(setenv "LUA_CPATH" (string-append profile-dir "/lib/lua/5.1/?.so;;"))
(test-assert "materialized node runs"
(string-prefix? "v24.14.0"
(command-output (string-append profile-dir "/bin/node") "--version")))
(test-assert "materialized npm runs"
(string-prefix? "11.11.0"
(command-output (string-append profile-dir "/bin/npm") "--version")))
(test-assert "materialized ripgrep runs"
(string-prefix? "ripgrep 15.1.0"
(command-output (string-append profile-dir "/bin/rg") "--version")))
(test-assert "materialized tmux runs"
(string-prefix? "tmux 3.6a"
(command-output (string-append profile-dir "/bin/tmux") "-V")))
(test-assert "materialized neovim runs"
(string-prefix? "NVIM v0.12.0"
(command-output (string-append profile-dir "/bin/nvim") "--version")))
(with-directory
npm-workdir
(lambda ()
(run-command (string-append profile-dir "/bin/npm")
"install"
"--ignore-scripts"
"--no-audit"
"--no-fund")
(test-assert "npm local install works"
(file-exists? (string-append npm-workdir "/node_modules/pkg-a/package.json")))
(test-equal "npm exec can run node against the local dependency"
"42"
(command-output (string-append profile-dir "/bin/npm")
"exec"
"--"
"node"
"-e"
"process.stdout.write(String(require(\"pkg-a\")))")))))
(test-end "dev-tools-packages")
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
set -eu
repo_root=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)
. "$HOME/.local/opt/fruix-builder/env.sh"
guile_version=$($GUILE_BIN -c '(display (effective-version))')
guile_load_path="$repo_root/modules:$GUIX_SOURCE_DIR:$HOME/.local/opt/fruix-builder/shepherd/share/guile/site/$guile_version${GUILE_LOAD_PATH:+:$GUILE_LOAD_PATH}"
guile_load_compiled_path="$HOME/.local/opt/fruix-builder/shepherd/lib/guile/$guile_version/site-ccache${GUILE_LOAD_COMPILED_PATH:+:$GUILE_LOAD_COMPILED_PATH}"
env \
GUILE_AUTO_COMPILE=0 \
GUILE_LOAD_PATH="$guile_load_path" \
GUILE_LOAD_COMPILED_PATH="$guile_load_compiled_path" \
"$GUILE_BIN" --no-auto-compile "$repo_root/tests/dev-tools-packages.scm"