commit 843f6f1b466ddc390ace09d394cd78e346672235 Author: xenia Date: Fri Sep 26 21:17:32 2025 -0400 init racket at nixpkgs/f8a7597 f8a7597f5d80c116d775e86175f5b7592be9b441 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c5f3f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/result +/result-* diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..b3819c2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,60 @@ +{ + "nodes": { + "dragnpkgs": { + "inputs": { + "lix-module": "lix-module", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1758120987, + "narHash": "sha256-Rp8UFvIUt8W3AfkdF0hucCUv1fmHhLNbYMXcR9b82so=", + "ref": "nixos-25.05", + "rev": "debca5464a660af2f5b7a720c1364b693e068e03", + "revCount": 168, + "type": "git", + "url": "https://git.lain.faith/haskal/dragnpkgs.git" + }, + "original": { + "id": "dragnpkgs", + "type": "indirect" + } + }, + "lix-module": { + "flake": false, + "locked": { + "lastModified": 1756125859, + "narHash": "sha256-6a+PWILmqHCs9B5eIBLg6HSZ8jYweZpgOWO8FlyVwYI=", + "rev": "d3292125035b04df00d01549a26e948631fabe1e", + "type": "tarball", + "url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/d3292125035b04df00d01549a26e948631fabe1e.tar.gz?rev=d3292125035b04df00d01549a26e948631fabe1e" + }, + "original": { + "type": "tarball", + "url": "https://git.lix.systems/lix-project/nixos-module/archive/2.93.3-2.tar.gz" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1757941119, + "narHash": "sha256-TssJZFzMRYdWgpHySzKv4YQg6DUv5SDENiWbVgNTo0M=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7ff837017c3b82bd3671932599a119d7bc672ff0", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "dragnpkgs": "dragnpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..b4bb50b --- /dev/null +++ b/flake.nix @@ -0,0 +1,7 @@ +{ + description = "A very basic flake"; + + outputs = { self, dragnpkgs } @ inputs: dragnpkgs.lib.mkFlake { + packages.racket = ./racket/package.nix; + }; +} diff --git a/racket/configure-installation.rkt b/racket/configure-installation.rkt new file mode 100644 index 0000000..ffc72b1 --- /dev/null +++ b/racket/configure-installation.rkt @@ -0,0 +1,27 @@ +#lang racket/base +(require + racket/function + racket/list + racket/pretty + racket/string + setup/dirs + ) + +(define config-file (build-path (find-config-dir) "config.rktd")) + +(define lib-paths + ((compose remove-duplicates + (curry map (curryr string-trim "-L" #:right? #f)) + (curry filter (curryr string-prefix? "-L")) + string-split) + (getenv "NIX_LDFLAGS"))) + +(define config + (let* ([prev-config (read-installation-configuration-table)] + [prev-lib-search-dirs (hash-ref prev-config 'lib-search-dirs '(#f))] + [lib-search-dirs (remove-duplicates (append lib-paths prev-lib-search-dirs))]) + (hash-set prev-config 'lib-search-dirs lib-search-dirs))) + +(call-with-output-file config-file + #:exists 'replace + (curry pretty-write config)) diff --git a/racket/manifest.json b/racket/manifest.json new file mode 100644 index 0000000..3944775 --- /dev/null +++ b/racket/manifest.json @@ -0,0 +1,11 @@ +{ + "version": "8.18", + "full": { + "filename": "racket-8.18-src.tgz", + "sha256": "65477c71ec1a978a6ee4db582b9b47b1a488029d7a42e358906de154a6e5905c" + }, + "minimal": { + "filename": "racket-minimal-8.18-src.tgz", + "sha256": "24b9cf8365254b43bac308192c782edfbd86363df1322c4e063b797ed0f7db66" + } +} diff --git a/racket/minimal.nix b/racket/minimal.nix new file mode 100644 index 0000000..17c4dcf --- /dev/null +++ b/racket/minimal.nix @@ -0,0 +1,175 @@ +{ + lib, + stdenv, + fetchurl, + + libiconvReal, + libz, + lz4, + ncurses, + openssl, + sqlite, + + disableDocs ? false, + + callPackage, + writers, +}: + +let + manifest = lib.importJSON ./manifest.json; + + inherit (stdenv.hostPlatform) isDarwin; +in + +stdenv.mkDerivation (finalAttrs: { + pname = "racket"; + inherit (manifest) version; + + src = fetchurl { + url = "https://mirror.racket-lang.org/installers/${manifest.version}/${manifest.minimal.filename}"; + inherit (manifest.minimal) sha256; + }; + + buildInputs = [ + libiconvReal + libz + lz4 + ncurses + openssl + sqlite.out + ]; + + patches = lib.optionals isDarwin [ + /* + The entry point binary $out/bin/racket is codesigned at least once. The + following error is triggered as a result. + (error 'add-ad-hoc-signature "file already has a signature") + We always remove the existing signature then call add-ad-hoc-signature to + circumvent this error. + */ + ./patches/force-remove-codesign-then-add.patch + ]; + + preConfigure = + /* + The configure script forces using `libtool -o` as AR on Darwin. But, the + `-o` option is only available from Apple libtool. GNU ar works here. + */ + lib.optionalString isDarwin '' + substituteInPlace src/ChezScheme/zlib/configure \ + --replace-fail 'ARFLAGS="-o"' 'AR=ar; ARFLAGS="rc"' + '' + + '' + mkdir src/build + cd src/build + ''; + + configureScript = "../configure"; + + configureFlags = [ + # > docs failure: ftype-ref: ftype mismatch for # + # "--enable-check" + "--enable-csonly" + "--enable-liblz4" + "--enable-libz" + ] + ++ lib.optional disableDocs "--disable-docs" + ++ lib.optionals (!(finalAttrs.dontDisableStatic or false)) [ + # instead of `--disable-static` that `stdenv` assumes + "--disable-libs" + # "not currently supported" in `configure --help-cs` but still emphasized in README + "--enable-shared" + ] + ++ lib.optionals isDarwin [ + "--disable-strip" + # "use Unix style (e.g., use Gtk) for Mac OS", which eliminates many problems + "--enable-xonx" + ]; + + # The upstream script builds static libraries by default. + dontAddStaticConfigureFlags = true; + + dontStrip = isDarwin; + + postFixup = + let + configureInstallation = builtins.path { + name = "configure-installation.rkt"; + path = ./configure-installation.rkt; + }; + in + '' + $out/bin/racket -U -u ${configureInstallation} + ''; + + passthru = { + # Functionalities # + updateScript = { + command = ./update.py; + attrPath = "racket"; + supportedFeatures = [ "commit" ]; + }; + writeScript = + nameOrPath: + { + libraries ? [ ], + ... + }@config: + assert lib.assertMsg (libraries == [ ]) "library integration for Racket has not been implemented"; + writers.makeScriptWriter ( + builtins.removeAttrs config [ "libraries" ] + // { + interpreter = "${lib.getExe finalAttrs.finalPackage}"; + } + ) nameOrPath; + writeScriptBin = name: finalAttrs.passthru.writeScript "/bin/${name}"; + + # Tests # + tests = builtins.mapAttrs (name: path: callPackage path { racket = finalAttrs.finalPackage; }) { + ## Basic ## + write-greeting = ./tests/write-greeting.nix; + get-version-and-variant = ./tests/get-version-and-variant.nix; + load-openssl = ./tests/load-openssl.nix; + + ## Nixpkgs supports ## + nix-write-script = ./tests/nix-write-script.nix; + }; + }; + + meta = { + description = "Programmable programming language (minimal distribution)"; + longDescription = '' + Racket is a full-spectrum programming language. It goes beyond + Lisp and Scheme with dialects that support objects, types, + laziness, and more. Racket enables programmers to link + components written in different dialects, and it empowers + programmers to create new, project-specific dialects. Racket's + libraries support applications from web servers and databases to + GUIs and charts. + + This minimal distribution includes just enough of Racket that you can + use `raco pkg` to install more. + ''; + homepage = "https://racket-lang.org/"; + changelog = "https://github.com/racket/racket/releases/tag/v${finalAttrs.version}"; + /* + > Racket is distributed under the MIT license and the Apache version 2.0 + > license, at your option. + + > The Racket runtime system embeds Chez Scheme, which is distributed + > under the Apache version 2.0 license. + */ + license = with lib.licenses; [ + asl20 + mit + ]; + sourceProvenance = with lib.sourceTypes; [ + fromSource + binaryBytecode + ]; + maintainers = with lib.maintainers; [ rc-zb ]; + mainProgram = "racket"; + platforms = lib.platforms.all; + }; +}) diff --git a/racket/package.nix b/racket/package.nix new file mode 100644 index 0000000..82be2c3 --- /dev/null +++ b/racket/package.nix @@ -0,0 +1,123 @@ +{ + lib, + stdenv, + fetchurl, + racket-minimal, + + cairo, + fontconfig, + glib, + glibcLocales, + gtk3, + libGL, + libiodbc, + libjpeg, + libpng, + makeFontsConf, + pango, + unixODBC, + wrapGAppsHook3, + + disableDocs ? false, + + callPackage, +}: + +let + minimal = racket-minimal.override { inherit disableDocs; }; + + manifest = lib.importJSON ./manifest.json; + inherit (stdenv.hostPlatform) isDarwin; +in + +minimal.overrideAttrs ( + finalAttrs: prevAttrs: { + src = fetchurl { + url = "https://mirror.racket-lang.org/installers/${manifest.version}/${manifest.full.filename}"; + inherit (manifest.full) sha256; + }; + + buildInputs = prevAttrs.buildInputs ++ [ + (if isDarwin then libiodbc else unixODBC) + cairo + fontconfig.lib + glib + gtk3 + libGL + libjpeg + libpng + pango + ]; + + nativeBuildInputs = [ + wrapGAppsHook3 + ]; + + patches = prevAttrs.patches or [ ] ++ [ + /* + Hardcode variant detection because nixpkgs wraps the Racket binary making it + fail to detect its variant at runtime. + https://github.com/NixOS/nixpkgs/issues/114993#issuecomment-812951247 + */ + ./patches/force-cs-variant.patch + ]; + + preBuild = + let + libPathsVar = if isDarwin then "DYLD_FALLBACK_LIBRARY_PATH" else "LD_LIBRARY_PATH"; + in + /* + Makes FFIs available for setting up `main-distribution` and its + dependencies, which is integrated into the build process of Racket + */ + '' + for lib_path in $( \ + echo "$NIX_LDFLAGS" \ + | tr ' ' '\n' \ + | grep '^-L' \ + | sed 's/^-L//' \ + | awk '!seen[$0]++' \ + ); do + addToSearchPath ${libPathsVar} $lib_path + done + '' + # Fixes Fontconfig errors + + '' + export FONTCONFIG_FILE=${makeFontsConf { fontDirectories = [ ]; }} + export XDG_CACHE_HOME=$(mktemp -d) + ''; + + preFixup = lib.optionalString (!isDarwin) '' + gappsWrapperArgs+=("--set" "LOCALE_ARCHIVE" "${glibcLocales}/lib/locale/locale-archive") + ''; + + passthru = + let + notUpdated = x: !builtins.isAttrs x || lib.isDerivation x; + stopPred = + _: lhs: rhs: + notUpdated lhs || notUpdated rhs; + in + lib.recursiveUpdateUntil stopPred prevAttrs.passthru { + tests = builtins.mapAttrs (name: path: callPackage path { racket = finalAttrs.finalPackage; }) { + ## `main-distribution` ## + draw-crossing = ./tests/draw-crossing.nix; + }; + }; + + meta = prevAttrs.meta // { + description = "Programmable programming language"; + longDescription = '' + Racket is a full-spectrum programming language. It goes beyond + Lisp and Scheme with dialects that support objects, types, + laziness, and more. Racket enables programmers to link + components written in different dialects, and it empowers + programmers to create new, project-specific dialects. Racket's + libraries support applications from web servers and databases to + GUIs and charts. + ''; + platforms = lib.platforms.unix; + badPlatforms = lib.platforms.darwin; + }; + } +) diff --git a/racket/patches/force-cs-variant.patch b/racket/patches/force-cs-variant.patch new file mode 100644 index 0000000..52bb537 --- /dev/null +++ b/racket/patches/force-cs-variant.patch @@ -0,0 +1,12 @@ +--- old/collects/setup/variant.rkt ++++ new/collects/setup/variant.rkt +@@ -7,7 +7,8 @@ + (provide variant-suffix + script-variant?) + +-(define plain-variant ++(define plain-variant 'cs) ++#;(define plain-variant + (delay/sync + (cond + [(cross-installation?) diff --git a/racket/patches/force-remove-codesign-then-add.patch b/racket/patches/force-remove-codesign-then-add.patch new file mode 100644 index 0000000..98e2cb1 --- /dev/null +++ b/racket/patches/force-remove-codesign-then-add.patch @@ -0,0 +1,10 @@ +--- old/src/mac/codesign.rkt ++++ new/src/mac/codesign.rkt +@@ -18,6 +18,6 @@ + file)) + + (void +- (if remove? ++ (begin + (remove-signature file) + (add-ad-hoc-signature file))) diff --git a/racket/tests/draw-crossing.nix b/racket/tests/draw-crossing.nix new file mode 100644 index 0000000..a4f0fab --- /dev/null +++ b/racket/tests/draw-crossing.nix @@ -0,0 +1,18 @@ +{ runCommandLocal, racket }: + +runCommandLocal "racket-test-draw-crossing" + { + nativeBuildInputs = [ racket ]; + } + '' + racket -f - <