commit
2ec636df25
@ -0,0 +1,63 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
let |
||||
inherit (lib) escapeShellArgs mkEnableOption mkIf mkOption types; |
||||
|
||||
cfg = config.services.mimir; |
||||
|
||||
settingsFormat = pkgs.formats.yaml {}; |
||||
in { |
||||
options.services.mimir = { |
||||
enable = mkEnableOption "mimir"; |
||||
|
||||
configuration = mkOption { |
||||
type = (pkgs.formats.json {}).type; |
||||
default = {}; |
||||
description = '' |
||||
Specify the configuration for Mimir in Nix. |
||||
''; |
||||
}; |
||||
|
||||
configFile = mkOption { |
||||
type = types.nullOr types.path; |
||||
default = null; |
||||
description = '' |
||||
Specify a configuration file that Mimir should use. |
||||
''; |
||||
}; |
||||
}; |
||||
|
||||
config = mkIf cfg.enable { |
||||
assertions = [{ |
||||
assertion = ( |
||||
(cfg.configuration == {} -> cfg.configFile != null) && |
||||
(cfg.configFile != null -> cfg.configuration == {}) |
||||
); |
||||
message = '' |
||||
Please specify either |
||||
'services.mimir.configuration' or |
||||
'services.mimir.configFile'. |
||||
''; |
||||
}]; |
||||
|
||||
systemd.services.mimir = { |
||||
description = "mimir Service Daemon"; |
||||
wantedBy = [ "multi-user.target" ]; |
||||
|
||||
serviceConfig = let |
||||
conf = if cfg.configFile == null |
||||
then settingsFormat.generate "config.yaml" cfg.configuration |
||||
else cfg.configFile; |
||||
in |
||||
{ |
||||
ExecStart = "${pkgs.grafana-mimir}/bin/mimir --config.file=${conf}"; |
||||
DynamicUser = true; |
||||
Restart = "always"; |
||||
ProtectSystem = "full"; |
||||
DevicePolicy = "closed"; |
||||
NoNewPrivileges = true; |
||||
StateDirectory = "mimir"; |
||||
}; |
||||
}; |
||||
}; |
||||
} |
@ -0,0 +1,53 @@ |
||||
{ stdenv, lib, fetchFromGitLab, cmake, pkg-config, cairo, libxkbcommon |
||||
, xcbutilcursor, xcbutilkeysyms, xcbutil, libXrandr, libXinerama, libXcursor |
||||
, alsa-lib, libjack2, lv2, gcc-unwrapped, curl}: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "LibreArp"; |
||||
version = "2.2"; |
||||
|
||||
src = fetchFromGitLab { |
||||
owner = "LibreArp"; |
||||
repo = "LibreArp"; |
||||
rev = version; |
||||
hash = "sha256-jCUT/sflO9L57xRTqNR90RbwJ0uZ+xJVXnB3n+FhWBo="; |
||||
fetchSubmodules = true; |
||||
}; |
||||
|
||||
nativeBuildInputs = [ cmake pkg-config ]; |
||||
buildInputs = [ |
||||
cairo |
||||
libxkbcommon |
||||
xcbutilcursor |
||||
xcbutilkeysyms |
||||
xcbutil |
||||
libXrandr |
||||
libXinerama |
||||
libXcursor |
||||
alsa-lib |
||||
libjack2 |
||||
lv2 |
||||
curl |
||||
]; |
||||
|
||||
cmakeFlags = [ |
||||
"-DCMAKE_AR=${gcc-unwrapped}/bin/gcc-ar" |
||||
"-DCMAKE_RANLIB=${gcc-unwrapped}/bin/gcc-ranlib" |
||||
"-DCMAKE_NM=${gcc-unwrapped}/bin/gcc-nm" |
||||
]; |
||||
|
||||
installPhase = '' |
||||
mkdir -p $out/lib/vst3 |
||||
cd LibreArp_artefacts/Release |
||||
cp -r VST3/LibreArp.vst3 $out/lib/vst3 |
||||
''; |
||||
|
||||
meta = with lib; { |
||||
description = |
||||
"A pattern-based arpeggio generator plugin."; |
||||
homepage = "https://librearp.gitlab.io/"; |
||||
license = licenses.gpl3Plus; |
||||
platforms = [ "x86_64-linux" ]; |
||||
maintainers = with maintainers; [ magnetophon ]; |
||||
}; |
||||
} |
@ -0,0 +1,53 @@ |
||||
{ stdenv, lib, fetchFromGitLab, cmake, pkg-config, cairo, libxkbcommon |
||||
, xcbutilcursor, xcbutilkeysyms, xcbutil, libXrandr, libXinerama, libXcursor |
||||
, alsa-lib, libjack2, lv2, gcc-unwrapped, curl}: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "LibreArp-lv2"; |
||||
version = "2.2"; |
||||
|
||||
src = fetchFromGitLab { |
||||
owner = "LibreArp"; |
||||
repo = "LibreArp"; |
||||
rev = "${version}-lv2"; |
||||
hash = "sha256-j5SksuhC4ZXXILfOpwXNqIu5fO07a/6tiZ5qUo+p0Ug="; |
||||
fetchSubmodules = true; |
||||
}; |
||||
|
||||
nativeBuildInputs = [ cmake pkg-config ]; |
||||
buildInputs = [ |
||||
cairo |
||||
libxkbcommon |
||||
xcbutilcursor |
||||
xcbutilkeysyms |
||||
xcbutil |
||||
libXrandr |
||||
libXinerama |
||||
libXcursor |
||||
alsa-lib |
||||
libjack2 |
||||
lv2 |
||||
curl |
||||
]; |
||||
|
||||
cmakeFlags = [ |
||||
"-DCMAKE_AR=${gcc-unwrapped}/bin/gcc-ar" |
||||
"-DCMAKE_RANLIB=${gcc-unwrapped}/bin/gcc-ranlib" |
||||
"-DCMAKE_NM=${gcc-unwrapped}/bin/gcc-nm" |
||||
]; |
||||
|
||||
installPhase = '' |
||||
mkdir -p $out/lib/lv2 |
||||
cd LibreArp_artefacts/Release |
||||
cp -r LV2/LibreArp.lv2 $out/lib/lv2 |
||||
''; |
||||
|
||||
meta = with lib; { |
||||
description = |
||||
"A pattern-based arpeggio generator plugin."; |
||||
homepage = "https://librearp.gitlab.io/"; |
||||
license = licenses.gpl3Plus; |
||||
platforms = [ "x86_64-linux" ]; |
||||
maintainers = with maintainers; [ magnetophon ]; |
||||
}; |
||||
} |
@ -0,0 +1,50 @@ |
||||
{ lib |
||||
, mkDerivation |
||||
, fetchFromGitHub |
||||
, pkg-config |
||||
, qtbase |
||||
, qtsvg |
||||
, qtcharts |
||||
, wrapQtAppsHook |
||||
, cmake |
||||
, python3 |
||||
}: |
||||
|
||||
mkDerivation rec { |
||||
pname = "ripes"; |
||||
version = "2.2.4"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "mortbopet"; |
||||
repo = "Ripes"; |
||||
rev = "v${version}"; |
||||
fetchSubmodules = true; |
||||
sha256 = "sha256-Aal2A4xypzaY7Oa+boIrXk7ITNKnh5OZIP7DkJjcGu4="; |
||||
}; |
||||
|
||||
nativeBuildInputs = [ |
||||
cmake |
||||
pkg-config |
||||
python3 |
||||
wrapQtAppsHook |
||||
]; |
||||
|
||||
buildInputs = [ |
||||
qtbase |
||||
qtsvg |
||||
qtcharts |
||||
]; |
||||
|
||||
installPhase = '' |
||||
install -D Ripes $out/bin/Ripes |
||||
cp -r ${src}/appdir/usr/share $out/share |
||||
''; |
||||
|
||||
meta = with lib; { |
||||
description = "A graphical processor simulator and assembly editor for the RISC-V ISA"; |
||||
homepage = "https://github.com/mortbopet/Ripes"; |
||||
license = licenses.mit; |
||||
platforms = platforms.linux; |
||||
maintainers = with maintainers; [ rewine ]; |
||||
}; |
||||
} |
@ -1,35 +0,0 @@ |
||||
{ lib, stdenv, fetchFromGitHub, pkg-config |
||||
, libX11, libxcb, cairo, gtk2, pango, python27, python3 |
||||
}: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "lighthouse"; |
||||
version = "unstable-2016-07-20"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "emgram769"; |
||||
repo = "lighthouse"; |
||||
rev = "d1813ef8e2aca9f6b3609b1e0c6d1d5ee683281a"; |
||||
sha256 = "0v6ylm49f1b44zwq1y1gqxp2csyqblplr24ajllc2q3r0sc9m1ys"; |
||||
}; |
||||
|
||||
nativeBuildInputs = [ pkg-config ]; |
||||
buildInputs = [ |
||||
libX11 libxcb cairo gtk2 pango python27 python3 |
||||
]; |
||||
|
||||
makeFlags = [ "PREFIX=\${out}" ]; |
||||
|
||||
preFixup = "chmod +x $out/share/lighthouse/.config/lighthouse/google.py"; |
||||
|
||||
postFixup = "chmod -x $out/share/lighthouse/.config/lighthouse/google.py"; |
||||
|
||||
meta = with lib; { |
||||
description = "A simple flexible popup dialog to run on X"; |
||||
homepage = "https://github.com/emgram769/lighthouse"; |
||||
license = licenses.mit; |
||||
maintainers = with maintainers; [ ramkromberg ]; |
||||
platforms = platforms.linux; |
||||
}; |
||||
|
||||
} |
@ -0,0 +1,23 @@ |
||||
{ lib, stdenv, fetchFromGitHub }: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "adolc"; |
||||
version = "2.7.2"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "coin-or"; |
||||
repo = "ADOL-C"; |
||||
sha256 = "1w0x0p32r1amfmh2lyx33j4cb5bpkwjr5z0ll43zi5wf5gsvckd1"; |
||||
rev = "releases/${version}"; |
||||
}; |
||||
|
||||
configureFlags = [ "--with-openmp-flag=-fopenmp" ]; |
||||
|
||||
meta = with lib; { |
||||
description = "Automatic Differentiation of C/C++"; |
||||
homepage = "https://github.com/coin-or/ADOL-C"; |
||||
maintainers = [ maintainers.bzizou ]; |
||||
license = licenses.gpl2Plus; |
||||
}; |
||||
} |
||||
|
@ -0,0 +1,50 @@ |
||||
{ avahi-compat, cmake, fetchFromGitHub, flatbuffers, hidapi, lib, libcec |
||||
, libusb1, libX11, libxcb, libXrandr, mbedtls, mkDerivation, protobuf, python3 |
||||
, qtbase, qtserialport, qtsvg, qtx11extras, wrapQtAppsHook }: |
||||
|
||||
mkDerivation rec { |
||||
pname = "hyperion.ng"; |
||||
version = "2.0.12"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "hyperion-project"; |
||||
repo = pname; |
||||
rev = version; |
||||
sha256 = "sha256-J31QaWwGNhIpnZmWN9lZEI6fC0VheY5X8fGchQqtAlQ="; |
||||
}; |
||||
|
||||
buildInputs = [ |
||||
avahi-compat |
||||
flatbuffers |
||||
hidapi |
||||
libcec |
||||
libusb1 |
||||
libX11 |
||||
libxcb |
||||
libXrandr |
||||
mbedtls |
||||
protobuf |
||||
python3 |
||||
qtbase |
||||
qtserialport |
||||
qtsvg |
||||
qtx11extras |
||||
]; |
||||
|
||||
nativeBuildInputs = [ cmake wrapQtAppsHook ]; |
||||
|
||||
cmakeFlags = [ |
||||
"-DCMAKE_BUILD_TYPE=Release" |
||||
"-DUSE_SYSTEM_MBEDTLS_LIBS=ON" |
||||
"-DUSE_SYSTEM_FLATBUFFERS_LIBS=ON" |
||||
"-DUSE_SYSTEM_PROTO_LIBS=ON" |
||||
]; |
||||
|
||||
meta = with lib; { |
||||
description = "Open Source Ambilight solution"; |
||||
homepage = "https://github.com/hyperion-project/hyperion.ng"; |
||||
license = licenses.mit; |
||||
maintainers = with maintainers; [ algram ]; |
||||
platforms = platforms.unix; |
||||
}; |
||||
} |
@ -0,0 +1,29 @@ |
||||
{ lib, fetchzip }: |
||||
|
||||
let |
||||
version = "1.204"; |
||||
in |
||||
fetchzip rec { |
||||
name = "annapurna-sil-${version}"; |
||||
|
||||
url = "https://software.sil.org/downloads/r/annapurna/AnnapurnaSIL-${version}.zip"; |
||||
|
||||
postFetch = '' |
||||
mkdir -p $out/share/{doc,fonts} |
||||
unzip -j $downloadedFile \*.ttf -d $out/share/fonts/truetype |
||||
unzip -j $downloadedFile \*OFL.txt \*OFL-FAQ.txt \*README.txt \*FONTLOG.txt -d "$out/share/doc/${name}" |
||||
''; |
||||
|
||||
sha256 = "sha256-kVeP9ZX8H+Wn6jzmH1UQvUKY6vJjadMTdEusS7LodFM="; |
||||
|
||||
meta = with lib; { |
||||
homepage = "https://software.sil.org/annapurna"; |
||||
description = "Unicode-based font family with broad support for writing systems that use the Devanagari script"; |
||||
longDescription = '' |
||||
Annapurna SIL is a Unicode-based font family with broad support for writing systems that use the Devanagari script. Inspired by traditional calligraphic forms, the design is intended to be highly readable, reasonably compact, and visually attractive. |
||||
''; |
||||
license = licenses.ofl; |
||||
platforms = platforms.all; |
||||
maintainers = [ maintainers.kmein ]; |
||||
}; |
||||
} |
@ -0,0 +1,26 @@ |
||||
{ lib, fetchzip }: |
||||
|
||||
let |
||||
version = "2.51"; |
||||
in |
||||
fetchzip rec { |
||||
name = "ezra-sil-${version}"; |
||||
|
||||
url = "https://software.sil.org/downloads/r/ezra/EzraSIL-${version}.zip"; |
||||
|
||||
postFetch = '' |
||||
mkdir -p $out/share/{doc,fonts} |
||||
unzip -j $downloadedFile \*.ttf -d $out/share/fonts/truetype |
||||
unzip -j $downloadedFile \*OFL-FAQ.txt \*README.txt \*FONTLOG.txt -d "$out/share/doc/${name}" |
||||
''; |
||||
|
||||
sha256 = "sha256-1LGw/RPFeNtEvcBWFWZf8+dABvWye2RfZ/jt8rwQewM="; |
||||
|
||||
meta = with lib; { |
||||
homepage = "https://software.sil.org/ezra"; |
||||
description = "Typeface fashioned after the square letter forms of the typography of the Biblia Hebraica Stuttgartensia (BHS)"; |
||||
license = licenses.ofl; |
||||
platforms = platforms.all; |
||||
maintainers = [ maintainers.kmein ]; |
||||
}; |
||||
} |
@ -0,0 +1,29 @@ |
||||
{ lib, fetchzip }: |
||||
|
||||
let |
||||
version = "2.1"; |
||||
in |
||||
fetchzip rec { |
||||
name = "galatia-sil-${version}"; |
||||
|
||||
url = "https://software.sil.org/downloads/r/galatia/GalatiaSIL-${version}.zip"; |
||||
|
||||
postFetch = '' |
||||
mkdir -p $out/share/{doc,fonts} |
||||
unzip -j $downloadedFile \*.ttf -d $out/share/fonts/truetype |
||||
unzip -j $downloadedFile \*OFL.txt \*OFL-FAQ.txt \*FONTLOG.txt -d "$out/share/doc/${name}" |
||||
''; |
||||
|
||||
sha256 = "sha256-zLL/7LMcJul2LilhEafpvm+tiYlgv1y1jj85VvG+wiI="; |
||||
|
||||
meta = with lib; { |
||||
homepage = "https://software.sil.org/galatia"; |
||||
description = "Font designed to support Biblical Polytonic Greek"; |
||||
longDescription = '' |
||||
Galatia SIL, designed to support Biblical Polytonic Greek, is a Unicode 3.1 font released under the SIL Open Font License. The font supports precomposed characters rather than decomposed characters. Thus, you must use a keyboard that outputs NFC encoding (precomposed). |
||||
''; |
||||
license = licenses.ofl; |
||||
platforms = platforms.all; |
||||
maintainers = [ maintainers.kmein ]; |
||||
}; |
||||
} |
@ -1,95 +1,95 @@ |
||||
# This file was autogenerated. DO NOT EDIT! |
||||
{ |
||||
iosevka = "1g8x2bjhnhiq46mx02rhp0wphi7rj21m1nh2gx6rxly2ybms3pnw"; |
||||
iosevka-aile = "1hvrzycsilvjl3a90n2sk5sznkjvrn9r6yqaad397rbd309w46ai"; |
||||
iosevka-curly = "0df15zbjs9xpqm5032vmjmnp4ay545bs4i8xr6rd37slb8a8x2bf"; |
||||
iosevka-curly-slab = "0n57gz1v12l01khy3y0i0yd4w88jz6izwl4iav4679qjfhhd206c"; |
||||
iosevka-etoile = "1mq1mqxkj5y3r9xwjy7pbrvnv72zkj2hnh48kac0xr414yrqql3n"; |
||||
iosevka-slab = "0srnbwxj03is9d8q0y0k55dr35s747p8xbiz7xany5piljl68f42"; |
||||
iosevka-ss01 = "1rm514g3x510dcpn9hn98kl2pv4h9rxmkgp2wvxxhg3s47x0462n"; |
||||
iosevka-ss02 = "0p8h1khzxsi4c6wmwri9vvbcv2qy4nksnhmyhksb0b8yw22s9iyk"; |
||||
iosevka-ss03 = "1rsw5gx5l5mi8ljvgrrir4bnhy8mvx3rkr9d4vba8wzvvqvc74nv"; |
||||
iosevka-ss04 = "02rcdfrnhqdjlks26968mxsrdyfalk3h985bf9vi03sf9nqmmfpz"; |
||||
iosevka-ss05 = "1qn323iawpvjqhmx6s7i8irjqkxq9yya5dxp87m452hq9zm2jynq"; |
||||
iosevka-ss06 = "0zyg2afzmzdm7gd2c9i9vp751xapajabjm85sri3mcyvgkbcxqai"; |
||||
iosevka-ss07 = "1qfalhxl2vxflwn3f73bdq5q1p8zblmswdfw5mrl3b5nzy8y40nw"; |
||||
iosevka-ss08 = "0idj19nk7mq6z4yphmxa09c5azgxyi38zlq7y872s0dl9j2qbi5f"; |
||||
iosevka-ss09 = "1zwwlb9c34q36kflc6r4wygv3rpkd7y6n1xpkql02w6rb1gp7nd9"; |
||||
iosevka-ss10 = "0j01j7frkv2ldz3hqn65r3b56yn63fchhhkghs95v4cln27qzmxx"; |
||||
iosevka-ss11 = "0imwzcxh7cqmqcsdlg5nay12jql8dq1hk0h7a0i1igrn3fflga5g"; |
||||
iosevka-ss12 = "0z5smyxx5szz5ky4lxmscf44a5pzkjm590cihmcnjw3nxiw84bs1"; |
||||
iosevka-ss13 = "0pyq12n7h1adhs5rbkrx9b64rpwvd9nj8vjmwzf3qmdc39bx6rfv"; |
||||
iosevka-ss14 = "0v3aipgvw1ygs6v839cw17arm5iag57aqdkr35n0wx3yl5h3v9wg"; |
||||
iosevka-ss15 = "0vhwi4b2nmshx7lh5d4fr3swfx58sxwn6w38kvp5p27jp68azbbz"; |
||||
iosevka-ss16 = "1rzrd0swjaacbjpxniglkkwsn4dfhvb8f70g8nigc2mah3md62gp"; |
||||
iosevka-ss17 = "184acjrqdlw38lzizwxp02lwmc8jznrb55krlvrxkd2lkj4r6gni"; |
||||
iosevka-ss18 = "0sza6q6yisjsk5gkkj1z7qbrhpvqv18nykgdwqraa3im66bkl1v9"; |
||||
sgr-iosevka = "1n1i12d9891il20ry3vkv5503d9j541w17imh09dbn5r0lrjr40r"; |
||||
sgr-iosevka-aile = "0y1nx1xk7fn8dj5jc6zyva593vdxngjc61j717jlqh855fpz5v04"; |
||||
sgr-iosevka-curly = "03x2w2arkbhnpl3rlsdgpldqnfrd14q55kf5rf5lsrnmdndg706s"; |
||||
sgr-iosevka-curly-slab = "0vncsw3k56cqzpp5rpllz4azklib0vq7rah0ssz2syh43zffsyw3"; |
||||
sgr-iosevka-etoile = "0plk2c7ckxm0f7aa9wd1qpi3dfb2gap0222jhx906clx04kb6bp0"; |
||||
sgr-iosevka-fixed = "147qjfqwdr0l29ljbn0c73m2wg1vm9qdn5fjika8z1wy7mbrmbsl"; |
||||
sgr-iosevka-fixed-curly = "1222ms9kpgcah531ik7h9qkprpq4dd98p41xrsxad3hvr4aa6x05"; |
||||
sgr-iosevka-fixed-curly-slab = "1fcg0afhan0ym15c10qikfa4hadgzj0aabymac0qq74l5dn8lmx7"; |
||||
sgr-iosevka-fixed-slab = "174xgxrwy50gnm53qhr9mf5cwkbwgalw6ypbz6r68fhyk70dbjvx"; |
||||
sgr-iosevka-fixed-ss01 = "16wpj0yvkavhlvz5xzfa5mr219wlynqlfg1am1y1b9w647ypx6q6"; |
||||
sgr-iosevka-fixed-ss02 = "1ya9riiiphv6fmirg5r0va06xvcgq8j41vmibqrzld7sjk26yrll"; |
||||
sgr-iosevka-fixed-ss03 = "1l6dc7sl5a9p076a7jp2lfwrn1xh0rlp8v3d9k5m9gjghr62b288"; |
||||
sgr-iosevka-fixed-ss04 = "1fmbdjgkvaw30x9wycdfzk9n9c1a2vznx8fnxc3xjps4xw5vd4h3"; |
||||
sgr-iosevka-fixed-ss05 = "1f66q69wgqxqzkf5r54cjqg66lnfpk7w9lf1hk59v3vmxjxy39xh"; |
||||
sgr-iosevka-fixed-ss06 = "1lfjnjn3k6wj03gxpvzc73zj98iy0x447pigxln911ai3v2mcmz5"; |
||||
sgr-iosevka-fixed-ss07 = "0567x6rvikpn2cn9prrym0rlw5swa4rb7wihmhpgal64ygysipq4"; |
||||
sgr-iosevka-fixed-ss08 = "0b81a3841c2fdfrpsiq8cyly9mzrk0974na53b505wasj5jvikqb"; |
||||
sgr-iosevka-fixed-ss09 = "1p5w7m5r11m94icyv8fnwzmpnsih9s8p8iq8hg6iasawqzh60ll3"; |
||||
sgr-iosevka-fixed-ss10 = "0c0dhi2c84km1vhbiifv95x4yf03jz12jax2vvc68hhi3w4gmg68"; |
||||
sgr-iosevka-fixed-ss11 = "10jp3i36sv4jl2887g1ir1dc2gy1iyhzf2f396jchi5dadzfpgwj"; |
||||
sgr-iosevka-fixed-ss12 = "14pq3l6241ylpxlx2n483g1ghlhqahk8dla0frvb572k0bvl4vh5"; |
||||
sgr-iosevka-fixed-ss13 = "0js73rildzz24v4alj2xfl5n5wvmlxk18qzdchzrb78lq6bifvvd"; |
||||
sgr-iosevka-fixed-ss14 = "0f47d6khi5kr10xlm61pbwr1xk5kqgj82abcaxmvbf5c3jj3v1lr"; |
||||
sgr-iosevka-fixed-ss15 = "1nkyfmx4ps8mbnz7ap0vzgwgrxm6nbi4fhvalr6w2dk521inyfn7"; |
||||
sgr-iosevka-fixed-ss16 = "0fykkgksdmni80v3q513xwxnay9l73viwj9qbn4bc58ljzd5hffr"; |
||||
sgr-iosevka-fixed-ss17 = "09n1vl8m2drg5zs05hvdp7yy47a9s927a8ndxqsa34klanz7c04j"; |
||||
sgr-iosevka-fixed-ss18 = "1rmfnnsi9c6alifhnfa4yc9gfgk687zxhrsyrjizwg9r19b2k34m"; |
||||
sgr-iosevka-slab = "1nffh7iy3gn5v2yqilq57x6nvk25jh9jmbdmdfyra19nwfn601ja"; |
||||
sgr-iosevka-ss01 = "1nwl7psz11jnyldry3wa3wfki28wghqq8f7vz8gmmcvv98caga80"; |
||||
sgr-iosevka-ss02 = "1clk233v4ycfqmbv7whmbvm2l1qr1kf75kdca1r4c5y4wjmsh1ap"; |
||||
sgr-iosevka-ss03 = "1lxn8hgz0qxs39d1jvr855h8zi3dv1k56v99q0ivrnp5y7aclia5"; |
||||
sgr-iosevka-ss04 = "03nz6864i5s6gpjy7jjj52062ivd57wh90j6p8x4lj72479fwfsy"; |
||||
sgr-iosevka-ss05 = "1bfgdnc44vmj3hxifz0kb5bfbv3bj9dglp4l7p781chi0m9yrmm8"; |
||||
sgr-iosevka-ss06 = "1zcqq2kv080xsfll6zap3hm2l0kx6sr378iq7qrfpavmfifc3rk8"; |
||||
sgr-iosevka-ss07 = "1phy7gdx5j5rww54mmzvi5f401lxqxxrwmh0hrhl0bvsxybhdcgm"; |
||||
sgr-iosevka-ss08 = "1wyznlzpbv8vb1sny4f1v8x4azfbcp2ajml4aram9k9cx3zkvd8s"; |
||||
sgr-iosevka-ss09 = "0q4sla496pdhfv4v15y5ax0h4pr4n47bfrvs27lq26x4p1fhgwdg"; |
||||
sgr-iosevka-ss10 = "1iyr4vfs2dp26vi26libv5k18mvdnfzmwmvzdczkh8cyc9hwp36d"; |
||||
sgr-iosevka-ss11 = "083pfql4nlq2847csqskb2qxrsnlvfwz198ybnfd97lxa1zczj6k"; |
||||
sgr-iosevka-ss12 = "08isy55m7dqpyhbzf5jkamnr8c135850dwpqp380g991h5sp3vnm"; |
||||
sgr-iosevka-ss13 = "1vjv198pkvnnxxcbyc5fy54ld4phf52nhybqc9hyf8d7806wrvyn"; |
||||
sgr-iosevka-ss14 = "1y4iclzcfb2q0172xag3zqabw03q89jqb7asi0x9zkrhcd1i512y"; |
||||
sgr-iosevka-ss15 = "1zxxn6s418gpx2ndknqdwp132p0sr3smsqhavpl5kw5cxrgxa9q6"; |
||||
sgr-iosevka-ss16 = "132xmf4rlsa3d0j2s9hmfih6s32wm1na0hs72h7padnh6c7di3rl"; |
||||
sgr-iosevka-ss17 = "1bb94ladk0qvzmvb2gc1561xfy7ddgqkqgcgigkkhdab7cfw0cxq"; |
||||
sgr-iosevka-ss18 = "15rrngd4qnzqk06whczsmfdf5c1k3nm4m8ga691i1rjxwc5dwycc"; |
||||
sgr-iosevka-term = "09m74mqczkm0pirahlisdw2mafyzq7wpzplyqg51221x2m01px7z"; |
||||
sgr-iosevka-term-curly = "19ralig26akrabclnniwvimqkcrd0agcwyxakinb7qcbm8p4x30x"; |
||||
sgr-iosevka-term-curly-slab = "01zwrlkrp840ah5fclxxl17vckcx4wnv3vwlz6nch2igy965k6qs"; |
||||
sgr-iosevka-term-slab = "0520d21x04fvc2b3aa6kzdhwvf24s8yd8vkbl400i0x78gyrlnzv"; |
||||
sgr-iosevka-term-ss01 = "0q64vcp4djk0mdfc05a9bz0nqc2a7dr0gdvj2d2kfpbqsg4i32qq"; |
||||
sgr-iosevka-term-ss02 = "0h8a4wc5ck1p7gaf1r08h4irj10kqbpm2jkb2p63gybi9gp6ivwg"; |
||||
sgr-iosevka-term-ss03 = "0608yhvkbv1hkdj7c347r9q7wbm9bvy6lnhhs6gb0ndkx596pnzm"; |
||||
sgr-iosevka-term-ss04 = "1yfpkczgfjfr52ilinzi2dfyw11mmsilxjpl9r9yh0fxmr48c976"; |
||||
sgr-iosevka-term-ss05 = "1brrfhkj7wlyhfdfhafkqw8kgsfy7fsi7567ayxii5b05wn9g6mr"; |
||||
sgr-iosevka-term-ss06 = "0vksv1k9wvyfiifxnajvmi8b5mx8w72d80y3r9ic7rz36l0rbl3x"; |
||||
sgr-iosevka-term-ss07 = "0n5hz3zdp7flbr2xh4yddwkxvpcd0v55m274w15s9q6wln0knwhy"; |
||||
sgr-iosevka-term-ss08 = "1qknqr11imcrr0iqpa9qpf70m7505wl81k48igdyqgmimgksrlji"; |
||||
sgr-iosevka-term-ss09 = "1j53n5fv2y97bj7n4kx8h8v5isflbmgdqh0hz58ilp06v6rd6j5i"; |
||||
sgr-iosevka-term-ss10 = "1bzi39n4x4qa7vyhv5yh875n8gbyjkiaqfhj2xh8pj88b8064cw0"; |
||||
sgr-iosevka-term-ss11 = "0xxyh1zxy1jdy0b110f7rallhf0vicsw0snyh3bf3v0mnkimk0y4"; |
||||
sgr-iosevka-term-ss12 = "1hpbpqnkd4jzcqkg424y3d6i6nn5gyqlpqsfxrvfvx4igmm75vs5"; |
||||
sgr-iosevka-term-ss13 = "12fg2j5xw6vcpczc5kgq6q29cq579l1wyv5ag9r4kxqg541s3frl"; |
||||
sgr-iosevka-term-ss14 = "02qkmzr5kn5p69nqk59j6431313apy861yphbzpy56k4g80j0gy4"; |
||||
sgr-iosevka-term-ss15 = "0pcb91b8iic6blsgz0sw5hv2d9add355dizpvhc6m8rmp6l5pnqq"; |
||||
sgr-iosevka-term-ss16 = "081g07cav6k36k78bmdrx0z9jj2xzx3p1midzsxgsqp3ns2qxk7s"; |
||||
sgr-iosevka-term-ss17 = "1bx7mx75344i4807aq1xk0rw03hnv24wn3kj247hv3b1lxx14285"; |
||||
sgr-iosevka-term-ss18 = "068vy78d710aszk5s9kwf56rxg17qm8pphd329cmwknxsyan139g"; |
||||
iosevka = "0654wkgdr5gy0s9gr4llyqkvngxrqfn6hfvm5akz0zwq3xwfjc0p"; |
||||
iosevka-aile = "0hkgb7p22ayzsjw7idzl47djcpglsjzyi8rkz39vb9w4w3dvxbn5"; |
||||
iosevka-curly = "04kkvbl0jz3ykdc30wvagh7f49nqxr6vz0wjcq93ajdc2pm4i5k4"; |
||||
iosevka-curly-slab = "189w0xszks8msg7wis0gck3r2cp1rdimkii44dlj8l4p4qjxg8va"; |
||||
iosevka-etoile = "1i8p8knl3hr8gj7nhbd93jh31rbj11pvjwhvjxy1djgipmdn3257"; |
||||
iosevka-slab = "049j6p5v4f50yvmw8ab01pzcf18i326741rsg0kgsxw36yidmd1d"; |
||||
iosevka-ss01 = "1h5s0nlgl5g0w08ii77jg671nwrmpan22ddgxaq941lznhmkv27k"; |
||||
iosevka-ss02 = "03ps2a2z2x1d42mqnal1dr32949ra04hd8igwl93lflijlbww1xh"; |
||||
iosevka-ss03 = "134kzw6ys3rnfw8wv7gfbvjx5im21647n1gvj68bayry41y3xisp"; |
||||
iosevka-ss04 = "03kqg6n4p5m27szkjpfpyr4jgyigvj40rm1nmvv4dfd3cs9rg326"; |
||||
iosevka-ss05 = "1xzvim04d2z152ml9av2zsgyla1n7wa0rja4j9bvi22rh1qb8kwv"; |
||||
iosevka-ss06 = "1r8bj27rfsz732gw6qwqj6hx4babpm5cqm4i7f37spkw1dmvcrkx"; |
||||
iosevka-ss07 = "16ndzr6abacy8m3bf4smfy9yw8w2i51pkv3d7klfflz9jimx540y"; |
||||
iosevka-ss08 = "0kn4q2n1nyn3ds2gajc42b2mi8n67mlgz4rhbbn01nd8miz6lasw"; |
||||
iosevka-ss09 = "1wajl1cng698dk0w81j2n54gcb7lygfj645s3gf2k4ywsmfd17rr"; |
||||
iosevka-ss10 = "1cx44l69z8y2b0dcxw43msppgl030cvihf40asfsj036zab36n71"; |
||||
iosevka-ss11 = "0jk3777bx4ibr7na9qraqhaldbaini9qyjw4lpqnszqxryx5p9ms"; |
||||
iosevka-ss12 = "19w5wmq5q1rwn0yw9q74kfkbqaxbbv1ak7ikdi95qa06c1sz4z73"; |
||||
iosevka-ss13 = "0llhdh641l8hqrpzs663ry3mr1fxh42g7vv1dknyh7lp32qdrh8h"; |
||||
iosevka-ss14 = "1rfi157f3fln2ww3q945ych34lc9fxjx2spv6zrjg6j6k841ld76"; |
||||
iosevka-ss15 = "12qpgbg4d2h8kqlc3xhpg1j3ic6wnffn4af1kr05kdln6av9sfjn"; |
||||
iosevka-ss16 = "1ry923xky52fylhnya3yay3wh0cxwwqy64vq74a8wls1vnfpq7md"; |
||||
iosevka-ss17 = "0d152px48gh8axqaw8myy81h9mff5vkikdqqv1mqcqy5yb50g550"; |
||||
iosevka-ss18 = "1q9j0rp8a29yazgp9a3jgp54xjih0ffqfm5ii85sl0dxrval5vkq"; |
||||
sgr-iosevka = "1khq3vqma1zc588x2rcnqv6lc2ajxkvs711w8zrjb7x9aaysly66"; |
||||
sgr-iosevka-aile = "0cryvq204hadx28raldjp901zvvv7iywah8pcn09qwrhpkbk1r92"; |
||||
sgr-iosevka-curly = "1mqybxgc9pdn5ww5zy9ki6apiv0vbdmspz2glmcrz4vfxylbydqb"; |
||||
sgr-iosevka-curly-slab = "0v7y5ld3ccyb4y7nz391pxljcmxczll319lj6znxj9p9pgykw6gy"; |
||||
sgr-iosevka-etoile = "03vcxnkb766l8i0r9rpd08ylazhxhv2avb3mszpirgs7ax979jqm"; |
||||
sgr-iosevka-fixed = "12b2n3yjz3r67p757dmrdzayjidrlmb16mjlzdc2rrnijd41qyn7"; |
||||
sgr-iosevka-fixed-curly = "12l7d0472m524jx52libsxc5ffjsnki3ah07vfg6lj7w8lam1vq1"; |
||||
sgr-iosevka-fixed-curly-slab = "1lyvjvl5gsx16vfy6s0qgvkw50xvariqp6xvfzz68sg7hm1s3jqp"; |
||||
sgr-iosevka-fixed-slab = "1080269ykl7xpjkp120rm46j3yhj3sd3rpygf79ny2svq0jn99y2"; |
||||
sgr-iosevka-fixed-ss01 = "0g04xlr1jarnmj427gdvskgy7hmbxi5hs2ppjfj71qv75kyvlvyk"; |
||||
sgr-iosevka-fixed-ss02 = "1gh3grq87ibibryl6h0z3z4r55k0wv7w4mvg63jfrbvdc7z2rkhz"; |
||||
sgr-iosevka-fixed-ss03 = "1aa8nyaccx1ryfrdmwjdrfcwcr7vh3f28ygh3m1cmakmji6gr63z"; |
||||
sgr-iosevka-fixed-ss04 = "0qv3pk1pwiciqw15lanljk2j8g667rn6514b16xf9lmmmpczlz2m"; |
||||
sgr-iosevka-fixed-ss05 = "0pjmzrq836xw0nxr1j6hgphwya20k00v29mpbrxrmcg5ii4ph82h"; |
||||
sgr-iosevka-fixed-ss06 = "0wxis8mg9jm38caf2rjsfyc1g83r7yayp415cwzl1pm6sdkxar9g"; |
||||
sgr-iosevka-fixed-ss07 = "0r4rvlk67p8s02i54lpgarw75lhfr2w4an8z34n7689arl2a03bv"; |
||||
sgr-iosevka-fixed-ss08 = "0rd1dglhqzbaib104hh7i89m4br8kg2shd0221kvshkjwbpbpr1r"; |
||||
sgr-iosevka-fixed-ss09 = "02jaykc43c35i0n34gi3ds66gglcdycq9nalidqcldbxcpgciiiz"; |
||||
sgr-iosevka-fixed-ss10 = "046s8iv5yv9vbaf9nv1kr0lpvxa0yb125hjzw3sm8fvihpwks0m7"; |
||||
sgr-iosevka-fixed-ss11 = "19rq860q79cl5b6p7q5phsnb89xxsv4h5dqyn1qkc7axwvx9yj9v"; |
||||
sgr-iosevka-fixed-ss12 = "1gscgqrc9b8liwr00c2h5zbi3xq2nkfwfbfv6adv8wjprfw2ri3d"; |
||||
sgr-iosevka-fixed-ss13 = "0px3zvxbis70b24xzgnrs3rh2pacdqlkdkwb5gwngans2alnq5bw"; |
||||
sgr-iosevka-fixed-ss14 = "1n6pn1jv0diikbhp9kngxnakjkhjc414qzccfrinml6fg7cr8kz8"; |
||||
sgr-iosevka-fixed-ss15 = "00w67v49iqxcrqrqv7fcncdly6cswlzp4x8650hq48dxmc279wmj"; |
||||
sgr-iosevka-fixed-ss16 = "1dxfn2lzgdcdzq5p35q0cafyrq15zmfn5gf8iw4g9xjl4hyyzi29"; |
||||
sgr-iosevka-fixed-ss17 = "0zaxqaxng61gwr2zywq7b4m0aaiqwkb3khpadzcnvd1i4ggx9n7l"; |
||||
sgr-iosevka-fixed-ss18 = "150ialpsvkmnhisv73x9w5dlmvh2a3496zrpyk03xqz9vzxmxw84"; |
||||
sgr-iosevka-slab = "12i3fgr0pj0mp9mcwfd221f6lj6fbf4cj77wq173hzjkjn8l7gbj"; |
||||
sgr-iosevka-ss01 = "1bdba7693iszm1y2zs0c3rsz8wwsgvf9zj9l93fjgnhmxfigkwlx"; |
||||
sgr-iosevka-ss02 = "13pdpg1rhvv86y2wplswri95dpfsly4x37bpflyd1n60rzcgp4d1"; |
||||
sgr-iosevka-ss03 = "199nvbfvwfbn7qfdxzibb38avbwx6476c3iwd93q21d49zk4xfrk"; |
||||
sgr-iosevka-ss04 = "17kv8039g5xdwqmg8ywjnfk95742izrdj5dxkzwq2s3kpqz4yikz"; |
||||
sgr-iosevka-ss05 = "1xg4ds6gfa5h90lggs8sbx2icz7rklq4rgzbrk9x1z3mnmmprm3r"; |
||||
sgr-iosevka-ss06 = "00mrcklg9ijyqhsq848xlqi1s66alkcv7h73qnqjqvsd4a0q6lww"; |
||||
sgr-iosevka-ss07 = "0p0x3974kwlw5m3wn0ngk5ik7apd94hyp2a9b1rw6ndv864h0j5y"; |
||||
sgr-iosevka-ss08 = "12fywxdmsaqbq8xaxgbigjj89g2c0y2brps31mkdz0l1ba329192"; |
||||
sgr-iosevka-ss09 = "0pjl8h2bf6v0llqjs52k9gq3mm31jl80phzcqsz5vx17p5gn7wnn"; |
||||
sgr-iosevka-ss10 = "1cww7ing7is6r6naj3nwaq24v3gqsk0pj9d8r167a5mr8zhx7pqb"; |
||||
sgr-iosevka-ss11 = "1rl13qmxqc8ajshc9ylbb29w8kx5ad5bz71xjw7j646k30hsl8fc"; |
||||
sgr-iosevka-ss12 = "1zyhz1k1a534hq04prw9f8rjm4yrxmc30c65jpx1d94ckzbzj1qm"; |
||||
sgr-iosevka-ss13 = "0rh9w9jdbhi56dcwf51api3v8gqfpzjz91ccnikikrg413b3r2qs"; |
||||
sgr-iosevka-ss14 = "0s2sqdmfnlqzz07spvkhyxg5fj4r4bx2ik2mglqzbawc0fmp6ajn"; |
||||
sgr-iosevka-ss15 = "1kya4lyvcph6d80zbgr1b3189yqa4cngx5bzgp09437pb84k7lv3"; |
||||
sgr-iosevka-ss16 = "1d453qf4arvzxyivj789y9dd87sqg392fl1xshwh56h7rx4qbv4q"; |
||||
sgr-iosevka-ss17 = "1qbvr1307gkqyxgx2sqvc6jvv4x0pibcsxbmp7ih96pk9sryfw06"; |
||||
sgr-iosevka-ss18 = "0lqcjymaxxh2p3irqmyfsq15339amwdnyizi71lh0p16sypcc14f"; |
||||
sgr-iosevka-term = "04fwjyc44kmwaaqm4f47az24vrl502hi8mqjhm3mjhpm7a7ysywx"; |
||||
sgr-iosevka-term-curly = "1h0g2jhv2qirlrqjs7w72db00xvm99agwddb9mngmsg5m97dywmm"; |
||||
sgr-iosevka-term-curly-slab = "0m641zbd4232vpnc92phvsxvzpl33xvrkrm22hxysmwwm6b4sb68"; |
||||
sgr-iosevka-term-slab = "0k8pijigr6i0y2d91c9irkm4xcw8pqwqyv1dpn2y4q6nbrm1jvcs"; |
||||
sgr-iosevka-term-ss01 = "1vv1japj1dxp36smvs4lb9hqlcrkvxandrknjswd343acwf9pr6y"; |
||||
sgr-iosevka-term-ss02 = "11s5zidgx2rdvpix32h9j1d1in35s7acwwfxzf78ba3zlsmkslis"; |
||||
sgr-iosevka-term-ss03 = "179wrslzrji05d2pgcjrspgqmmym6r9ihcjqq8fci7y0nwn2pbzm"; |
||||
sgr-iosevka-term-ss04 = "1g64fviviykl8mwdsd4cjwjcsfjnskjmcxm8kfq22xlh0s9h6p1k"; |
||||
sgr-iosevka-term-ss05 = "15s3q5yv5qv5h6lrw9mjw97csaiql1lqsf8sb0v7is0qk28qld78"; |
||||
sgr-iosevka-term-ss06 = "1i8jb8is2xmdz2m1wh51708861rfvkia28qic9c30xq50a49n4ls"; |
||||
sgr-iosevka-term-ss07 = "15mbhilmv72f824sqks4vkqkh46zs5z46sbibw7vfgz6b5wyknl0"; |
||||
sgr-iosevka-term-ss08 = "02a9ws0fnzrdc4p54sb5x85z46i2071lq24i4676l8q42szf0xal"; |
||||
sgr-iosevka-term-ss09 = "0kakm3fszw6gxr2294fi8pm52drjdihb0sg2ickq5jf22pbknswy"; |
||||
sgr-iosevka-term-ss10 = "1c8jahi1ilny09gm5lvjm1fgqvcfjb9g9hn9f2q7b3cb5m1p3iya"; |
||||
sgr-iosevka-term-ss11 = "1y67g39x2lyw0j7xx3ga4sncrh7q6fciyl26ql2c9jvm9fs6yywh"; |
||||
sgr-iosevka-term-ss12 = "1zg4459v8m21dip5lbfxvp57x64h3js7lzb675m5nhqgyw01phxf"; |
||||
sgr-iosevka-term-ss13 = "0fqc1gpxw8bd0023vvp7js9q1wxinz7j3n6q9c0amq8niw7572d5"; |
||||
sgr-iosevka-term-ss14 = "04q6kq0d0bzarxa976gnq4xvk28r0q2s9wji5av6nivj7df85zl0"; |
||||
sgr-iosevka-term-ss15 = "1ccvb520vfmhsgp9ra1yysc5c93a2d3nasb45f9ppsqbjf3slrz0"; |
||||
sgr-iosevka-term-ss16 = "1spdadjssjnxp63wp04vncnfpyrkjlfkxrsyf8wbarg81c8zz1b3"; |
||||
sgr-iosevka-term-ss17 = "1vm1nkk3arpyk92x4pjccs1d2b5zqqa1pzv0vavnchhri8q6csrd"; |
||||
sgr-iosevka-term-ss18 = "0rpc7hcyc0dv174zk9crdz152bd342d1zinc1xsdm10qnf72ssbr"; |
||||
} |
||||
|
@ -0,0 +1,27 @@ |
||||
{ lib, stdenv, fetchMavenArtifact }: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "liquibase-redshift-extension"; |
||||
version = "4.8.0"; |
||||
|
||||
src = fetchMavenArtifact { |
||||
artifactId = "liquibase-redshift"; |
||||
groupId = "org.liquibase.ext"; |
||||
sha256 = "sha256-jZdDKAC4Cvmkih8VH84Z3Q8BzsqGO55Uefr8vOlbDAk="; |
||||
inherit version; |
||||
}; |
||||
|
||||
installPhase = '' |
||||
runHook preInstall |
||||
install -m444 -D $src/share/java/liquibase-redshift-${version}.jar $out/share/java/liquibase-redshift.jar |
||||
runHook postInstall |
||||
''; |
||||
|
||||
meta = with lib; { |
||||
homepage = "https://github.com/liquibase/liquibase-redshift/"; |
||||
description = "Amazon Redshift extension for Liquibase"; |
||||
license = licenses.asl20; |
||||
platforms = platforms.unix; |
||||
maintainers = with maintainers; [ sir4ur0n ]; |
||||
}; |
||||
} |
@ -0,0 +1,28 @@ |
||||
{ lib, stdenv, fetchMavenArtifact }: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "redshift-jdbc"; |
||||
version = "2.1.0.3"; |
||||
|
||||
src = fetchMavenArtifact { |
||||
artifactId = "redshift-jdbc42"; |
||||
groupId = "com.amazon.redshift"; |
||||
sha256 = "sha256-TO/JXh/pZ7tUZGfHqkzgZx18gLnISvnPVyGavzFv6vo="; |
||||
inherit version; |
||||
}; |
||||
|
||||
installPhase = '' |
||||
runHook preInstall |
||||
install -m444 -D $src/share/java/redshift-jdbc42-${version}.jar $out/share/java/redshift-jdbc42.jar |
||||
runHook postInstall |
||||
''; |
||||
|
||||
meta = with lib; { |
||||
homepage = "https://github.com/aws/amazon-redshift-jdbc-driver/"; |
||||
description = |
||||
"JDBC 4.2 driver for Amazon Redshift allowing Java programs to connect to a Redshift database"; |
||||
license = licenses.asl20; |
||||
platforms = platforms.unix; |
||||
maintainers = with maintainers; [ sir4ur0n ]; |
||||
}; |
||||
} |
@ -0,0 +1 @@ |
||||
imported.nix linguist-vendored |
@ -0,0 +1,3 @@ |
||||
result |
||||
*.sqlite |
||||
*.fasl |
@ -0,0 +1,197 @@ |
||||
## The API |
||||
|
||||
This page documents the Nix API of nix-cl. |
||||
|
||||
## Overview |
||||
|
||||
The core API functions are `build-asdf-system` and |
||||
`lispWithPackagesInternal`. |
||||
|
||||
They are considered more low-level that the rest of the API, which |
||||
builds on top of them to provide a more convenient interface with sane |
||||
defaults. |
||||
|
||||
The higher-level API provides a lot of pre-configured packages, |
||||
including all of Quicklisp, and consists of the functions: |
||||
|
||||
- `lispPackagesFor` |
||||
- `lispWithPackages` |
||||
|
||||
Finally, there are functions that provide pre-defined Lisps, for |
||||
people who don't need to customize that: |
||||
|
||||
- `abclPackages`, `eclPackages`, `cclPackages`, `claspPackages`, `sbclPackages` |
||||
- `abclWithPackages`, `eclWithPackages`, `cclWithPackages`, `claspWithPackages`, `sbclWithPackages` |
||||
|
||||
The following is an attempt to document all of this. |
||||
|
||||
## Packaging systems - `build-asdf-system` |
||||
|
||||
Packages are declared using `build-asdf-system`. This function takes |
||||
the following arguments and returns a `derivation`. |
||||
|
||||
#### Required arguments |
||||
|
||||
##### `pname` |
||||
Name of the package/library |
||||
|
||||
##### `version` |
||||
Version of the package/library |
||||
|
||||
##### `src` |
||||
Source of the package/library (`fetchzip`, `fetchgit`, `fetchhg` etc.) |
||||
|
||||
##### `lisp` |
||||
This command must load the provided file (`$buildScript`) then exit |
||||
immediately. For example, SBCL's --script flag does just that. |
||||
|
||||
#### Optional arguments |
||||
|
||||
##### `patches ? []` |
||||
|
||||
Patches to apply to the source code before compiling it. This is a |
||||
list of files. |
||||
|
||||
##### `nativeLibs ? []` |
||||
|
||||
Native libraries, will be appended to the library |
||||
path. (`pkgs.openssl` etc.) |
||||
|
||||
##### `javaLibs ? []` |
||||
|
||||
Java libraries for ABCL, will be appended to the class path. |
||||
|
||||
##### `lispLibs ? []` |
||||
|
||||
Lisp dependencies These must themselves be packages built with |
||||
`build-asdf-system` |
||||
|
||||
##### `systems ? [ pname ]` |
||||
|
||||
Some libraries have multiple systems under one project, for example, |
||||
[cffi] has `cffi-grovel`, `cffi-toolchain` etc. By default, only the |
||||
`pname` system is build. |
||||
|
||||
`.asd's` not listed in `systems` are removed before saving the library |
||||
to the Nix store. This prevents ASDF from referring to uncompiled |
||||
systems on run time. |
||||
|
||||
Also useful when the `pname` is differrent than the system name, such |
||||
as when using [reverse domain naming]. (see `jzon` -> |
||||
`com.inuoe.jzon`) |
||||
|
||||
[cffi]: https://cffi.common-lisp.dev/ |
||||
[reverse domain naming]: https://en.wikipedia.org/wiki/Reverse_domain_name_notation |
||||
|
||||
##### `asds ? systems` |
||||
|
||||
The .asd files that this package provides. By default, same as |
||||
`systems`. |
||||
|
||||
#### Return value |
||||
|
||||
A `derivation` that, when built, contains the sources and pre-compiled |
||||
FASL files (Lisp implementation dependent) alongside any other |
||||
artifacts generated during compilation. |
||||
|
||||
#### Example |
||||
|
||||
[bordeaux-threads.nix] contains a simple example of packaging |
||||
`alexandria` and `bordeaux-threads`. |
||||
|
||||
[bordeaux-threads.nix]: /examples/bordeaux-threads.nix |
||||
|
||||
## Building a Lisp with packages: `lispWithPackagesInternal` |
||||
|
||||
Generators of Lisps configured to be able to `asdf:load-system` |
||||
pre-compiled libraries on run-time are built with |
||||
`lispWithPackagesInternal`. |
||||
|
||||
#### Required Arguments |
||||
|
||||
##### `clpkgs` |
||||
|
||||
An attribute set of `derivation`s returned by `build-asdf-system` |
||||
|
||||
#### Return value |
||||
|
||||
`lispWithPackagesInternal` returns a function that takes one argument: |
||||
a function `(lambda (clpkgs) packages)`, that, given a set of |
||||
packages, returns a list of package `derivation`s to be included in |
||||
the closure. |
||||
|
||||
#### Example |
||||
|
||||
The [sbcl-with-bt.nix] example creates a runnable Lisp where the |
||||
`bordeaux-threads` defined in the previous section is precompiled and |
||||
loadable via `asdf:load-system`: |
||||
|
||||
[sbcl-with-bt.nix]: /examples/sbcl-with-bt.nix |
||||
|
||||
## Reusing pre-packaged Lisp libraries: `lispPackagesFor` |
||||
|
||||
`lispPackagesFor` is a higher level version of |
||||
`lispPackagesForInternal`: it only takes one argument - a Lisp command |
||||
to use for compiling packages. It then provides a bunch of ready to |
||||
use packages. |
||||
|
||||
#### Required Arguments |
||||
|
||||
##### `lisp` |
||||
|
||||
The Lisp command to use in calls to `build-asdf-system` while building |
||||
the library-provided Lisp package declarations. |
||||
|
||||
#### Return value |
||||
|
||||
A set of packages built with `build-asdf-system`. |
||||
|
||||
#### Example |
||||
|
||||
The [abcl-package-set.nix] example generates a set of thousands of packages for ABCL. |
||||
|
||||
[abcl-package-set.nix]: /examples/abcl-package-set.nix |
||||
|
||||
## Reusing pre-packaged Lisp libraries, part 2: `lispWithPackages` |
||||
|
||||
This is simply a helper function to avoid having to call |
||||
`lispPackagesFor` if all you want is a Lisp-with-packages wrapper. |
||||
|
||||
#### Required Arguments |
||||
|
||||
##### `lisp` |
||||
|
||||
The Lisp command to pass to `lispPackagesFor` in order for it to |
||||
generate a package set. That set is then passed to |
||||
`lispWithPackagesInternal`. |
||||
|
||||
#### Return value |
||||
|
||||
A Lisp-with-packages function (see sections above). |
||||
|
||||
#### Example |
||||
|
||||
The [abcl-with-packages.nix] example creates an `abclWithPackages` function. |
||||
|
||||
[abcl-with-packages.nix]: /examples/abcl-with-packages.nix |
||||
|
||||
## Using the default Lisp implementations |
||||
|
||||
This is the easiest way to get going with `nix-cl` in general. Choose |
||||
the CL implementation of interest and a set of libraries, and get a |
||||
lisp-with-packages wrapper with those libraries pre-compiled. |
||||
|
||||
#### `abclPackages`, `eclPackages`, `cclPackages`, `claspPackages`, `sbclPackages` |
||||
|
||||
Ready to use package sets. |
||||
|
||||
#### `abclWithPackages`, `eclWithPackages`, `cclWithPackages`, `claspWithPackages`, `sbclWithPackages` |
||||
|
||||
Ready to use wrapper generators. |
||||
|
||||
#### Example |
||||
|
||||
For example, to open a shell with SBCL + hunchentoot + sqlite in PATH: |
||||
``` |
||||
nix-shell -p 'with import ./. {}; sbclWithPackages (ps: [ ps.hunchentoot ps.sqlite ])' |
||||
``` |
@ -0,0 +1,98 @@ |
||||
## Use cases |
||||
|
||||
This page lists some possible use cases for nix-cl. |
||||
|
||||
## Pinning down the exact commits of libraries |
||||
|
||||
Sometimes, a bug is fixed upstream but is not yet available in package |
||||
repositories such as Quicklisp or Ultralisp. The users have to wait |
||||
for the repository maintainer to update it, or download and compile |
||||
the patched sources themselves. |
||||
|
||||
This is a manual and hard to reproduce process. By leveraging Nix, |
||||
users of `nix-cl` can essentially "run their own package repository", |
||||
written as Nix code, with all the benefits of that (shareability, |
||||
cacheability, reproducibility, version-controllable etc.) |
||||
|
||||
|
||||
## Modifying libraries with patches |
||||
|
||||
Other times, a bug in a library is not fixed upstream, but you fixed |
||||
it yourself. Or, you would like a change to the internals that the |
||||
maintainers don't like. |
||||
|
||||
Sure, you could fork the code or maintain patches manually, but that |
||||
becomes hard to manage with a lot of patches. It also doesn't have the |
||||
benefits mentioned in the previous section. |
||||
|
||||
`nix-cl` provides a way of applying version-controlled patches to any |
||||
package. |
||||
|
||||
|
||||
## Using libraries not available in repositories |
||||
|
||||
There are useful and working libraries out there, that are nontheless |
||||
unavailable to users of package managers such as Quicklisp or |
||||
Ultralisp. Two real-world examples are [jzon] and [cl-tar]. |
||||
|
||||
`nix-cl` is not tied to any particular package source: instead, |
||||
packages are written as a Nix expression, which can be done manually |
||||
or generated/imported. |
||||
|
||||
This frees the user to have any package they want, and not be |
||||
constrained by a central repository. |
||||
|
||||
## Reproducible environments |
||||
|
||||
The usual way to develop a project involves several steps, such as: |
||||
|
||||
1. Installing a Lisp implementation |
||||
2. Installing a package manager |
||||
3. Installing the chosen libraries |
||||
|
||||
This is not necessarily reproducible. It's unlikely to come back a |
||||
year later and develop the project using the exact same versions of |
||||
the dependencies. |
||||
|
||||
Things can break between attempts at different points in time. The |
||||
repository could have updated versions in the meantime. The source |
||||
tarballs could become unreachable. |
||||
|
||||
With `nix-cl` you can have your own binary cache for Lisp libraries |
||||
and not be affected by downtime of other central repositories. |
||||
|
||||
## Testing across CL implementations |
||||
|
||||
One can manually download different Lisp implementations and run tests |
||||
of a package. This works well in most cases, but it is limited in how |
||||
you can tweak the software. Some practical examples are: |
||||
|
||||
- Statically compiling [zlib] into [SBCL] |
||||
- Building SBCL with the `--fancy` flag |
||||
- Compiling [ECL] as a static library |
||||
|
||||
These are usually hard to do manually, unless you have the necessary |
||||
compilers already configured. These combinations are usually not |
||||
available from package managers as well. |
||||
|
||||
With Nix it's easier, because it will set up the build environment |
||||
automatically. It could be useful to, for example: |
||||
|
||||
- Test against all possible compiler flag combinations |
||||
- Libc versions (ECL) |
||||
- JDK versions ([ABCL]) |
||||
|
||||
[zlib]: https://zlib.net |
||||
[SBCL]: https://sbcl.org |
||||
[ECL]: https://ecl.common-lisp.dev/ |
||||
[Ultralisp]: https://ultralisp.org/ |
||||
[jzon]: https://github.com/Zulu-Inuoe/jzon |
||||
[cl-tar]: https://gitlab.common-lisp.net/cl-tar/cl-tar |
||||
[bootstrap tools]: https://github.com/NixOS/nixpkgs/tree/master/pkgs/stdenv/linux/bootstrap-files |
||||
[nixpkgs]: https://github.com/NixOS/nixpkgs |
||||
|
||||
## Windows note |
||||
|
||||
Note that all of this still only applies to Unix systems - primarily because Nix doesn't work on Windows. |
||||
|
||||
If you have an idea how to port some of the functionality to Windows, get in touch. |
@ -0,0 +1,54 @@ |
||||
## Importing package definitions from Quicklisp |
||||
|
||||
This page documents how to import packages from Quicklisp. |
||||
|
||||
## Nix dumper |
||||
|
||||
Run: |
||||
|
||||
``` |
||||
$ nix-shell |
||||
$ sbcl --script ql-import.lisp |
||||
``` |
||||
|
||||
This command runs a program that dumps a `imported.nix` file |
||||
containing Nix expressions for all packages in Quicklisp. They will be |
||||
automatically picked up by the `lispPackagesFor` and |
||||
`lispWithPackages` API functions. |
||||
|
||||
It also creates a 'packages.sqlite' file. It's used during the |
||||
generation of the 'imported.nix' file and can be safely removed. It |
||||
contains the full information of Quicklisp packages, so you can use it |
||||
to query the dependency graphs using SQL, if you're interested. |
||||
|
||||
## Tarball hashes |
||||
|
||||
The Nix dumper program will re-use hashes from "imported.nix" if it |
||||
detects that it's being run for the first time. This saves a lot of |
||||
bandwidth by not having to download each tarball again. |
||||
|
||||
But when upgrading the Quicklisp release URL, this can take a while |
||||
because it needs to fetch the source code of each new system to |
||||
compute its SHA256 hash. This is because Quicklisp only provides a |
||||
SHA1 , and Nix's `builtins.fetchTarball` requires a SHA256. |
||||
|
||||
Later on, the hashes are cached in `packages.sqlite`, and are reused |
||||
in subsequent invocations. Therefore you might want to keep the |
||||
'packages.sqlite' file around if you'd like to keep hashes of |
||||
historical Quicklisp tarballs, for example for archival purposes. |
||||
|
||||
## Choosing a Quicklisp release |
||||
|
||||
Quicklisp release url's are currently hard-coded and can be changed |
||||
directly in the source code. See the `import` directory. |
||||
|
||||
## Native and Java libraries |
||||
|
||||
At the moment, native and Java libraries need to be added manually to |
||||
imported systems in `ql.nix` on an as-needed basis. |
||||
|
||||
## Dependencies from packages.nix |
||||
|
||||
Also worth noting is that systems imported from Quicklisp will prefer |
||||
packages from `packages.nix` as dependencies, so that custom versions |
||||
can be provided or broken versions replaced. |
@ -0,0 +1,5 @@ |
||||
## Quirks |
||||
|
||||
- `+` in names are converted to `_plus{_,}`: `cl+ssl`->`cl_plus_ssl`, `alexandria+`->`alexandria_plus` |
||||
- `.` to `_dot_`: `iolib.base`->`iolib_dot_base` |
||||
- names starting with a number have a `_` prepended (`3d-vectors`->`_3d-vectors`) |
@ -0,0 +1,24 @@ |
||||
# To run this example from a nix repl, run: |
||||
# $ nix repl |
||||
# nix-repl> abcl-packages = import ./abcl-package-set.nix |
||||
# nix-repl> builtins.attrNames abcl-packages |
||||
# nix-repl> builtins.length (builtins.attrNames abcl-packages) |
||||
# |
||||
# The import returns a package set, which you can use for example to |
||||
# discover what packages are available in lispWithPackages: |
||||
# |
||||
# nix-repl> abcl-packages.cl-op<TAB> |
||||
# nix-repl> abcl-packages.cl-opengl |
||||
# nix-repl> # cool, we can use cl-opengl |
||||
# nix-repl> # some-abcl-with-packages (p: [ p.cl-opengl ]) |
||||
|
||||
|
||||
let |
||||
|
||||
pkgs = import ../../../../default.nix {}; |
||||
|
||||
abcl = "${pkgs.abcl}/bin/abcl --batch --load"; |
||||
|
||||
abcl-packages = pkgs.lispPackages_new.lispPackagesFor abcl; |
||||
|
||||
in abcl-packages |
@ -0,0 +1,23 @@ |
||||
# To run this example from a nix repl, run: |
||||
# $ nix repl |
||||
# nix-repl> abcl-with-packages = import ./abcl-with-packages.nix |
||||
# nix-repl> :b abcl-with-packages (p: [ p.cffi ]) |
||||
# |
||||
# The import returns a function, which you can call to get access to |
||||
# thousands of libraries, like, cffi. This works in ABCL by closing |
||||
# over the JNA dependency: |
||||
# |
||||
# nix-repl> awp = abcl-with-packages (p: [ p.cffi ]) |
||||
# nix-repl> awp.CLASSPATH |
||||
# nix-repl> cffi = builtins.head (awp.lispLibs) |
||||
# nix-repl> cffi.javaLibs |
||||
|
||||
let |
||||
|
||||
pkgs = import ../../../../default.nix {}; |
||||
|
||||
abcl = "${pkgs.abcl}/bin/abcl --batch --load"; |
||||
|
||||
abcl-with-packages = pkgs.lispPackages_new.lispWithPackages abcl; |
||||
|
||||
in abcl-with-packages |
@ -0,0 +1,43 @@ |
||||
# To run this example from the command line, run this command: |
||||
# |
||||
# $ nix-build ./bordeaux-threads.nix |
||||
# $ ls ./result/ |
||||
# |
||||
# To run from a nix repl, run: |
||||
# $ nix repl |
||||
# nix-repl> bt = import ./bordeaux-threads.nix |
||||
# nix-repl> :b bt |
||||
# |
||||
# In the `result` directory you can find .fasl files of the |
||||
# bordeaux-threads library: |
||||
# |
||||
# $ ls -l ./result/src/ |
||||
|
||||
let |
||||
|
||||
pkgs = import ../../../../default.nix {}; |
||||
|
||||
sbcl = "${pkgs.sbcl}/bin/sbcl --script"; |
||||
|
||||
alexandria = pkgs.lispPackages_new.build-asdf-system { |
||||
pname = "alexandria"; |
||||
version = "v1.4"; |
||||
src = pkgs.fetchzip { |
||||
url = "https://gitlab.common-lisp.net/alexandria/alexandria/-/archive/v1.4/alexandria-v1.4.tar.gz"; |
||||
sha256 = "0r1adhvf98h0104vq14q7y99h0hsa8wqwqw92h7ghrjxmsvz2z6l"; |
||||
}; |
||||
lisp = sbcl; |
||||
}; |
||||
|
||||
bordeaux-threads = pkgs.lispPackages_new.build-asdf-system { |
||||
pname = "bordeaux-threads"; |
||||
version = "0.8.8"; |
||||
src = pkgs.fetchzip { |
||||
url = "http://github.com/sionescu/bordeaux-threads/archive/v0.8.8.tar.gz"; |
||||
sha256 = "19i443fz3488v1pbbr9x24y8h8vlyhny9vj6c9jk5prm702awrp6"; |
||||
}; |
||||
lisp = sbcl; |
||||
lispLibs = [ alexandria ]; |
||||
}; |
||||
|
||||
in bordeaux-threads |
@ -0,0 +1,31 @@ |
||||
# To run this example from the command line, run this command: |
||||
# $ nix-build ./sbcl-with-bt.nix |
||||
# $ ls ./result/ |
||||
# |
||||
# To run from a nix repl, run: |
||||
# $ nix repl |
||||
# nix-repl> sbcl-bt = import ./sbcl-with-bt.nix |
||||
# nix-repl> :b sbcl-bt |
||||
# |
||||
# In the `result/bin` directory you can find an `sbcl` executable |
||||
# that, when started, is able to load the pre-compiled |
||||
# bordeaux-threads from the Nix store: |
||||
# $ ./result/bin/sbcl |
||||
# * (require :asdf) |
||||
# * (asdf:load-system :bordeaux-threads) |
||||
|
||||
let |
||||
|
||||
pkgs = import ../../../../default.nix {}; |
||||
|
||||
sbcl = "${pkgs.sbcl}/bin/sbcl --script"; |
||||
|
||||
bordeaux-threads = import ./bordeaux-threads.nix; |
||||
|
||||
sbclPackages = { inherit bordeaux-threads; }; |
||||
|
||||
sbclWithPackages = pkgs.lispPackages_new.lispWithPackagesInternal sbclPackages; |
||||
|
||||
sbcl-bt = sbclWithPackages (p: [ p.bordeaux-threads ]); |
||||
|
||||
in sbcl-bt |
@ -0,0 +1,18 @@ |
||||
(defpackage org.lispbuilds.nix/api |
||||
(:documentation "Public interface of org.lispbuilds.nix") |
||||
(:use :cl) |
||||
(:export |
||||
:import-lisp-packages |
||||
:database->nix-expression)) |
||||
|
||||
(in-package org.lispbuilds.nix/api) |
||||
|
||||
(defgeneric import-lisp-packages (repository database) |
||||
(:documentation |
||||
"Import Lisp packages (ASDF systems) from repository (Quicklisp, |
||||
Ultralisp etc.) into a package database.")) |
||||
|
||||
(defgeneric database->nix-expression (database outfile) |
||||
(:documentation |
||||
"Generate a nix expression from the package database and write it |
||||
into outfile.")) |
@ -0,0 +1,134 @@ |
||||
(defpackage org.lispbuilds.nix/database/sqlite |
||||
(:use :cl) |
||||
(:import-from :str) |
||||
(:import-from :sqlite) |
||||
(:import-from :alexandria :read-file-into-string) |
||||
(:import-from :arrow-macros :->>) |
||||
(:import-from |
||||
:org.lispbuilds.nix/util |
||||
:replace-regexes) |
||||
(:import-from |
||||
:org.lispbuilds.nix/nix |
||||
:nix-eval |
||||
:system-master |
||||
:nixify-symbol |
||||
:make-pname |
||||
:*nix-attrs-depth*) |
||||
(:import-from |
||||
:org.lispbuilds.nix/api |
||||
:database->nix-expression) |
||||
(:export :sqlite-database :init-db) |
||||
(:local-nicknames |
||||
(:json :com.inuoe.jzon))) |
||||
|
||||
(in-package org.lispbuilds.nix/database/sqlite) |
||||
|
||||
(defclass sqlite-database () |
||||
((url :initarg :url |
||||
:reader database-url |
||||
:initform (error "url required")) |
||||
(init-file :initarg :init-file |
||||
:reader init-file |
||||
:initform (error "init file required")))) |
||||
|
||||
(defun init-db (db init-file) |
||||
(let ((statements (->> (read-file-into-string init-file) |
||||
(replace-regexes '(".*--.*") '("")) |
||||
(substitute #\Space #\Newline) |
||||
(str:collapse-whitespaces) |
||||
(str:split #\;) |
||||
(mapcar #'str:trim) |
||||
(remove-if #'str:emptyp)))) |
||||
(sqlite:with-transaction db |
||||
(dolist (s statements) |
||||
(sqlite:execute-non-query db s))))) |
||||
|
||||
|
||||
;; Writing Nix |
||||
|
||||
(defparameter prelude " |
||||
# This file was auto-generated by nix-quicklisp.lisp |
||||
|
||||
{ runCommand, fetchzip, pkgs, ... }: |
||||
|
||||
# Ensures that every non-slashy `system` exists in a unique .asd file. |
||||
# (Think cl-async-base being declared in cl-async.asd upstream) |
||||
# |
||||
# This is required because we're building and loading a system called |
||||
# `system`, not `asd`, so otherwise `system` would not be loadable |
||||
# without building and loading `asd` first. |
||||
# |
||||
let createAsd = { url, sha256, asd, system }: |
||||
let |
||||
src = fetchzip { inherit url sha256; }; |
||||
in runCommand \"source\" {} '' |
||||
mkdir -pv $out |
||||
cp -r ${src}/* $out |
||||
find $out -name \"${asd}.asd\" | while read f; do mv -fv $f $(dirname $f)/${system}.asd || true; done |
||||
''; |
||||
|
||||
getAttr = builtins.getAttr; |
||||
|
||||
in {") |
||||
|
||||
(defmethod database->nix-expression ((database sqlite-database) outfile) |
||||
(sqlite:with-open-database (db (database-url database)) |
||||
(with-open-file (f outfile |
||||
:direction :output |
||||
:if-exists :supersede) |
||||
|
||||
;; Fix known problematic packages before dumping the nix file. |
||||
(sqlite:execute-non-query db |
||||
"create temp table fixed_systems as select * from system_view") |
||||
|
||||
(sqlite:execute-non-query db |
||||
"alter table fixed_systems add column systems") |
||||
|
||||
(sqlite:execute-non-query db |
||||
"update fixed_systems set systems = json_array(name)") |
||||
|
||||
(sqlite:execute-non-query db |
||||
"alter table fixed_systems add column asds") |
||||
|
||||
(sqlite:execute-non-query db |
||||
"update fixed_systems set asds = json_array(name)") |
||||
|
||||
(format f prelude) |
||||
|
||||
(dolist (p (sqlite:execute-to-list db "select * from fixed_systems")) |
||||
(destructuring-bind (name version asd url sha256 deps systems asds) p |
||||
(format f "~% ") |
||||
(let ((*nix-attrs-depth* 1)) |
||||
(format |
||||
f |
||||
"~a = ~a;" |
||||
(nix-eval `(:symbol ,name)) |
||||
(nix-eval |
||||
`(:attrs |
||||
("pname" (:string ,(make-pname name))) |
||||
("version" (:string ,version)) |
||||
("asds" (:list |
||||
,@(mapcar (lambda (asd) |
||||
`(:string ,(system-master asd))) |
||||
(coerce (json:parse asds) 'list)))) |
||||
("src" (:funcall |
||||
"createAsd" |
||||
(:attrs |
||||
("url" (:string ,url)) |
||||
("sha256" (:string ,sha256)) |
||||
("system" (:string ,(system-master name))) |
||||
("asd" (:string ,asd))))) |
||||
("systems" (:list |
||||
,@(mapcar (lambda (sys) |
||||
`(:string ,sys)) |
||||
(coerce (json:parse systems) 'list)))) |
||||
("lispLibs" (:list |
||||
,@(mapcar (lambda (dep) |
||||
`(:funcall |
||||
"getAttr" |
||||
(:string ,(nixify-symbol dep)) |
||||
(:symbol "pkgs"))) |
||||
(remove "asdf" |
||||
(str:split-omit-nulls #\, deps) |
||||
:test #'string=)))))))))) |
||||
(format f "~%}~%")))) |
@ -0,0 +1,41 @@ |
||||
CREATE TABLE IF NOT EXISTS sha256 ( |
||||
id integer PRIMARY KEY AUTOINCREMENT, |
||||
url text UNIQUE, |
||||
hash text NOT NULL, |
||||
created real DEFAULT (julianday('now')) |
||||
); |
||||
|
||||
CREATE TABLE IF NOT EXISTS system ( |
||||
id integer PRIMARY KEY AUTOINCREMENT, |
||||
name text NOT NULL, |
||||
version text NOT NULL, |
||||
asd text NOT NULL, |
||||
created real DEFAULT (julianday('now')), |
||||
UNIQUE(name, version) |
||||
); |
||||
|
||||
CREATE TABLE IF NOT EXISTS dep ( |
||||
system_id integer NOT NULL REFERENCES system(id), |
||||
dep_id integer NOT NULL REFERENCES system(id), |
||||
PRIMARY KEY (system_id, dep_id) |
||||
); |
||||
|
||||
CREATE TABLE IF NOT EXISTS src ( |
||||
sha256_id integer REFERENCES sha256(id), |
||||
system_id integer UNIQUE REFERENCES system(id) |
||||
); |
||||
|
||||
DROP VIEW IF EXISTS system_view; |
||||
CREATE VIEW IF NOT EXISTS system_view AS |
||||
SELECT |
||||
sys.name, |
||||
sys.version, |
||||
sys.asd, |
||||
sha.url, |
||||
sha.hash, |
||||
group_concat((SELECT name FROM system WHERE id = dep.dep_id)) as deps |
||||
FROM system sys |
||||
JOIN src ON src.system_id = sys.id |
||||
JOIN sha256 sha ON sha.id = src.sha256_id |
||||
LEFT JOIN dep ON dep.system_id = sys.id |
||||
GROUP BY sys.name; |
@ -0,0 +1,40 @@ |
||||
(defpackage org.lispbuilds.nix/main |
||||
(:use :common-lisp |
||||
:org.lispbuilds.nix/database/sqlite |
||||
:org.lispbuilds.nix/repository/quicklisp |
||||
:org.lispbuilds.nix/api)) |
||||
|
||||
(in-package org.lispbuilds.nix/main) |
||||
|
||||
(defun resource (name type) |
||||
(make-pathname |
||||
:defaults (asdf:system-source-directory :org.lispbuilds.nix) |
||||
:name name |
||||
:type type)) |
||||
|
||||
(defvar *sqlite* |
||||
(make-instance |
||||
'sqlite-database |
||||
:init-file (resource "init" "sql") |
||||
:url "packages.sqlite")) |
||||
|
||||
(defvar *quicklisp* |
||||
(make-instance |
||||
'quicklisp-repository |
||||
:dist-url |
||||
"https://beta.quicklisp.org/dist/quicklisp/2021-12-30/")) |
||||
|
||||
(defun run-importers () |
||||
(import-lisp-packages *quicklisp* *sqlite*) |
||||
(format t "Imported packages from quicklisp to ~A~%" |
||||
(truename "packages.sqlite"))) |
||||
|
||||
(defun gen-nix-file () |
||||
(database->nix-expression *sqlite* "imported.nix") |
||||
(format t "Dumped nix file to ~a~%" |
||||
(truename "imported.nix"))) |
||||
|
||||
(defun main () |
||||
(format t "~%") |
||||
(run-importers) |
||||
(gen-nix-file)) |
@ -0,0 +1,81 @@ |
||||
(defpackage org.lispbuilds.nix/nix |
||||
(:documentation "Utilities for generating Nix code") |
||||
(:use :cl) |
||||
(:import-from :str) |
||||
(:import-from :ppcre) |
||||
(:import-from :arrow-macros :->>) |
||||
(:import-from :org.lispbuilds.nix/util :replace-regexes) |
||||
(:export |
||||
:nix-eval |
||||
:system-master |
||||
:nixify-symbol |
||||
:make-pname |
||||
:*nix-attrs-depth*)) |
||||
|
||||
(in-package org.lispbuilds.nix/nix) |
||||
|
||||
;; Path names are alphanumeric and can include the symbols +-._?= and |
||||
;; must not begin with a period. |
||||
(defun make-pname (string) |
||||
(replace-regexes '("^[.]" "[^a-zA-Z0-9+-._?=]") |
||||
'("_" "_") |
||||
string)) |
||||
|
||||
(defun system-master (system) |
||||
(first (str:split "/" system))) |
||||
|
||||
;;;; Nix generation |
||||
|
||||
(defun nix-eval (exp) |
||||
(assert (consp exp)) |
||||
(ecase (car exp) |
||||
(:string (nix-string (cadr exp))) |
||||
(:list (apply #'nix-list (rest exp))) |
||||
(:funcall (apply #'nix-funcall (rest exp))) |
||||
(:attrs (nix-attrs (cdr exp))) |
||||
(:merge (apply #'nix-merge (cdr exp))) |
||||
(:symbol (nix-symbol (cadr exp))))) |
||||
|
||||
(defun nix-string (object) |
||||
(format nil "\"~a\"" object)) |
||||
|
||||
(defun nixify-symbol (string) |
||||
(flet ((fix-special-chars (str) |
||||
(replace-regexes '("[+]$" "[+][/]" "[+]" "[.]" "[/]") |
||||
'("_plus" "_plus/" "_plus_" "_dot_" "_slash_") |
||||
str))) |
||||
(if (ppcre:scan "^[0-9]" string) |
||||
(str:concat "_" (fix-special-chars string)) |
||||
(fix-special-chars string)))) |
||||
|
||||
|
||||
(defun nix-symbol (object) |
||||
(nixify-symbol (format nil "~a" object))) |
||||
|
||||
(defun nix-list (&rest things) |
||||
(format nil "[ ~{~A~^ ~} ]" (mapcar 'nix-eval things))) |
||||
(defvar *nix-attrs-depth* 0) |
||||
|
||||
(defun nix-attrs (keyvals) |
||||
(let ((*nix-attrs-depth* (1+ *nix-attrs-depth*))) |
||||
(format |
||||
nil |
||||
(->> "{~%*depth*~{~{~A = ~A;~}~^~%*depth*~}~%*depth-1*}" |
||||
(str:replace-all "*depth*" (str:repeat *nix-attrs-depth* " ")) |
||||
(str:replace-all "*depth-1*" (str:repeat (1- *nix-attrs-depth*) " "))) |
||||
(mapcar (lambda (keyval) |
||||
(let ((key (car keyval)) |
||||
(val (cadr keyval))) |
||||
(list (nix-symbol key) |
||||
(nix-eval val)))) |
||||
keyvals)))) |
||||
|
||||
(defun nix-funcall (fun &rest args) |
||||
(format nil "(~a ~{~a~^ ~})" |
||||
(nixify-symbol fun) |
||||
(mapcar 'nix-eval args))) |
||||
|
||||
(defun nix-merge (a b) |
||||
(format nil "(~a // ~b)" |
||||
(nix-eval a) |
||||
(nix-eval b))) |
@ -0,0 +1,24 @@ |
||||
(defsystem org.lispbuilds.nix |
||||
:class :package-inferred-system |
||||
:description "Utilities for importing ASDF systems into Nix" |
||||
:depends-on ( |
||||
:alexandria |
||||
:str |
||||
:cl-ppcre |
||||
:sqlite |
||||
:dexador |
||||
:arrow-macros |
||||
:com.inuoe.jzon |
||||
:org.lispbuilds.nix/api |
||||
:org.lispbuilds.nix/repository/quicklisp |
||||
:org.lispbuilds.nix/database/sqlite |
||||
)) |
||||
|
||||
|
||||
(register-system-packages |
||||
"cl-ppcre" |
||||
'(:ppcre)) |
||||
|
||||
(register-system-packages |
||||
"dexador" |
||||
'(:dex)) |
@ -0,0 +1,199 @@ |
||||
(defpackage org.lispbuilds.nix/repository/quicklisp |
||||
(:use :cl) |
||||
(:import-from :dex) |
||||
(:import-from :alexandria :read-file-into-string :ensure-list) |
||||
(:import-from :arrow-macros :->>) |
||||
(:import-from :str) |
||||
(:import-from |
||||
:org.lispbuilds.nix/database/sqlite |
||||
:sqlite-database |
||||
:init-db |
||||
:database-url |
||||
:init-file) |
||||
(:import-from |
||||
:org.lispbuilds.nix/api |
||||
:import-lisp-packages) |
||||
(:import-from |
||||
:org.lispbuilds.nix/util |
||||
:replace-regexes) |
||||
(:export :quicklisp-repository) |
||||
(:local-nicknames |
||||
(:json :com.inuoe.jzon))) |
||||
|
||||
(in-package org.lispbuilds.nix/repository/quicklisp) |
||||
|
||||
(defclass quicklisp-repository () |
||||
((dist-url :initarg :dist-url |
||||
:reader dist-url |
||||
:initform (error "dist url required")))) |
||||
|
||||
(defun clear-line () |
||||
(write-char #\Return *error-output*) |
||||
(write-char #\Escape *error-output*) |
||||
(write-char #\[ *error-output*) |
||||
(write-char #\K *error-output*)) |
||||
|
||||
(defun status (&rest format-args) |
||||
(clear-line) |
||||
(apply #'format (list* *error-output* format-args)) |
||||
(force-output *error-output*)) |
||||
|
||||
;; TODO: This should not know about the imported.nix file. |
||||
(defun init-tarball-hashes (database) |
||||
(status "no packages.sqlite - will pre-fill tarball hashes from ~A to save time~%" |
||||
(truename "imported.nix")) |
||||
(let* ((lines (uiop:read-file-lines "imported.nix")) |
||||
(lines (remove-if-not |
||||
(lambda (line) |
||||
(let ((trimmed (str:trim-left line))) |
||||
(or (str:starts-with-p "url = " trimmed) |
||||
(str:starts-with-p "sha256 = " trimmed)))) |
||||
lines)) |
||||
(lines (mapcar |
||||
(lambda (line) |
||||
(multiple-value-bind (whole groups) |
||||
(ppcre:scan-to-strings "\"\(.*\)\"" line) |
||||
(declare (ignore whole)) |
||||
(svref groups 0))) |
||||
lines))) |
||||
(sqlite:with-open-database (db (database-url database)) |
||||
(init-db db (init-file database)) |
||||
(sqlite:with-transaction db |
||||
(loop while lines do |
||||
(sqlite:execute-non-query db |
||||
"insert or ignore into sha256(url,hash) values (?,?)" |
||||
(prog1 (first lines) (setf lines (rest lines))) |
||||
(prog1 (first lines) (setf lines (rest lines)))))) |
||||
(status "OK, imported ~A hashes into DB.~%" |
||||
(sqlite:execute-single db |
||||
"select count(*) from sha256"))))) |
||||
|
||||
(defmethod import-lisp-packages ((repository quicklisp-repository) |
||||
(database sqlite-database)) |
||||
|
||||
;; If packages.sqlite is missing, we should populate the sha256 |
||||
;; table to speed things up. |
||||
(unless (probe-file (database-url database)) |
||||
(init-tarball-hashes database)) |
||||
|
||||
(let* ((db (sqlite:connect (database-url database))) |
||||
(systems-url (str:concat (dist-url repository) "systems.txt")) |
||||
(releases-url (str:concat (dist-url repository) "releases.txt")) |
||||
(systems-lines (rest (butlast (str:split #\Newline (dex:get systems-url))))) |
||||
(releases-lines (rest (butlast (str:split #\Newline (dex:get releases-url)))))) |
||||
|
||||
(flet ((sql-query (sql &rest params) |
||||
(apply #'sqlite:execute-to-list (list* db sql params)))) |
||||
|
||||
;; Ensure database schema |
||||
(init-db db (init-file database)) |
||||
|
||||
;; Prepare temporary tables for efficient access |
||||
(sql-query "create temp table if not exists quicklisp_system |
||||
(project, asd, name unique, deps)") |
||||
|
||||
(sql-query "create temp table if not exists quicklisp_release |
||||
(project unique, url, size, md5, sha1, prefix not null, asds)") |
||||
|
||||
(sqlite:with-transaction db |
||||
(dolist (line systems-lines) |
||||
(destructuring-bind (project asd name &rest deps) |
||||
(str:words line) |
||||
(sql-query |
||||
"insert or ignore into quicklisp_system values(?,?,?,?)" |
||||
project asd name (json:stringify (coerce deps 'vector)))))) |
||||
|
||||
(sqlite:with-transaction db |
||||
(dolist (line releases-lines) |
||||
(destructuring-bind (project url size md5 sha1 prefix &rest asds) |
||||
(str:words line) |
||||
(sql-query |
||||
"insert or ignore into quicklisp_release values(?,?,?,?,?,?,?)" |
||||
project url size md5 sha1 prefix (json:stringify (coerce |
||||
asds |
||||
'vector)))))) |
||||
|
||||
(sqlite:with-transaction db |
||||
;; Should these be temp tables, that then get queried by |
||||
;; system name? This looks like it uses a lot of memory. |
||||
(let ((systems |
||||
(sql-query |
||||
"with pkg as ( |
||||
select |
||||
name, asd, url, deps, |
||||
ltrim(replace(prefix, r.project, ''), '-_') as version |
||||
from quicklisp_system s, quicklisp_release r |
||||
where s.project = r.project |
||||
) |
||||
select |
||||
name, version, asd, url, |
||||
(select json_group_array( |
||||
json_array(value, (select version from pkg where name=value)) |
||||
) |
||||
from json_each(deps)) as deps |
||||
from pkg" |
||||
))) |
||||
|
||||
;; First pass: insert system and source tarball informaton. |
||||
;; Can't insert dependency information, because this works |
||||
;; on system ids in the database and they don't exist |
||||
;; yet. Could it be better to just base dependencies on |
||||
;; names? But then ACID is lost. |
||||
(dolist (system systems) |
||||
(destructuring-bind (name version asd url deps) system |
||||
(declare (ignore deps)) |
||||
(status "importing system '~a-~a'" name version) |
||||
(let ((hash (nix-prefetch-tarball url db))) |
||||
(sql-query |
||||
"insert or ignore into system(name,version,asd) values (?,?,?)" |
||||
name version asd) |
||||
(sql-query |
||||
"insert or ignore into sha256(url,hash) values (?,?)" |
||||
url hash) |
||||
(sql-query |
||||
"insert or ignore into src values |
||||
((select id from sha256 where url=?), |
||||
(select id from system where name=? and version=?))" |
||||
url name version)))) |
||||
|
||||
;; Second pass: connect the in-database systems with |
||||
;; dependency information |
||||
(dolist (system systems) |
||||
(destructuring-bind (name version asd url deps) system |
||||
(declare (ignore asd url)) |
||||
(dolist (dep (coerce (json:parse deps) 'list)) |
||||
(destructuring-bind (dep-name dep-version) (coerce dep 'list) |
||||
(if (eql dep-version 'NULL) |
||||
(warn "Bad data in Quicklisp: ~a has no version" dep-name) |
||||
(sql-query |
||||
"insert or ignore into dep values |
||||
((select id from system where name=? and version=?), |
||||
(select id from system where name=? and version=?))" |
||||
name version |
||||
dep-name dep-version)))))))))) |
||||
|
||||
(write-char #\Newline *error-output*)) |
||||
|
||||
(defun shell-command-to-string (cmd) |
||||
;; Clearing the library path is needed to prevent a bug, where the |
||||
;; called subprocess uses a different glibc than the SBCL process |
||||
;; is. In that case, the call to execve attempts to load the |
||||
;; libraries used by SBCL from LD_LIBRARY_PATH using a different |
||||
;; glibc than they expect, which errors out. |
||||
(let ((ld-library-path (uiop:getenv "LD_LIBRARY_PATH"))) |
||||
(setf (uiop:getenv "LD_LIBRARY_PATH") "") |
||||
(unwind-protect |
||||
(uiop:run-program cmd :output '(:string :stripped t)) |
||||
(setf (uiop:getenv "LD_LIBRARY_PATH") ld-library-path)))) |
||||
|
||||
(defun nix-prefetch-tarball (url db) |
||||
(restart-case |
||||
(compute-sha256 url db) |
||||
(try-again () |
||||
:report "Try downloading again" |
||||
(nix-prefetch-tarball url db)))) |
||||
|
||||
(defun compute-sha256 (url db) |
||||
(or (sqlite:execute-single db "select hash from sha256 where url=?" url) |
||||
(let ((sha256 (shell-command-to-string (str:concat "nix-prefetch-url --unpack " url)))) |
||||
sha256))) |
@ -0,0 +1,16 @@ |
||||
(defpackage org.lispbuilds.nix/util |
||||
(:use :cl) |
||||
(:import-from :ppcre) |
||||
(:export |
||||
:replace-regexes)) |
||||
|
||||
(in-package org.lispbuilds.nix/util) |
||||
|
||||
(defun replace-regexes (from to str) |
||||
(assert (= (length from) (length to))) |
||||
(if (null from) |
||||
str |
||||
(replace-regexes |
||||
(rest from) |
||||
(rest to) |
||||
(ppcre:regex-replace-all (first from) str (first to))))) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,432 @@ |
||||
# TODO: |
||||
# - faster build by using lisp with preloaded asdf? |
||||
# - dont include java libs unless abcl? |
||||
# - dont use build-asdf-system to build lispWithPackages? |
||||
# - make the lisp packages overridable? (e.g. buildInputs glibc->musl) |
||||
# - build asdf with nix and use that instead of one shipped with impls |
||||
# (e.g. to fix build with clisp - does anyone use clisp?) |
||||
# - claspPackages ? (gotta package clasp with nix first) |
||||
# - hard one: remove unrelated sources ( of systems not being built) |
||||
# - figure out a less awkward way to patch sources |
||||
# (have to build from src directly for SLIME to work, so can't just patch sources in place) |
||||
|
||||
{ pkgs, lib, stdenv, ... }: |
||||
|
||||
|
||||
let |
||||
|
||||
inherit (lib) |
||||
length |
||||
filter |
||||
foldl |
||||
unique |
||||
id |
||||
concat |
||||
concatMap |
||||
mutuallyExclusive |
||||
findFirst |
||||
remove |
||||
setAttr |
||||
getAttr |
||||
hasAttr |
||||
attrNames |
||||
attrValues |
||||
filterAttrs |
||||
mapAttrs |
||||
splitString |
||||
concatStringsSep |
||||
concatMapStringsSep |
||||
replaceStrings |
||||
removeSuffix |
||||
hasInfix |
||||
optionalString |
||||
makeLibraryPath |
||||
makeSearchPath |
||||
; |
||||
|
||||
inherit (builtins) |
||||
head |
||||
tail |
||||
elem |
||||
split |
||||
storeDir; |
||||
|
||||
# Returns a flattened dependency tree without duplicates |
||||
# This is probably causing performance problems... |
||||
flattenedDeps = lispLibs: |
||||
let |
||||
walk = acc: node: |
||||
if length node.lispLibs == 0 |
||||
then acc |
||||
else foldl walk (acc ++ node.lispLibs) node.lispLibs; |
||||
in unique (walk [] { inherit lispLibs; }); |
||||
|
||||
# Stolen from python-packages.nix |
||||
# Actually no idea how this works |
||||
makeOverridableLispPackage = f: origArgs: |
||||
let |
||||
ff = f origArgs; |
||||
overrideWith = newArgs: origArgs // (if pkgs.lib.isFunction newArgs then newArgs origArgs else newArgs); |
||||
in |
||||
if builtins.isAttrs ff then (ff // { |
||||
overrideLispAttrs = newArgs: makeOverridableLispPackage f (overrideWith newArgs); |
||||
}) |
||||
else if builtins.isFunction ff then { |
||||
overrideLispAttrs = newArgs: makeOverridableLispPackage f (overrideWith newArgs); |
||||
__functor = self: ff; |
||||
} |
||||
else ff; |
||||
|
||||
# |
||||
# Wrapper around stdenv.mkDerivation for building ASDF systems. |
||||
# |
||||
build-asdf-system = makeOverridableLispPackage ( |
||||
{ pname, |
||||
version, |
||||
src ? null, |
||||
patches ? [], |
||||
|
||||
# Native libraries, will be appended to the library path |
||||
nativeLibs ? [], |
||||
|
||||
# Java libraries for ABCL, will be appended to the class path |
||||
javaLibs ? [], |
||||
|
||||
# Lisp dependencies |
||||
# these should be packages built with `build-asdf-system` |
||||
lispLibs ? [], |
||||
|
||||
# Lisp command to run buildScript |
||||
lisp, |
||||
|
||||
# Some libraries have multiple systems under one project, for |
||||
# example, cffi has cffi-grovel, cffi-toolchain etc. By |
||||
# default, only the `pname` system is build. |
||||
# |
||||
# .asd's not listed in `systems` are removed in |
||||
# installPhase. This prevents asdf from referring to uncompiled |
||||
# systems on run time. |
||||
# |
||||
# Also useful when the pname is differrent than the system name, |
||||
# such as when using reverse domain naming. |
||||
systems ? [ pname ], |
||||
|
||||
# The .asd files that this package provides |
||||
asds ? systems, |
||||
|
||||
# Other args to mkDerivation |
||||
... |
||||
} @ args: |
||||
|
||||
let |
||||
|
||||
# A little slow for big dependency graphs. |
||||
# How to make it faster? |
||||
# Maybe do it in the buildScript in Common Lisp or Bash, instead |
||||
# of here with Nix? |
||||
libsFlat = flattenedDeps lispLibs; |
||||
|
||||
in stdenv.mkDerivation (rec { |
||||
inherit pname version nativeLibs javaLibs lispLibs lisp systems asds; |
||||
|
||||
src = if builtins.length patches > 0 |
||||
then apply-patches args |
||||
else args.src; |
||||
|
||||
# When src is null, we are building a lispWithPackages and only |
||||
# want to make use of the dependency environment variables |
||||
# generated by build-asdf-system |
||||
dontUnpack = src == null; |
||||
|
||||
|
||||
# TODO: Do the propagation like for lisp, native and java like this: |
||||
# https://github.com/teu5us/nix-lisp-overlay/blob/e30dafafa5c1b9a5b0ccc9aaaef9d285d9f0c46b/pkgs/development/lisp-modules/setup-hook.sh |
||||
# Then remove the "echo >> nix-drvs" from buildScript |
||||
|
||||
# Tell asdf where to find system definitions of lisp dependencies. |
||||
# |
||||
# The "//" ending is important as it makes asdf recurse into |
||||
# subdirectories when searching for .asd's. This is to support |
||||
# projects where .asd's aren't in the root directory. |
||||
CL_SOURCE_REGISTRY = makeSearchPath "/" libsFlat; |
||||
|
||||
# Tell lisp where to find native dependencies |
||||
# |
||||
# Normally generated from lispLibs, but LD_LIBRARY_PATH as a |
||||
# derivation attr itself can be used as an extension point when |
||||
# the libs are not in a '/lib' subdirectory |
||||
LD_LIBRARY_PATH = |
||||
let |
||||
libs = concatMap (x: x.nativeLibs) libsFlat; |
||||
paths = filter (x: x != "") (map (x: x.LD_LIBRARY_PATH) libsFlat); |
||||
path = |
||||
makeLibraryPath libs |
||||
+ optionalString (length paths != 0) ":" |
||||
+ concatStringsSep ":" paths; |
||||
in concatStringsSep ":" (unique (splitString ":" path)); |
||||
|
||||
# Java libraries For ABCL |
||||
CLASSPATH = makeSearchPath "share/java/*" (concatMap (x: x.javaLibs) libsFlat); |
||||
|
||||
# Portable script to build the systems. |
||||
# |
||||
# `lisp` must evaluate this file then exit immediately. For |
||||
# example, SBCL's --script flag does just that. |
||||
# |
||||
# NOTE: |
||||
# Every other library worked fine with asdf:compile-system in |
||||
# buildScript. |
||||
# |
||||
# cl-syslog, for some reason, signals that CL-SYSLOG::VALID-SD-ID-P |
||||
# is undefined with compile-system, but works perfectly with |
||||
# load-system. Strange. |
||||
buildScript = pkgs.writeText "build-${pname}.lisp" '' |
||||
(require :asdf) |
||||
(dolist (s '(${concatStringsSep " " systems})) |
||||
(asdf:load-system s)) |
||||
''; |
||||
|
||||
buildPhase = optionalString (src != null) '' |
||||
# In addition to lisp dependencies, make asdf see the .asd's |
||||
# of the systems being built |
||||
# |
||||
# *Append* src since `lispLibs` can provide .asd's that are |
||||
# also in `src` but are not in `systems` (that is, the .asd's |
||||
# that will be deleted in installPhase). We don't want to |
||||
# rebuild them, but to load them from lispLibs. |
||||
# |
||||
# NOTE: It's important to read files from `src` instead of |
||||
# from pwd to get go-to-definition working with SLIME |
||||
export CL_SOURCE_REGISTRY=$CL_SOURCE_REGISTRY:${src}// |
||||
|
||||
# Similiarily for native deps |
||||
export LD_LIBRARY_PATH=${makeLibraryPath nativeLibs}:$LD_LIBRARY_PATH |
||||
export CLASSPATH=${makeSearchPath "share/java/*" javaLibs}:$CLASSPATH |
||||
|
||||
# Make asdf compile from `src` to pwd and load `lispLibs` |
||||
# from storeDir. Otherwise it could try to recompile lisp deps. |
||||
export ASDF_OUTPUT_TRANSLATIONS="${src}:$(pwd):${storeDir}:${storeDir}" |
||||
|
||||
# Make Nix track the dependencies so that graphs can be generated with |
||||
# nix-store -q --graph |
||||
echo "$lispLibs" >> nix-drvs |
||||
echo "$nativeLibs" >> nix-drvs |
||||
echo "$javaLibs" >> nix-drvs |
||||
|
||||
# Finally, compile the systems |
||||
${lisp} $buildScript |
||||
''; |
||||
|
||||
# Copy compiled files to store |
||||
# |
||||
# Make sure to include '$' in regex to prevent skipping |
||||
# stuff like 'iolib.asdf.asd' for system 'iolib.asd' |
||||
# |
||||
# Same with '/': `local-time.asd` for system `cl-postgres+local-time.asd` |
||||
installPhase = |
||||
let |
||||
mkSystemsRegex = systems: |
||||
concatMapStringsSep "\\|" (replaceStrings ["." "+"] ["[.]" "[+]"]) systems; |
||||
in |
||||
'' |
||||
mkdir -pv $out |
||||
cp -r * $out |
||||
|
||||
# Remove all .asd files except for those in `systems`. |
||||
find $out -name "*.asd" \ |
||||
| grep -v "/\(${mkSystemsRegex systems}\)\.asd$" \ |
||||
| xargs rm -fv || true |
||||
''; |
||||
|
||||
# Not sure if it's needed, but caused problems with SBCL |
||||
# save-lisp-and-die binaries in the past |
||||
dontStrip = true; |
||||
dontFixup = true; |
||||
|
||||
} // args)); |
||||
|
||||
# Need to do that because we always want to compile straight from |
||||
# `src` for go-to-definition to work in SLIME. |
||||
apply-patches = { patches, src, ... }: |
||||
stdenv.mkDerivation { |
||||
inherit patches src; |
||||
pname = "source"; |
||||
version = "patched"; |
||||
dontConfigure = true; |
||||
dontBuild = true; |
||||
dontStrip = true; |
||||
dontFixup = true; |
||||
installPhase = '' |
||||
mkdir -pv $out |
||||
cp -r * $out |
||||
''; |
||||
}; |
||||
|
||||
# Build the set of lisp packages using `lisp` |
||||
# These packages are defined manually for one reason or another: |
||||
# - The library is not in quicklisp |
||||
# - The library that is in quicklisp is broken |
||||
# - Special build procedure such as cl-unicode, asdf |
||||
# |
||||
# These Probably could be done even in ql.nix |
||||
# - Want to pin a specific commit |
||||
# - Want to apply custom patches |
||||
# |
||||
# They can use the auto-imported quicklisp packages as dependencies, |
||||
# but some of those don't work out of the box. |
||||
# |
||||
# E.g if a QL package depends on cl-unicode it won't build out of |
||||
# the box. The dependency has to be rewritten using the manually |
||||
# fixed cl-unicode. |
||||
# |
||||
# This is done by generating a 'fixed' set of Quicklisp packages by |
||||
# calling quicklispPackagesFor with the right `fixup`. |
||||
commonLispPackagesFor = lisp: |
||||
let |
||||
build-asdf-system' = body: build-asdf-system (body // { inherit lisp; }); |
||||
in import ./packages.nix { |
||||
inherit pkgs; |
||||
inherit lisp; |
||||
inherit quicklispPackagesFor; |
||||
inherit fixupFor; |
||||
build-asdf-system = build-asdf-system'; |
||||
}; |
||||
|
||||
# Build the set of packages imported from quicklisp using `lisp` |
||||
quicklispPackagesFor = { lisp, fixup ? lib.id, build ? build-asdf-system }: |
||||
let |
||||
build-asdf-system' = body: build (body // { |
||||
inherit lisp; |
||||
}); |
||||
in import ./ql.nix { |
||||
inherit pkgs; |
||||
inherit fixup; |
||||
build-asdf-system = build-asdf-system'; |
||||
}; |
||||
|
||||
# Rewrite deps of pkg to use manually defined packages |
||||
# |
||||
# The purpose of manual packages is to customize one package, but |
||||
# then it has to be propagated everywhere for it to make sense and |
||||
# have consistency in the package tree. |
||||
fixupFor = manualPackages: qlPkg: |
||||
assert (lib.isAttrs qlPkg && !lib.isDerivation qlPkg); |
||||
let |
||||
# Make it possible to reuse generated attrs without recursing into oblivion |
||||
packages = (lib.filterAttrs (n: v: n != qlPkg.pname) manualPackages); |
||||
substituteLib = pkg: |
||||
if lib.hasAttr pkg.pname packages |
||||
then packages.${pkg.pname} |
||||
else pkg; |
||||
pkg = substituteLib qlPkg; |
||||
in pkg // { lispLibs = map substituteLib pkg.lispLibs; }; |
||||
|
||||
makeAttrName = str: |
||||
removeSuffix |
||||
"_" |
||||
(replaceStrings |
||||
["+" "." "/"] |
||||
["_plus_" "_dot_" "_slash_"] |
||||
str); |
||||
|
||||
oldMakeWrapper = pkgs.runCommand "make-wrapper.sh" {} '' |
||||
substitute ${./old-make-wrapper.sh} $out \ |
||||
--replace @shell@ ${pkgs.bash}/bin/bash |
||||
''; |
||||
|
||||
# Creates a lisp wrapper with `packages` installed |
||||
# |
||||
# `packages` is a function that takes `clpkgs` - a set of lisp |
||||
# packages - as argument and returns the list of packages to be |
||||
# installed |
||||
lispWithPackagesInternal = clpkgs: packages: |
||||
# FIXME just use flattenedDeps instead |
||||
(build-asdf-system rec { |
||||
lisp = (head (lib.attrValues clpkgs)).lisp; |
||||
# See dontUnpack in build-asdf-system |
||||
src = null; |
||||
pname = baseNameOf (head (split " " lisp)); |
||||
version = "with-packages"; |
||||
lispLibs = packages clpkgs; |
||||
systems = []; |
||||
}).overrideAttrs(o: { |
||||
installPhase = '' |
||||
# The recent version of makeWrapper causes breakage. For more info see |
||||
# https://github.com/Uthar/nix-cl/issues/2 |
||||
source ${oldMakeWrapper} |
||||
|
||||
mkdir -pv $out/bin |
||||
makeWrapper \ |
||||
${head (split " " o.lisp)} \ |
||||
$out/bin/${baseNameOf (head (split " " o.lisp))} \ |
||||
--prefix CL_SOURCE_REGISTRY : "${o.CL_SOURCE_REGISTRY}" \ |
||||
--prefix ASDF_OUTPUT_TRANSLATIONS : ${concatStringsSep "::" (flattenedDeps o.lispLibs)}: \ |
||||
--prefix LD_LIBRARY_PATH : "${o.LD_LIBRARY_PATH}" \ |
||||
--prefix LD_LIBRARY_PATH : "${makeLibraryPath o.nativeLibs}" \ |
||||
--prefix CLASSPATH : "${o.CLASSPATH}" \ |
||||
--prefix CLASSPATH : "${makeSearchPath "share/java/*" o.javaLibs}" |
||||
''; |
||||
}); |
||||
|
||||
lispWithPackages = lisp: |
||||
let |
||||
packages = lispPackagesFor lisp; |
||||
in lispWithPackagesInternal packages; |
||||
|
||||
lispPackagesFor = lisp: |
||||
let |
||||
packages = commonLispPackagesFor lisp; |
||||
qlPackages = quicklispPackagesFor { |
||||
inherit lisp; |
||||
fixup = fixupFor packages; |
||||
}; |
||||
in qlPackages // packages; |
||||
|
||||
commonLispPackages = rec { |
||||
inherit |
||||
build-asdf-system |
||||
lispWithPackagesInternal |
||||
lispPackagesFor |
||||
lispWithPackages; |
||||
|
||||
# Uncomment for debugging/development |
||||
# inherit |
||||
# flattenedDeps |
||||
# concatMap |
||||
# attrNames |
||||
# getAttr |
||||
# filterAttrs |
||||
# filter |
||||
# elem |
||||
# unique |
||||
# makeAttrName |
||||
# length; |
||||
|
||||
# TODO: uncomment clasp when clasp 1.0.0 is packaged |
||||
|
||||
# There's got to be a better way than this... |
||||
# The problem was that with --load everywhere, some |
||||
# implementations didn't exit with 0 on compilation failure |
||||
# Maybe a handler-case in buildScript? |
||||
sbcl = "${pkgs.sbcl}/bin/sbcl --script"; |
||||
ecl = "${pkgs.ecl}/bin/ecl --shell"; |
||||
abcl = ''${pkgs.abcl}/bin/abcl --batch --eval "(load \"$buildScript\")"''; |
||||
ccl = ''${pkgs.ccl}/bin/ccl --batch --eval "(load \"$buildScript\")" --''; |
||||
# clasp = ''${pkgs.clasp}/bin/clasp --non-interactive --quit --load''; |
||||
|
||||
# Manually defined packages shadow the ones imported from quicklisp |
||||
|
||||
sbclPackages = lispPackagesFor sbcl; |
||||
eclPackages = lispPackagesFor ecl; |
||||
abclPackages = lispPackagesFor abcl; |
||||
cclPackages = lispPackagesFor ccl; |
||||
# claspPackages = lispPackagesFor clasp; |
||||
|
||||
sbclWithPackages = lispWithPackages sbcl; |
||||
eclWithPackages = lispWithPackages ecl; |
||||
abclWithPackages = lispWithPackages abcl; |
||||
cclWithPackages = lispWithPackages ccl; |
||||
# claspWithPackages = lispWithPackages clasp; |
||||
}; |
||||
|
||||
in commonLispPackages |
@ -0,0 +1,155 @@ |
||||
# Assert that FILE exists and is executable |
||||
# |
||||
# assertExecutable FILE |
||||
assertExecutable() { |
||||
local file="$1" |
||||
[[ -f "$file" && -x "$file" ]] || \ |
||||
die "Cannot wrap '$file' because it is not an executable file" |
||||
} |
||||
|
||||
# construct an executable file that wraps the actual executable |
||||
# makeWrapper EXECUTABLE OUT_PATH ARGS |
||||
|
||||
# ARGS: |
||||
# --argv0 NAME : set name of executed process to NAME |
||||
# (otherwise it’s called …-wrapped) |
||||
# --set VAR VAL : add VAR with value VAL to the executable’s |
||||
# environment |
||||
# --set-default VAR VAL : like --set, but only adds VAR if not already set in |
||||
# the environment |
||||
# --unset VAR : remove VAR from the environment |
||||
# --run COMMAND : run command before the executable |
||||
# --add-flags FLAGS : add FLAGS to invocation of executable |
||||
|
||||
# --prefix ENV SEP VAL : suffix/prefix ENV with VAL, separated by SEP |
||||
# --suffix |
||||
# --prefix-each ENV SEP VALS : like --prefix, but VALS is a list |
||||
# --suffix-each ENV SEP VALS : like --suffix, but VALS is a list |
||||
# --prefix-contents ENV SEP FILES : like --suffix-each, but contents of FILES |
||||
# are read first and used as VALS |
||||
# --suffix-contents |
||||
makeWrapper() { |
||||
local original="$1" |
||||
local wrapper="$2" |
||||
local params varName value command separator n fileNames |
||||
local argv0 flagsBefore flags |
||||
|
||||
assertExecutable "$original" |
||||
|
||||
mkdir -p "$(dirname "$wrapper")" |
||||
|
||||
echo "#! @shell@ -e" > "$wrapper" |
||||
|
||||
params=("$@") |
||||
for ((n = 2; n < ${#params[*]}; n += 1)); do |
||||
p="${params[$n]}" |
||||
|
||||
if [[ "$p" == "--set" ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
value="${params[$((n + 2))]}" |
||||
n=$((n + 2)) |
||||
echo "export $varName=${value@Q}" >> "$wrapper" |
||||
elif [[ "$p" == "--set-default" ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
value="${params[$((n + 2))]}" |
||||
n=$((n + 2)) |
||||
echo "export $varName=\${$varName-${value@Q}}" >> "$wrapper" |
||||
elif [[ "$p" == "--unset" ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
n=$((n + 1)) |
||||
echo "unset $varName" >> "$wrapper" |
||||
elif [[ "$p" == "--run" ]]; then |
||||
command="${params[$((n + 1))]}" |
||||
n=$((n + 1)) |
||||
echo "$command" >> "$wrapper" |
||||
elif [[ ("$p" == "--suffix") || ("$p" == "--prefix") ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
separator="${params[$((n + 2))]}" |
||||
value="${params[$((n + 3))]}" |
||||
n=$((n + 3)) |
||||
if test -n "$value"; then |
||||
if test "$p" = "--suffix"; then |
||||
echo "export $varName=\$$varName\${$varName:+${separator@Q}}${value@Q}" >> "$wrapper" |
||||
else |
||||
echo "export $varName=${value@Q}\${$varName:+${separator@Q}}\$$varName" >> "$wrapper" |
||||
fi |
||||
fi |
||||
elif [[ "$p" == "--prefix-each" ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
separator="${params[$((n + 2))]}" |
||||
values="${params[$((n + 3))]}" |
||||
n=$((n + 3)) |
||||
for value in $values; do |
||||
echo "export $varName=${value@Q}\${$varName:+${separator@Q}}\$$varName" >> "$wrapper" |
||||
done |
||||
elif [[ "$p" == "--suffix-each" ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
separator="${params[$((n + 2))]}" |
||||
values="${params[$((n + 3))]}" |
||||
n=$((n + 3)) |
||||
for value in $values; do |
||||
echo "export $varName=\$$varName\${$varName:+$separator}${value@Q}" >> "$wrapper" |
||||
done |
||||
elif [[ ("$p" == "--suffix-contents") || ("$p" == "--prefix-contents") ]]; then |
||||
varName="${params[$((n + 1))]}" |
||||
separator="${params[$((n + 2))]}" |
||||
fileNames="${params[$((n + 3))]}" |
||||
n=$((n + 3)) |
||||
for fileName in $fileNames; do |
||||
contents="$(cat "$fileName")" |
||||
if test "$p" = "--suffix-contents"; then |
||||
echo "export $varName=\$$varName\${$varName:+$separator}${contents@Q}" >> "$wrapper" |
||||
else |
||||
echo "export $varName=${contents@Q}\${$varName:+$separator}\$$varName" >> "$wrapper" |
||||
fi |
||||
done |
||||
elif [[ "$p" == "--add-flags" ]]; then |
||||
flags="${params[$((n + 1))]}" |
||||
n=$((n + 1)) |
||||
flagsBefore="$flagsBefore $flags" |
||||
elif [[ "$p" == "--argv0" ]]; then |
||||
argv0="${params[$((n + 1))]}" |
||||
n=$((n + 1)) |
||||
else |
||||
die "makeWrapper doesn't understand the arg $p" |
||||
fi |
||||
done |
||||
|
||||
echo exec ${argv0:+-a \"$argv0\"} \""$original"\" \ |
||||
"$flagsBefore" '"$@"' >> "$wrapper" |
||||
|
||||
chmod +x "$wrapper" |
||||
} |
||||
|
||||
addSuffix() { |
||||
suffix="$1" |
||||
shift |
||||
for name in "$@"; do |
||||
echo "$name$suffix" |
||||
done |
||||
} |
||||
|
||||
filterExisting() { |
||||
for fn in "$@"; do |
||||
if test -e "$fn"; then |
||||
echo "$fn" |
||||
fi |
||||
done |
||||
} |
||||
|
||||
# Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...> |
||||
wrapProgram() { |
||||
local prog="$1" |
||||
local hidden |
||||
|
||||
assertExecutable "$prog" |
||||
|
||||
hidden="$(dirname "$prog")/.$(basename "$prog")"-wrapped |
||||
while [ -e "$hidden" ]; do |
||||
hidden="${hidden}_" |
||||
done |
||||
mv "$prog" "$hidden" |
||||
# Silence warning about unexpanded $0: |
||||
# shellcheck disable=SC2016 |
||||
makeWrapper "$hidden" "$prog" --argv0 '$0' "${@:2}" |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue