From 1f9350c3e465c0fc76ad0a195088e883da014601 Mon Sep 17 00:00:00 2001 From: rczb Date: Tue, 24 Dec 2024 15:45:05 +0800 Subject: [PATCH 1/6] racket and racket-minimal: refactor - Remove redundant dependencies and patch. (fix #246902) - Unify `pname` to `racket`. - Clean code. --- .../interpreters/racket/default.nix | 340 +++++++++--------- .../racket/force-cs-variant.patch | 18 - .../interpreters/racket/manifest.json | 11 + .../interpreters/racket/minimal.nix | 25 -- .../force-remove-codesign-then-add.patch | 0 pkgs/top-level/all-packages.nix | 6 +- 6 files changed, 185 insertions(+), 215 deletions(-) delete mode 100644 pkgs/development/interpreters/racket/force-cs-variant.patch create mode 100644 pkgs/development/interpreters/racket/manifest.json delete mode 100644 pkgs/development/interpreters/racket/minimal.nix rename pkgs/development/interpreters/racket/{ => patches}/force-remove-codesign-then-add.patch (100%) diff --git a/pkgs/development/interpreters/racket/default.nix b/pkgs/development/interpreters/racket/default.nix index 4a16416374ff..a776f3e13c60 100644 --- a/pkgs/development/interpreters/racket/default.nix +++ b/pkgs/development/interpreters/racket/default.nix @@ -2,208 +2,212 @@ lib, stdenv, fetchurl, - makeFontsConf, - cacert, - cairo, - coreutils, - fontconfig, - freefont_ttf, - glib, - gmp, - gtk3, - glibcLocales, - libedit, - libffi, - libiconv, - libGL, - libGLU, - libjpeg, + + libiconvReal, + libz, + lz4, ncurses, - libpng, - libtool, - mpfr, openssl, + + isMinimal ? false, + + cairo, + fontconfig, + glib, + glibcLocales, + gtk3, + libGL, + libiodbc, + libjpeg, + libpng, + makeFontsConf, pango, - poppler, - readline, sqlite, - disableDocs ? false, - CoreFoundation, - gsettings-desktop-schemas, + unixODBC, wrapGAppsHook3, + + disableDocs ? false, }: let - - fontsConf = makeFontsConf { fontDirectories = [ freefont_ttf ]; }; - - libPath = lib.makeLibraryPath ( - [ - cairo - fontconfig - glib - gmp - gtk3 - gsettings-desktop-schemas - libedit - libjpeg - libpng - mpfr - ncurses - openssl - pango - poppler - readline - sqlite - ] - ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [ - libGL - libGLU + makeLibPaths = lib.concatMapStringsSep " " ( + lib.flip lib.pipe [ + lib.getLib + (x: ''"${x}/lib"'') ] ); + + manifest = lib.importJSON ./manifest.json; + inherit (stdenv.hostPlatform) isDarwin isStatic; + + runtimeDeps = [ openssl ]; + mainDistDeps = [ + (if isDarwin then libiodbc else unixODBC) + cairo + fontconfig + glib + gtk3 + libGL + libjpeg + libpng + pango + sqlite + ]; in -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "racket"; - version = "8.14"; # always change at once with ./minimal.nix + inherit (manifest) version; src = - (lib.makeOverridable ( - { name, hash }: - fetchurl { - url = "https://mirror.racket-lang.org/installers/${version}/${name}-src.tgz"; - inherit hash; - } - )) - { - name = "${pname}-${version}"; - hash = "sha256-qrjMDbM27S04KAPHCK1VqV/FKkQ2yRL2FvfEnUhFriw="; - }; + let + info = manifest.${if isMinimal then "minimal" else "full"}; + in + fetchurl { + url = "https://mirror.racket-lang.org/installers/${manifest.version}/${info.filename}"; + inherit (info) sha256; + }; - FONTCONFIG_FILE = fontsConf; - LD_LIBRARY_PATH = libPath; - NIX_LDFLAGS = lib.concatStringsSep " " [ - (lib.optionalString (stdenv.cc.isGNU && !stdenv.hostPlatform.isDarwin) "-lgcc_s") - ]; - - nativeBuildInputs = [ - cacert + nativeBuildInputs = lib.optionals (!isMinimal) [ wrapGAppsHook3 ]; - buildInputs = - [ - fontconfig - libffi - libtool - sqlite - gsettings-desktop-schemas - gtk3 - ncurses - ] - ++ lib.optionals stdenv.hostPlatform.isDarwin [ - libiconv - CoreFoundation - ]; + buildInputs = [ + libiconvReal + libz + lz4 + ncurses + ]; - patches = [ - # Hardcode variant detection because we wrap the Racket binary making it - # fail to detect its variant at runtime. - # See: https://github.com/NixOS/nixpkgs/issues/114993#issuecomment-812951247 - ./force-cs-variant.patch - - # 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. - ./force-remove-codesign-then-add.patch + 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 = - '' - unset AR - for f in src/lt/configure src/cs/c/configure src/bc/src/string.c; do - substituteInPlace "$f" \ - --replace /usr/bin/uname ${coreutils}/bin/uname \ - --replace /bin/cp ${coreutils}/bin/cp \ - --replace /bin/ln ${coreutils}/bin/ln \ - --replace /bin/rm ${coreutils}/bin/rm \ - --replace /bin/true ${coreutils}/bin/true - done - - # 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. + /* + 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 'ARFLAGS="-o"' 'AR=ar; ARFLAGS="rc"' - + --replace-fail 'ARFLAGS="-o"' 'AR=ar; ARFLAGS="rc"' + '' + + '' mkdir src/build cd src/build - - '' - + lib.optionalString stdenv.hostPlatform.isLinux '' - gappsWrapperArgs+=("--prefix" "LD_LIBRARY_PATH" ":" ${libPath}) - gappsWrapperArgs+=("--set" "LOCALE_ARCHIVE" "${glibcLocales}/lib/locale/locale-archive") - '' - + lib.optionalString stdenv.hostPlatform.isDarwin '' - gappsWrapperArgs+=("--prefix" "DYLD_LIBRARY_PATH" ":" ${libPath}) ''; - preBuild = lib.optionalString stdenv.hostPlatform.isDarwin '' - # Cannot set DYLD_LIBRARY_PATH as an attr of this drv, becasue dynamic - # linker environment variables like this are purged. - # See: https://apple.stackexchange.com/a/212954/167199 - - # Make builders feed it to dlopen(...). Do not expose all of $libPath to - # DYLD_LIBRARY_PATH as the order of looking up symbols like - # `__cg_jpeg_resync_to_restart` will be messed up. Our libJPEG.dyllib - # expects it from our libTIFF.dylib, but instead it could not be found from - # the system `libTIFF.dylib`. DYLD_FALLBACK_LIBRARY_PATH has its own problem - # , too. - export DYLD_FALLBACK_LIBRARY_PATH="${libPath}" - ''; - - shared = if stdenv.hostPlatform.isDarwin then "dylib" else "shared"; - configureFlags = - [ - "--enable-${shared}" - "--enable-lt=${libtool}/bin/libtool" - ] - ++ lib.optionals disableDocs [ "--disable-docs" ] - ++ lib.optionals stdenv.hostPlatform.isDarwin [ - "--disable-strip" - "--enable-xonx" - ]; - configureScript = "../configure"; - enableParallelBuilding = false; + configureFlags = + [ + "--enable-check" + "--enable-csonly" + "--enable-liblz4" + "--enable-libz" + ] + ++ lib.optional disableDocs "--disable-docs" + ++ lib.optionals (!isStatic) [ + # 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" + ]; - dontStrip = stdenv.hostPlatform.isDarwin; + preBuild = + let + libPaths = makeLibPaths mainDistDeps; + libPathsVar = if isDarwin then "DYLD_FALLBACK_LIBRARY_PATH" else "LD_LIBRARY_PATH"; + in + lib.optionalString (!isMinimal) ( + /* + Makes FFIs available for setting up `main-distribution` and its + dependencies, which is integrated into the build process of Racket + */ + '' + for lib_path in ${libPaths}; do + addToSearchPath ${libPathsVar} $lib_path + done + '' + # Fixes Fontconfig errors + + '' + export FONTCONFIG_FILE=${makeFontsConf { fontDirectories = [ ]; }} + export XDG_CACHE_HOME=$(mktemp -d) + '' + ); - meta = with lib; { - 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. + dontStrip = isDarwin; + + preFixup = lib.optionalString (!isMinimal && !isDarwin) '' + gappsWrapperArgs+=("--set" "LOCALE_ARCHIVE" "${glibcLocales}/lib/locale/locale-archive") + ''; + + postFixup = + let + libPaths = makeLibPaths (runtimeDeps ++ lib.optionals (!isMinimal) mainDistDeps); + in + '' + $out/bin/racket -f - < 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 ]; - maintainers = [ ]; - platforms = [ - "x86_64-darwin" - "x86_64-linux" - "aarch64-linux" - "aarch64-darwin" - ]; + maintainers = with lib.maintainers; [ rc-zb ]; + mainProgram = "racket"; + platforms = lib.platforms.${if isMinimal then "all" else "unix"}; }; -} +}) diff --git a/pkgs/development/interpreters/racket/force-cs-variant.patch b/pkgs/development/interpreters/racket/force-cs-variant.patch deleted file mode 100644 index 6acbe5dc95d3..000000000000 --- a/pkgs/development/interpreters/racket/force-cs-variant.patch +++ /dev/null @@ -1,18 +0,0 @@ -Hardcode Racket variant to CS - -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 - ---- 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/pkgs/development/interpreters/racket/manifest.json b/pkgs/development/interpreters/racket/manifest.json new file mode 100644 index 000000000000..2870cfa3cb05 --- /dev/null +++ b/pkgs/development/interpreters/racket/manifest.json @@ -0,0 +1,11 @@ +{ + "version": "8.14", + "full": { + "filename": "racket-8.14-src.tgz", + "sha256": "aab8cc0db336ed2d382803c708ad55a95fc52a4436c912f616f7c49d4845ae2c" + }, + "minimal": { + "filename": "racket-minimal-8.14-src.tgz", + "sha256": "fc1867c88c38410d9a30a5bc143265b1a9525b7a532ea3fbe025c9d79b5de6ca" + } +} diff --git a/pkgs/development/interpreters/racket/minimal.nix b/pkgs/development/interpreters/racket/minimal.nix deleted file mode 100644 index 3314f6d02a64..000000000000 --- a/pkgs/development/interpreters/racket/minimal.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ racket }: - -racket.overrideAttrs (oldAttrs: rec { - pname = "racket-minimal"; - version = oldAttrs.version; - src = oldAttrs.src.override { - name = "${pname}-${version}"; - hash = "sha256-/BhnyIw4QQ2aMKW8FDJlsalSW3pTLqP74CXJ15td5so="; - }; - - meta = oldAttrs.meta // { - description = "Racket without bundled packages, such as Dr. Racket"; - longDescription = '' - The essential package racket-libs is included, - as well as libraries that live in collections. In particular, raco - and the pkg library are still bundled. - ''; - platforms = [ - "x86_64-linux" - "aarch64-linux" - "x86_64-darwin" - "aarch64-darwin" - ]; - }; -}) diff --git a/pkgs/development/interpreters/racket/force-remove-codesign-then-add.patch b/pkgs/development/interpreters/racket/patches/force-remove-codesign-then-add.patch similarity index 100% rename from pkgs/development/interpreters/racket/force-remove-codesign-then-add.patch rename to pkgs/development/interpreters/racket/patches/force-remove-codesign-then-add.patch diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index b2adaaccdbd2..c82301b0b360 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7405,10 +7405,8 @@ with pkgs; wireplumber = callPackage ../development/libraries/pipewire/wireplumber.nix { }; - racket = callPackage ../development/interpreters/racket { - inherit (darwin.apple_sdk.frameworks) CoreFoundation; - }; - racket-minimal = callPackage ../development/interpreters/racket/minimal.nix { }; + racket = callPackage ../development/interpreters/racket { }; + racket-minimal = racket.override { isMinimal = true; }; rakudo = callPackage ../development/interpreters/rakudo { }; moarvm = darwin.apple_sdk_11_0.callPackage ../development/interpreters/rakudo/moarvm.nix { From 331314645636753a468fad2a108193c416ae8458 Mon Sep 17 00:00:00 2001 From: rczb Date: Tue, 24 Dec 2024 15:47:37 +0800 Subject: [PATCH 2/6] racket: add writeScript[Bin] --- .../interpreters/racket/default.nix | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkgs/development/interpreters/racket/default.nix b/pkgs/development/interpreters/racket/default.nix index a776f3e13c60..0b6d722e8c8d 100644 --- a/pkgs/development/interpreters/racket/default.nix +++ b/pkgs/development/interpreters/racket/default.nix @@ -27,6 +27,8 @@ wrapGAppsHook3, disableDocs ? false, + + writers, }: let @@ -175,6 +177,24 @@ stdenv.mkDerivation (finalAttrs: { EOF ''; + passthru = { + # Functionalities # + 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}"; + }; + meta = { description = "Programmable programming language" + lib.optionalString isMinimal " (minimal distribution)"; From e53c03c0e155743b07b05da45204c439c2ccd861 Mon Sep 17 00:00:00 2001 From: rczb Date: Tue, 24 Dec 2024 15:54:47 +0800 Subject: [PATCH 3/6] racket: add tests --- .../interpreters/racket/default.nix | 18 +++++++++++++ .../racket/tests/draw-crossing.nix | 18 +++++++++++++ .../racket/tests/get-version-and-variant.nix | 27 +++++++++++++++++++ .../racket/tests/load-openssl.nix | 15 +++++++++++ .../racket/tests/nix-write-script.nix | 26 ++++++++++++++++++ .../racket/tests/write-greeting.nix | 23 ++++++++++++++++ 6 files changed, 127 insertions(+) create mode 100644 pkgs/development/interpreters/racket/tests/draw-crossing.nix create mode 100644 pkgs/development/interpreters/racket/tests/get-version-and-variant.nix create mode 100644 pkgs/development/interpreters/racket/tests/load-openssl.nix create mode 100644 pkgs/development/interpreters/racket/tests/nix-write-script.nix create mode 100644 pkgs/development/interpreters/racket/tests/write-greeting.nix diff --git a/pkgs/development/interpreters/racket/default.nix b/pkgs/development/interpreters/racket/default.nix index 0b6d722e8c8d..b6ee981c0077 100644 --- a/pkgs/development/interpreters/racket/default.nix +++ b/pkgs/development/interpreters/racket/default.nix @@ -28,6 +28,7 @@ disableDocs ? false, + callPackage, writers, }: @@ -193,6 +194,23 @@ stdenv.mkDerivation (finalAttrs: { } ) 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; + } + // lib.optionalAttrs (!isMinimal) { + ## `main-distribution` ## + draw-crossing = ./tests/draw-crossing.nix; + } + ); }; meta = { diff --git a/pkgs/development/interpreters/racket/tests/draw-crossing.nix b/pkgs/development/interpreters/racket/tests/draw-crossing.nix new file mode 100644 index 000000000000..a4f0fabfe685 --- /dev/null +++ b/pkgs/development/interpreters/racket/tests/draw-crossing.nix @@ -0,0 +1,18 @@ +{ runCommandLocal, racket }: + +runCommandLocal "racket-test-draw-crossing" + { + nativeBuildInputs = [ racket ]; + } + '' + racket -f - < Date: Wed, 25 Dec 2024 16:50:56 +0800 Subject: [PATCH 4/6] racket: add updateScript --- .../interpreters/racket/default.nix | 5 ++ .../development/interpreters/racket/update.py | 73 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100755 pkgs/development/interpreters/racket/update.py diff --git a/pkgs/development/interpreters/racket/default.nix b/pkgs/development/interpreters/racket/default.nix index b6ee981c0077..1a096dd8b589 100644 --- a/pkgs/development/interpreters/racket/default.nix +++ b/pkgs/development/interpreters/racket/default.nix @@ -180,6 +180,11 @@ stdenv.mkDerivation (finalAttrs: { passthru = { # Functionalities # + updateScript = { + command = ./update.py; + attrPath = "racket"; + supportedFeatures = [ "commit" ]; + }; writeScript = nameOrPath: { diff --git a/pkgs/development/interpreters/racket/update.py b/pkgs/development/interpreters/racket/update.py new file mode 100755 index 000000000000..284c77bce1d6 --- /dev/null +++ b/pkgs/development/interpreters/racket/update.py @@ -0,0 +1,73 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 --packages 'python3.withPackages (ps: with ps; [ requests beautifulsoup4 ])' +import os +import re +import json +import requests +from bs4 import BeautifulSoup + +SITE = "https://download.racket-lang.org" +MANIFEST_FILENAME = "manifest.json" + +def find_info(table, group_name, subgroup_name): + group = table.find( + string=re.compile("^{}\\s*".format(group_name)) + ).find_parent("tr", class_="group") + subgroup = group.find_next( + string=re.compile("^{}\\s*".format(subgroup_name)) + ).find_parent(class_="subgroup") + link = subgroup.find_next( + "a", + class_="installer", + string="Source" + ) + filename = link["href"].split("/")[1] + sha256 = link.find_next(class_="checksum").string + + return { + "filename": filename, + "sha256": sha256, + } + +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +prev_version = os.environ["UPDATE_NIX_OLD_VERSION"] + +homepage = BeautifulSoup(requests.get(SITE).text, "html.parser") + +version = homepage.find( + "h3", + string=re.compile("^Version \\d+\\.\\d+") +).string.split()[1] +if version == prev_version: + raise Exception("no newer version available") + +down_page_path = homepage.find( + "a", + string="More Installers and Checksums" +)["href"] +down_page = BeautifulSoup(requests.get(SITE + "/" + down_page_path).text, "html.parser") +down_table = down_page.find(class_="download-table") + +full = find_info(down_table, "Racket", "Unix") +minimal = find_info(down_table, "Minimal Racket", "All Platforms") + +with open(MANIFEST_FILENAME, "w", encoding="utf-8") as f: + json.dump({ + "version": version, + "full": full, + "minimal": minimal, + }, f, indent=2, ensure_ascii=False) + f.write("\n") + +print(json.dumps( + [ + { + "attrPath": os.environ["UPDATE_NIX_ATTR_PATH"], + "oldVersion": prev_version, + "newVersion": version, + "files": [ os.path.abspath(MANIFEST_FILENAME) ], + }, + ], + indent=2, ensure_ascii=False +)) From 0babbe77c4a8271c4af59de84fee5966c518d748 Mon Sep 17 00:00:00 2001 From: rczb Date: Mon, 6 Jan 2025 09:38:28 +0000 Subject: [PATCH 5/6] racket: 8.14 -> 8.15 Release note: https://blog.racket-lang.org/2024/11/racket-v8-15.html Close #360765. --- pkgs/development/interpreters/racket/manifest.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/development/interpreters/racket/manifest.json b/pkgs/development/interpreters/racket/manifest.json index 2870cfa3cb05..adb19437139a 100644 --- a/pkgs/development/interpreters/racket/manifest.json +++ b/pkgs/development/interpreters/racket/manifest.json @@ -1,11 +1,11 @@ { - "version": "8.14", + "version": "8.15", "full": { - "filename": "racket-8.14-src.tgz", - "sha256": "aab8cc0db336ed2d382803c708ad55a95fc52a4436c912f616f7c49d4845ae2c" + "filename": "racket-8.15-src.tgz", + "sha256": "602b848459daf1b2222a46a9094e85ae2d28e480067219957fa46af8400e1233" }, "minimal": { - "filename": "racket-minimal-8.14-src.tgz", - "sha256": "fc1867c88c38410d9a30a5bc143265b1a9525b7a532ea3fbe025c9d79b5de6ca" + "filename": "racket-minimal-8.15-src.tgz", + "sha256": "1ac132c56bc52312049fa4f0849237f66713e8e0a7ab6c4780504633ee8f1dc3" } } From 1e81dc5584bc9c02c13a5ff56ba9bafd58a5da09 Mon Sep 17 00:00:00 2001 From: rczb Date: Mon, 6 Jan 2025 20:53:14 +0800 Subject: [PATCH 6/6] racket: mark Darwin as badPlatforms --- pkgs/development/interpreters/racket/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/development/interpreters/racket/default.nix b/pkgs/development/interpreters/racket/default.nix index 1a096dd8b589..b5c40f363e3f 100644 --- a/pkgs/development/interpreters/racket/default.nix +++ b/pkgs/development/interpreters/racket/default.nix @@ -252,5 +252,6 @@ stdenv.mkDerivation (finalAttrs: { maintainers = with lib.maintainers; [ rc-zb ]; mainProgram = "racket"; platforms = lib.platforms.${if isMinimal then "all" else "unix"}; + badPlatforms = lib.platforms.darwin; }; })