diff mbox series

[bug#53878,v2,15/15] gnu: racket: Update to 8.4.

Message ID 20220217205048.967383-16-philip@philipmcgrath.com
State Accepted
Headers show
Series Update Racket to 8.4. Adjust Chez Scheme packages. | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue

Commit Message

Philip McGrath Feb. 17, 2022, 8:50 p.m. UTC
* gnu/packages/patches/racket-gui-tethered-launcher-backport.patch: New
file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/chez-and-racket-bootstrap.scm (racket-vm-for-system): New
procedure.
* gnu/packages/racket.scm (racket-minimal, racket): Update to 8.4.
Rewrite to use 'racket-vm-for-system', label-less inputs, G-expressions,
and Git origins for main-distribution packages.
---
 gnu/local.mk                                  |    3 +-
 gnu/packages/chez-and-racket-bootstrap.scm    |   11 +-
 ...acket-gui-tethered-launcher-backport.patch |   26 +
 gnu/packages/racket.scm                       | 1550 +++++++++++------
 4 files changed, 1064 insertions(+), 526 deletions(-)
 create mode 100644 gnu/packages/patches/racket-gui-tethered-launcher-backport.patch

Comments

Liliana Marie Prikler Feb. 18, 2022, 7:38 a.m. UTC | #1
Hi,

Am Donnerstag, dem 17.02.2022 um 15:50 -0500 schrieb Philip McGrath:
> -;; Commentary:
> -;;
> -;; Here's how bootstrapping minimal Racket works:
> -;;
> -;;   - Racket BC [CGC] can be built with only a C compiler (except
> for
> -;;     one caveat discussed below).
> -;;   - Racket BC [3M] needs an existing Racket to run "xform",
> -;;     which transforms its own C source code to add additional
> annotations
> -;;     for the precise garbage collector.
> -;;   - Racket CS needs (bootfiles for) Racket's fork of Chez Scheme.
> -;;     It also needs an existing Racket to compile Racket-
> implemented
> -;;     parts of the runtime system to R6RS libraries.
> -;;   - Chez Scheme also needs bootfiles for itself, but Racket can
> simulate
> -;;     enough of Chez Scheme to load Racket's fork of the Chez
> Scheme compiler
> -;;     purely from source into Racket and apply the compiler to
> itself,
> -;;     producing the needed bootfiles (albeit very slowly).
> -;;     Any variant of Racket since version 7.1 can run the
> simulation.
> -;;
> -;; So, we build CGC to build 3M to build bootfiles and CS.
> -;;
> -;; One remaining bootstrapping limitation is that Racket's reader,
> module
> -;; system, and macro expander are implemented in Racket. For Racket
> CS,
> -;; they are compiled to R6RS libraries as discussed above. This note
> from the
> -;; README file applies to all such subsystems:
> -;;
> -;;     The Racket version must be practically the same as the
> current Racket
> -;;     verson, although it can be the Racket BC implementation
> (instead of
> -;;     the Racket CS implementation).
> -;;
> -;;     Unlike Chez Scheme boot files, the files generated in
> "schemified"
> -;;     are human-readable and -editable Scheme code. That provides a
> way
> -;;     out of bootstrapping black holes, even without BC.
> -;;
> -;; However, other Racket subsystems implemented in Racket for Racket
> CS
> -;; use older C implementations for Racket BC, whereas the reader,
> expander,
> -;; and module system were completely replaced with the Racket
> implementation
> -;; as of Racket 7.0.
> -;;
> -;; For Racket BC, the compiled "linklet" s-expressions (primitive
> modules)
> -;; are embeded in C as a static string constant. Eventually, they
> are further
> -;; compiled by the C-implemented Racket BC bytecode and JIT
> compilers.
> -;; (On platforms where Racket BC's JIT is not supported, yet another
> compiler
> -;; instead compiles the linklets to C code, but this is not a
> bootstrapping
> -;; issue.)
I think it'd be clearer if this commentary was moved along with the
bootstrapping code.  Is there a reason why we can't use (racket-vm-for-
system) before updating Racket to 8.4?  This looks like another of
those "two things at once" patches.
 
>  (define-public racket-minimal
>    (package
>      (name "racket-minimal")
> -    (version "8.3")            ; note: remember to also update
> racket!
> -    (source
> -     (origin
> -       (method git-fetch)
> -       (uri (git-reference
> -             (url "https://github.com/racket/racket")
> -             (commit (string-append "v" version))))
> -       (sha256
> -        "1i1jnv1wb0kanfg47hniafx2vhwjc33qqx66lq7wkf5hbmgsyws3")
> -       (file-name (git-file-name name version))
> -       (patches (search-patches "racket-minimal-sh-via-
> rktio.patch"))
> -       (modules '((guix build utils)))
> -       (snippet
> -        (with-imported-modules '((guix build utils))
> -          #~(begin
> -              ;; Unbundle Chez submodules.
> -              (with-directory-excursion "racket/src/ChezScheme"
> -                ;; Remove bundled libraries (copied from 'chez-
> scheme').
> -                (for-each delete-file-recursively
> -                          '("stex"
> -                            "nanopass"
> -                            "lz4"
> -                            "zlib")))
> -              ;; Unbundle libffi.
> -              (delete-file-recursively
> "racket/src/bc/foreign/libffi"))))))
> -    (inputs
> -     `(;; common to all racket-minimal variants:
> -       ("openssl" ,openssl)
> -       ("sqlite" ,sqlite)
> -       ("sh" ,bash-minimal)
> -       ;; only for CS
> -       ("zlib" ,zlib)
> -       ("zlib:static" ,zlib "static")
> -       ("lz4" ,lz4)
> -       ("lz4:static" ,lz4 "static")))
> -    (native-inputs
> -     `(("bootfiles" ,racket-bootstrap-chez-bootfiles)
> -       ,@(package-native-inputs racket-bootstrap-chez-bootfiles)))
> +    (version (package-version (racket-vm-for-system)))
> +    (source (package-source (racket-vm-for-system)))
> +    ;; For cross-compilation, Matthew Flatt recommends reusing
> +    ;; as much of `raco cross` as possible. So, put that off until
> +    ;; we have a build system for Racket packages.
> +    (inputs (list openssl sqlite (racket-vm-for-system)))
As outlined earlier, I believe Racket should define its version, not
racket-vm-for-system.

> [...]
>  (define-public racket
>    (package
>      (inherit racket-minimal)
>      (name "racket")
> -    (version (package-version racket-minimal)) ; needed for origin
> uri to work
> -    (source
> -     (origin
> -       (method url-fetch)
> -       (uri (map (lambda (base)
> -                   (string-append base version "/racket-src.tgz"))
> -                 %installer-mirrors))
> -       (sha256
> -        (base32
> -         "0jdr0y7scvv2a3sq456ifrgq0yfsbiwavdf2m86zmrapp481mby4"))
> -       (snippet
> -        #~(begin
> -            (use-modules (guix build utils)
> -                         (ice-9 match)
> -                         (ice-9 regex))
> -            ;; unbundle minimal Racket
> -            (for-each delete-file-recursively
> -                      '("collects"
> -                        "doc"
> -                        "etc"
> -                        "README"
> -                        "src"))
> -            ;; unbundle package sources included elsewhere
> -            (with-directory-excursion "share/pkgs"
> -              (for-each delete-file-recursively
> -                        '#+%main-repo-main-distribution-pkgs))
> -            #t))))
> +    (source #f)
Why?
>      (inputs
> -     `(("cairo" ,cairo)
> -       ("fontconfig" ,fontconfig)
> -       ("glib" ,glib)
> -       ("glu" ,glu)
> -       ("gmp" ,gmp)
> -       ("gtk+" ,gtk+)                   ; propagates gdk-pixbuf+svg
> -       ("libjpeg" ,libjpeg-turbo)
> -       ("libpng" ,libpng)
> -       ("libx11" ,libx11)
> -       ("mesa" ,mesa)
> -       ("mpfr" ,mpfr)
> -       ("pango" ,pango)
> -       ("unixodbc" ,unixodbc)
> -       ("libedit" ,libedit)))
> -    (native-inputs
> -     `(("racket" ,racket-minimal)
> -       ("extend-layer" ,extend-layer)
> -       ("main-repo" ,(package-source racket-minimal))))
> +     (list cairo
> +           fontconfig
> +           glib
> +           glu
> +           gmp
> +           gtk+ ;; propagates gdk-pixbuf+svg
> +           libjpeg-turbo
> +           libpng
> +           libx11 ;; ?? wayland ??
> +           mesa
> +           mpfr
> +           pango
> +           unixodbc
> +           libedit ;; TODO reconsider in light of expeditor and
> readline-gpl
> +           racket-minimal ;; <-- TODO non-tethered layer
> +           (racket-vm-for-system)))
>      (arguments
> -     `(#:phases
> -       (modify-phases %standard-phases
> -         (add-before 'configure 'unpack-packages
> -           (let ((unpack (assoc-ref %standard-phases 'unpack)))
> -             (lambda* (#:key  native-inputs inputs outputs #:allow-
> other-keys)
> -               (let* ((racket (assoc-ref (or native-inputs inputs)
> "racket"))
> -                      (prefix (assoc-ref outputs "out"))
> -                      (pkgs-dir (string-append prefix
> "/share/racket/pkgs")))
> -                 (mkdir-p pkgs-dir)
> -                 (copy-recursively
> -                  "share/links.rktd"
> -                  (string-append prefix "/share/racket/links.rktd"))
> -                 (copy-recursively "share/pkgs" pkgs-dir)
> -                 ;; NOTE: unpack changes the working directory
> -                 (unpack #:source (assoc-ref (or native-inputs
> inputs)
> -                                             "main-repo"))
> -                 (for-each (lambda (pkg)
> -                             (define dest (string-append pkgs-dir
> "/" pkg))
> -                             (mkdir-p dest)
> -                             (copy-recursively (string-append
> "pkgs/" pkg)
> -                                               dest))
> -                           ',%main-repo-main-distribution-pkgs)
> -                 #t))))
> -         (replace 'configure
> -           (lambda* (#:key native-inputs inputs outputs #:allow-
> other-keys)
> -             (let ((racket (assoc-ref (or native-inputs inputs)
> "racket"))
> -                   (prefix (assoc-ref outputs "out")))
> -               (apply invoke
> -                      (string-append racket "/bin/racket")
> -                      (assoc-ref inputs "extend-layer")
> -                      racket
> -                      prefix
> -                      (map
> -                       (lambda (lib)
> -                         (string-append (assoc-ref inputs lib)
> "/lib"))
> -                       '("cairo"
> -                         "fontconfig"
> -                         "glib"
> -                         "glu"
> -                         "gmp"
> -                         "gtk+"
> -                         "libjpeg"
> -                         "libpng"
> -                         "libx11"
> -                         "mesa"
> -                         "mpfr"
> -                         "pango"
> -                         "unixodbc"
> -                         "libedit")))
> -               #t)))
> -         (replace 'build
> -           (lambda* (#:key native-inputs inputs outputs #:allow-
> other-keys)
> -             (invoke (string-append (assoc-ref (or native-inputs
> inputs)
> -                                               "racket")
> -                                    "/bin/racket")
> -                     "--config"
> -                     (string-append (assoc-ref outputs "out")
> -                                    "/etc/racket")
> -                     "-l"
> -                     "raco"
> -                     "setup")
> -             #t))
> -         (delete 'install))
> -       ;; we still don't have these:
> -       #:tests? #f))
> +     (substitute-keyword-arguments (package-arguments racket-
> minimal)
> +       ((#:configure-flags _ '())
> +        #~`("--tethered"
> +            "--extra-foreign-lib-search-dirs"
> +            ,(format #f "~s"
> +                     '(#$@(map (lambda (name)
> +                                 (cond
> +                                  ((this-package-input name)
> +                                   => (cut file-append <> "/lib"))
> +                                  (else
> +                                   (raise-exception
> +                                    (make-exception
> +                                     (make-assertion-failure)
> +                                     (make-exception-with-message
> +                                      "missing input to the 'racket'
> package")
> +                                     (make-exception-with-irritants
> +                                      (list name)))))))
> +                               '("cairo"
> +                                 "fontconfig-minimal" ;; aka
> fontconfig
> +                                 "glib"
> +                                 "glu"
> +                                 "gmp"
> +                                 "gtk+"
> +                                 "libjpeg-turbo"
> +                                 "libpng"
> +                                 "libx11"
> +                                 "mesa"
> +                                 "mpfr"
> +                                 "pango"
> +                                 "unixodbc"
> +                                 "libedit"))))))
> +       ((#:make-flags _ '())
> +        #~`("main-distribution"))
> +       ((#:phases parent-phases #~%standard-phases)
> +        #~(modify-phases #$parent-phases
> +            (delete 'unpack)
> +            (replace 'build
> +              (lambda args
> +                (mkdir-p (string-append #$output
> "/lib/racket/pkgs"))
> +                (for-each
> +                 (match-lambda
> +                   ((name src)
> +                    (copy-recursively
> +                     src
> +                     (string-append #$output "/lib/racket/pkgs/"
> name))))
> +                 '(#$@main-distribution-packages))))))))
>      (synopsis "Programmable programming language in the Scheme
> family")
>      (description
>       "Racket is a general-purpose programming language in the Scheme
> family,
> @@ -539,82 +224,899 @@ (define dest (string-append pkgs-dir "/" pkg))
>  DrRacket IDE, libraries for GUI and web programming, and
> implementations of
>  languages such as Typed Racket, R5RS and R6RS Scheme, Algol 60, and
> Datalog.")))
This looks like a very weird way of phrasing union-build.  Is there a
reason to do this rather than union-build?


Cheers
Philip McGrath Feb. 19, 2022, 2:07 a.m. UTC | #2
Hi,

On Friday, February 18, 2022 2:38:52 AM EST Liliana Marie Prikler wrote:
> Hi,
> 
> Am Donnerstag, dem 17.02.2022 um 15:50 -0500 schrieb Philip McGrath:
> > -;; Commentary:
> > -;;
> > -;; Here's how bootstrapping minimal Racket works:
> > -;;
> > -;;   - Racket BC [CGC] can be built with only a C compiler (except
> > for
> > -;;     one caveat discussed below).
> > -;;   - Racket BC [3M] needs an existing Racket to run "xform",
> > -;;     which transforms its own C source code to add additional
> > annotations
> > -;;     for the precise garbage collector.
> > -;;   - Racket CS needs (bootfiles for) Racket's fork of Chez Scheme.
> > -;;     It also needs an existing Racket to compile Racket-
> > implemented
> > -;;     parts of the runtime system to R6RS libraries.
> > -;;   - Chez Scheme also needs bootfiles for itself, but Racket can
> > simulate
> > -;;     enough of Chez Scheme to load Racket's fork of the Chez
> > Scheme compiler
> > -;;     purely from source into Racket and apply the compiler to
> > itself,
> > -;;     producing the needed bootfiles (albeit very slowly).
> > -;;     Any variant of Racket since version 7.1 can run the
> > simulation.
> > -;;
> > -;; So, we build CGC to build 3M to build bootfiles and CS.
> > -;;
> > -;; One remaining bootstrapping limitation is that Racket's reader,
> > module
> > -;; system, and macro expander are implemented in Racket. For Racket
> > CS,
> > -;; they are compiled to R6RS libraries as discussed above. This note
> > from the
> > -;; README file applies to all such subsystems:
> > -;;
> > -;;     The Racket version must be practically the same as the
> > current Racket
> > -;;     verson, although it can be the Racket BC implementation
> > (instead of
> > -;;     the Racket CS implementation).
> > -;;
> > -;;     Unlike Chez Scheme boot files, the files generated in
> > "schemified"
> > -;;     are human-readable and -editable Scheme code. That provides a
> > way
> > -;;     out of bootstrapping black holes, even without BC.
> > -;;
> > -;; However, other Racket subsystems implemented in Racket for Racket
> > CS
> > -;; use older C implementations for Racket BC, whereas the reader,
> > expander,
> > -;; and module system were completely replaced with the Racket
> > implementation
> > -;; as of Racket 7.0.
> > -;;
> > -;; For Racket BC, the compiled "linklet" s-expressions (primitive
> > modules)
> > -;; are embeded in C as a static string constant. Eventually, they
> > are further
> > -;; compiled by the C-implemented Racket BC bytecode and JIT
> > compilers.
> > -;; (On platforms where Racket BC's JIT is not supported, yet another
> > compiler
> > -;; instead compiles the linklets to C code, but this is not a
> > bootstrapping
> > -;; issue.)
> 
> I think it'd be clearer if this commentary was moved along with the
> bootstrapping code.

I did add it to "chez-and-racket-bootstrap.scm" at the same time as I added 
the Racket bootstrapping code there. But I didn't delete the bootstrapping 
code from this file until this commit, so I deleted the associated comment at 
the same time.

> Is there a reason why we can't use (racket-vm-for-
> system) before updating Racket to 8.4?  This looks like another of
> those "two things at once" patches.
>  

The whole series based on `racket-vm-*` would not work with Racket 8.3 without 
backporting at least some things: off the top of my head, at a minimum, we 
would need b53090140596cc8522037f4c812325c71648df7a and 
2b282d9c48df811cd4678cdbaed8258cdef23946 to be able to build "chez-scheme-for-
racket:doc".

Maybe it will seem less like "two things at once" if I explain more explicitly 
that "racket-minimal@8.3" is actually the same content that is now in "racket-
vm-cs@8.4" (just installed into different directories), and does *not* contain 
anything that is now in "racket-minimal@8.4". 

Shortly before the release of Racket 8.3, it came to light from the 
intersection of a few conversations (scattered across several places, but 
summarised in <https://github.com/racket/racket/issues/
3851#issuecomment-932641908> and the following two comments) that the contents 
of a "minimal Racket" were inconsistent. On Windows, Mac OS, and "x86_64-
linux-natipkg" (a special configuration that avoids relying on a system package 
manager, e.g. for CI), minimal Racket had "racket-lib", "base", and packages 
providing native libraries (e.g. OpenSSL and SQLite). On other systems, 
whether using pre-built binaries or building from source using the released 
tarballs, "minimal Racket" would end up with only the "racket-lib" package, 
because "base" was pulled in only as a dependency of the native library 
packages. However, when building minimal Racket from the Git sources in the 
way Guix was, "minimal Racket" ended up with no packages installed at all.

Matthew Flatt's conclusion was that, starting after the 8.3 release (to allow 
more time for testing), "racket-lib" should directly depend on "base", and 
"minimal Racket" should always explicitly install "racket-lib". (That fits the 
semantic roles of those packages, which represent the current always-available 
native libraries and the current "built in" collections in the Racket package 
system's model of dependencies and compatibility.)

That works out especially nicely for Guix, as it gives us a clean boundary 
between the core Racket VM and compiler, with all of the bootstrapping 
involved, and building Racket packages and installation layers, which can be 
handled in a nice, uniform way and eventually turned into a `racket-build-
system`.

> >  (define-public racket-minimal
> >    (package
> >      (name "racket-minimal")
> > -    (version "8.3")            ; note: remember to also update
> > racket!
> > -    (source
> > -     (origin
> > -       (method git-fetch)
> > -       (uri (git-reference
> > -             (url "https://github.com/racket/racket")
> > -             (commit (string-append "v" version))))
> > -       (sha256
> > -        "1i1jnv1wb0kanfg47hniafx2vhwjc33qqx66lq7wkf5hbmgsyws3")
> > -       (file-name (git-file-name name version))
> > -       (patches (search-patches "racket-minimal-sh-via-
> > rktio.patch"))
> > -       (modules '((guix build utils)))
> > -       (snippet
> > -        (with-imported-modules '((guix build utils))
> > -          #~(begin
> > -              ;; Unbundle Chez submodules.
> > -              (with-directory-excursion "racket/src/ChezScheme"
> > -                ;; Remove bundled libraries (copied from 'chez-
> > scheme').
> > -                (for-each delete-file-recursively
> > -                          '("stex"
> > -                            "nanopass"
> > -                            "lz4"
> > -                            "zlib")))
> > -              ;; Unbundle libffi.
> > -              (delete-file-recursively
> > "racket/src/bc/foreign/libffi"))))))
> > -    (inputs
> > -     `(;; common to all racket-minimal variants:
> > -       ("openssl" ,openssl)
> > -       ("sqlite" ,sqlite)
> > -       ("sh" ,bash-minimal)
> > -       ;; only for CS
> > -       ("zlib" ,zlib)
> > -       ("zlib:static" ,zlib "static")
> > -       ("lz4" ,lz4)
> > -       ("lz4:static" ,lz4 "static")))
> > -    (native-inputs
> > -     `(("bootfiles" ,racket-bootstrap-chez-bootfiles)
> > -       ,@(package-native-inputs racket-bootstrap-chez-bootfiles)))
> > +    (version (package-version (racket-vm-for-system)))
> > +    (source (package-source (racket-vm-for-system)))
> > +    ;; For cross-compilation, Matthew Flatt recommends reusing
> > +    ;; as much of `raco cross` as possible. So, put that off until
> > +    ;; we have a build system for Racket packages.
> > +    (inputs (list openssl sqlite (racket-vm-for-system)))
> 
> As outlined earlier, I believe Racket should define its version, not
> racket-vm-for-system.
> 

As I said, I'll send a v3 with %racket-version.

But the reason I think the `racket` packages would be a particularly bad place 
to define this for reasons related to what I was just describing. Once we have 
a `racket-build-system`—and we are getting ever closer—`racket-minimal` will 
simply be a tethered installation layer with two packages (ignoring 
"natipkg"), assembled with something somewhat like the `texlive-udpmap.cfg` 
function. The `racket` package will likewise be a tethered installation layer 
with 203 packages, two of which will be shared by `racket-minimal`. We will 
want to have others, both larger (e.g. "main-distribution-test" and all of its 
dependencies) and smaller (e.g. some people like just "drracket" without some 
of the more niche dependencies of "main-distribution", like the support 
libraries for the textbook, "Schreibe Dein Programm!"). A major motivation for 
the whole design of the Racket package system (actually, its second package 
system) is that the "main-distribution" package and the Racket distribution 
based on it should not be in any way special or built in: it happens to be 
released at download.racket-lang.org, but there can be many Racket 
distributions. Some might go so far as to argue that any special status of 
"main-distribution" falls under the category of weaknesses and restrictions 
that should be removed.

> >  (define-public racket
> > 
> >    (package
> >      (inherit racket-minimal)
> >      (name "racket")
> > -    (version (package-version racket-minimal)) ; needed for origin
> > uri to work
> > -    (source
> > -     (origin
> > -       (method url-fetch)
> > -       (uri (map (lambda (base)
> > -                   (string-append base version "/racket-src.tgz"))
> > -                 %installer-mirrors))
> > -       (sha256
> > -        (base32
> > -         "0jdr0y7scvv2a3sq456ifrgq0yfsbiwavdf2m86zmrapp481mby4"))
> > -       (snippet
> > -        #~(begin
> > -            (use-modules (guix build utils)
> > -                         (ice-9 match)
> > -                         (ice-9 regex))
> > -            ;; unbundle minimal Racket
> > -            (for-each delete-file-recursively
> > -                      '("collects"
> > -                        "doc"
> > -                        "etc"
> > -                        "README"
> > -                        "src"))
> > -            ;; unbundle package sources included elsewhere
> > -            (with-directory-excursion "share/pkgs"
> > -              (for-each delete-file-recursively
> > -                        '#+%main-repo-main-distribution-pkgs))
> > -            #t))))
> > +    (source #f)
> 
> Why?
> 

The vast majority of package in `racket` are not developed in the <https://
github.com/racket/racket> repository. For that matter, the source of the "main 
distribution" package itself is <https://github.com/racket/main-distribution> 
(and, under the Racket package system's notion of versions, it is at version 
"0.0").

> >      (inputs
> > -     `(("cairo" ,cairo)
> > -       ("fontconfig" ,fontconfig)
> > -       ("glib" ,glib)
> > -       ("glu" ,glu)
> > -       ("gmp" ,gmp)
> > -       ("gtk+" ,gtk+)                   ; propagates gdk-pixbuf+svg
> > -       ("libjpeg" ,libjpeg-turbo)
> > -       ("libpng" ,libpng)
> > -       ("libx11" ,libx11)
> > -       ("mesa" ,mesa)
> > -       ("mpfr" ,mpfr)
> > -       ("pango" ,pango)
> > -       ("unixodbc" ,unixodbc)
> > -       ("libedit" ,libedit)))
> > -    (native-inputs
> > -     `(("racket" ,racket-minimal)
> > -       ("extend-layer" ,extend-layer)
> > -       ("main-repo" ,(package-source racket-minimal))))
> > +     (list cairo
> > +           fontconfig
> > +           glib
> > +           glu
> > +           gmp
> > +           gtk+ ;; propagates gdk-pixbuf+svg
> > +           libjpeg-turbo
> > +           libpng
> > +           libx11 ;; ?? wayland ??
> > +           mesa
> > +           mpfr
> > +           pango
> > +           unixodbc
> > +           libedit ;; TODO reconsider in light of expeditor and
> > readline-gpl
> > +           racket-minimal ;; <-- TODO non-tethered layer
> > +           (racket-vm-for-system)))
> >      (arguments
> > -     `(#:phases
> > -       (modify-phases %standard-phases
> > -         (add-before 'configure 'unpack-packages
> > -           (let ((unpack (assoc-ref %standard-phases 'unpack)))
> > -             (lambda* (#:key  native-inputs inputs outputs #:allow-
> > other-keys)
> > -               (let* ((racket (assoc-ref (or native-inputs inputs)
> > "racket"))
> > -                      (prefix (assoc-ref outputs "out"))
> > -                      (pkgs-dir (string-append prefix
> > "/share/racket/pkgs")))
> > -                 (mkdir-p pkgs-dir)
> > -                 (copy-recursively
> > -                  "share/links.rktd"
> > -                  (string-append prefix "/share/racket/links.rktd"))
> > -                 (copy-recursively "share/pkgs" pkgs-dir)
> > -                 ;; NOTE: unpack changes the working directory
> > -                 (unpack #:source (assoc-ref (or native-inputs
> > inputs)
> > -                                             "main-repo"))
> > -                 (for-each (lambda (pkg)
> > -                             (define dest (string-append pkgs-dir
> > "/" pkg))
> > -                             (mkdir-p dest)
> > -                             (copy-recursively (string-append
> > "pkgs/" pkg)
> > -                                               dest))
> > -                           ',%main-repo-main-distribution-pkgs)
> > -                 #t))))
> > -         (replace 'configure
> > -           (lambda* (#:key native-inputs inputs outputs #:allow-
> > other-keys)
> > -             (let ((racket (assoc-ref (or native-inputs inputs)
> > "racket"))
> > -                   (prefix (assoc-ref outputs "out")))
> > -               (apply invoke
> > -                      (string-append racket "/bin/racket")
> > -                      (assoc-ref inputs "extend-layer")
> > -                      racket
> > -                      prefix
> > -                      (map
> > -                       (lambda (lib)
> > -                         (string-append (assoc-ref inputs lib)
> > "/lib"))
> > -                       '("cairo"
> > -                         "fontconfig"
> > -                         "glib"
> > -                         "glu"
> > -                         "gmp"
> > -                         "gtk+"
> > -                         "libjpeg"
> > -                         "libpng"
> > -                         "libx11"
> > -                         "mesa"
> > -                         "mpfr"
> > -                         "pango"
> > -                         "unixodbc"
> > -                         "libedit")))
> > -               #t)))
> > -         (replace 'build
> > -           (lambda* (#:key native-inputs inputs outputs #:allow-
> > other-keys)
> > -             (invoke (string-append (assoc-ref (or native-inputs
> > inputs)
> > -                                               "racket")
> > -                                    "/bin/racket")
> > -                     "--config"
> > -                     (string-append (assoc-ref outputs "out")
> > -                                    "/etc/racket")
> > -                     "-l"
> > -                     "raco"
> > -                     "setup")
> > -             #t))
> > -         (delete 'install))
> > -       ;; we still don't have these:
> > -       #:tests? #f))
> > +     (substitute-keyword-arguments (package-arguments racket-
> > minimal)
> > +       ((#:configure-flags _ '())
> > +        #~`("--tethered"
> > +            "--extra-foreign-lib-search-dirs"
> > +            ,(format #f "~s"
> > +                     '(#$@(map (lambda (name)
> > +                                 (cond
> > +                                  ((this-package-input name)
> > +                                   => (cut file-append <> "/lib"))
> > +                                  (else
> > +                                   (raise-exception
> > +                                    (make-exception
> > +                                     (make-assertion-failure)
> > +                                     (make-exception-with-message
> > +                                      "missing input to the 'racket'
> > package")
> > +                                     (make-exception-with-irritants
> > +                                      (list name)))))))
> > +                               '("cairo"
> > +                                 "fontconfig-minimal" ;; aka
> > fontconfig
> > +                                 "glib"
> > +                                 "glu"
> > +                                 "gmp"
> > +                                 "gtk+"
> > +                                 "libjpeg-turbo"
> > +                                 "libpng"
> > +                                 "libx11"
> > +                                 "mesa"
> > +                                 "mpfr"
> > +                                 "pango"
> > +                                 "unixodbc"
> > +                                 "libedit"))))))
> > +       ((#:make-flags _ '())
> > +        #~`("main-distribution"))
> > +       ((#:phases parent-phases #~%standard-phases)
> > +        #~(modify-phases #$parent-phases
> > +            (delete 'unpack)
> > +            (replace 'build
> > +              (lambda args
> > +                (mkdir-p (string-append #$output
> > "/lib/racket/pkgs"))
> > +                (for-each
> > +                 (match-lambda
> > +                   ((name src)
> > +                    (copy-recursively
> > +                     src
> > +                     (string-append #$output "/lib/racket/pkgs/"
> > name))))
> > +                 '(#$@main-distribution-packages))))))))
> >      (synopsis "Programmable programming language in the Scheme
> > family")
> >      (description
> >       "Racket is a general-purpose programming language in the Scheme
> > family,
> > @@ -539,82 +224,899 @@ (define dest (string-append pkgs-dir "/" pkg))
> >  DrRacket IDE, libraries for GUI and web programming, and
> > implementations of
> >  languages such as Typed Racket, R5RS and R6RS Scheme, Algol 60, and
> > Datalog.")))
> 
> This looks like a very weird way of phrasing union-build.  Is there a
> reason to do this rather than union-build?
> 

IIUC, packages aren't supposed to install symbolic links into their sources, 
as `union-build` would do—wouldn't that prevent all of the extraneous files in 
those origins from being GCed? There's also the fact that `name` may be 
different from the name of the last element of `src`: in particular, in a 
significant number of cases, `src` will be something like "/gnu/store/
x22awqf0rbcyyk88kj82zihmdgkfhgza-racket-main-distribution-8.4-checkout" when 
`name` is "main-distribution".

-Philip
diff mbox series

Patch

diff --git a/gnu/local.mk b/gnu/local.mk
index aaecbc7898..6f4ddd3645 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -41,7 +41,7 @@ 
 # Copyright © 2020 Vinicius Monego <monego@posteo.net>
 # Copyright © 2021 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
 # Copyright © 2021 Greg Hogan <code@greghogan.com>
-# Copyright © 2021 Philip McGrath <philip@philipmcgrath.com>
+# Copyright © 2021, 2022 Philip McGrath <philip@philipmcgrath.com>
 # Copyright © 2021 Arun Isaac <arunisaac@systemreboot.net>
 # Copyright © 2021 Sharlatan Hellseher <sharlatanus@gmail.com>
 # Copyright © 2021 Dmitry Polyakov <polyakov@liltechdude.xyz>
@@ -1753,6 +1753,7 @@  dist_patch_DATA =						\
   %D%/packages/patches/rpcbind-CVE-2017-8779.patch		\
   %D%/packages/patches/rtags-separate-rct.patch			\
   %D%/packages/patches/racket-enable-scheme-backport.patch	\
+  %D%/packages/patches/racket-gui-tethered-launcher-backport.patch	\
   %D%/packages/patches/racket-minimal-sh-via-rktio.patch	\
   %D%/packages/patches/remake-impure-dirs.patch			\
   %D%/packages/patches/restic-0.9.6-fix-tests-for-go1.15.patch	\
diff --git a/gnu/packages/chez-and-racket-bootstrap.scm b/gnu/packages/chez-and-racket-bootstrap.scm
index 876c963293..cbdddb1e98 100644
--- a/gnu/packages/chez-and-racket-bootstrap.scm
+++ b/gnu/packages/chez-and-racket-bootstrap.scm
@@ -46,7 +46,8 @@  (define-module (gnu packages chez-and-racket-bootstrap)
   #:use-module (gnu packages xorg)
   #:use-module ((guix licenses)
                 #:prefix license:)
-  #:export (chez-scheme-for-system))
+  #:export (chez-scheme-for-system
+            racket-vm-for-system))
 
 ;; Commentary:
 ;;
@@ -209,6 +210,14 @@  (define* (chez-scheme-for-system #:optional
       chez-scheme-for-racket
       chez-scheme))
 
+(define* (racket-vm-for-system #:optional
+                               (system (or (%current-target-system)
+                                           (%current-system))))
+  "Return 'racket-vm-cs' if it supports SYSTEM; 'racket-vm-bc' otherwise."
+  (if (nix-system->chez-machine system)
+      racket-vm-cs
+      racket-vm-bc))
+
 (define (chez-machine->nonthreaded machine)
   "Given a string MACHINE naming a Chez Scheme machine type, returns a string
 naming the nonthreaded machine type for the same architecture and OS as
diff --git a/gnu/packages/patches/racket-gui-tethered-launcher-backport.patch b/gnu/packages/patches/racket-gui-tethered-launcher-backport.patch
new file mode 100644
index 0000000000..1e018eaa79
--- /dev/null
+++ b/gnu/packages/patches/racket-gui-tethered-launcher-backport.patch
@@ -0,0 +1,26 @@ 
+From aa792e707b1fbc5cc33691bfaee5828dc3fbebaa Mon Sep 17 00:00:00 2001
+From: Matthew Flatt <mflatt@racket-lang.org>
+Date: Mon, 31 Jan 2022 15:31:22 -0700
+Subject: [PATCH] fix creation of tethered launchers
+
+Related to racket/racket#4133
+
+(cherry picked from commit 563c68432f127729592f234ef30c31e92618b517)
+---
+ gui-lib/mred/installer.rkt | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/gui-lib/mred/installer.rkt b/gui-lib/mred/installer.rkt
+index b1691472..9ef06c53 100644
+--- a/gui-lib/mred/installer.rkt
++++ b/gui-lib/mred/installer.rkt
+@@ -72,4 +72,5 @@
+    (list "-A" (path->string (find-system-path 'addon-dir)))))
+ 
+ (define (config-flags)
+-  (list "-G" (path->string (find-config-dir))))
++  (list "-X" (path->string (find-collects-dir))
++        "-G" (path->string (find-config-dir))))
+-- 
+2.32.0
+
diff --git a/gnu/packages/racket.scm b/gnu/packages/racket.scm
index e8d016c07b..d66ff996cb 100644
--- a/gnu/packages/racket.scm
+++ b/gnu/packages/racket.scm
@@ -2,7 +2,7 @@ 
 ;;; Copyright © 2013, 2014, 2015, 2016, 2018, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2017, 2018, 2019, 2020 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;; Copyright © 2020 Pierre Neidhardt <mail@ambrevar.xyz>
-;;; Copyright © 2021 Philip McGrath <philip@philipmcgrath.com>
+;;; Copyright © 2021, 2022 Philip McGrath <philip@philipmcgrath.com>
 ;;; Copyright © 2021 jgart <jgart@dismail.de>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -21,8 +21,6 @@ 
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu packages racket)
-  #:use-module ((guix licenses)
-                #:select (asl2.0 expat lgpl3+))
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix git-download)
@@ -30,7 +28,10 @@  (define-module (gnu packages racket)
   #:use-module (guix gexp)
   #:use-module (guix build-system gnu)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
   #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 exceptions)
   #:use-module (gnu packages)
   #:use-module (gnu packages autotools)
   #:use-module (gnu packages bash)
@@ -47,200 +48,87 @@  (define-module (gnu packages racket)
   #:use-module (gnu packages multiprecision)
   #:use-module (gnu packages sqlite)
   #:use-module (gnu packages tls)
-  #:use-module (gnu packages xorg))
-
-;; Commentary:
-;;
-;; Here's how bootstrapping minimal Racket works:
-;;
-;;   - Racket BC [CGC] can be built with only a C compiler (except for
-;;     one caveat discussed below).
-;;   - Racket BC [3M] needs an existing Racket to run "xform",
-;;     which transforms its own C source code to add additional annotations
-;;     for the precise garbage collector.
-;;   - Racket CS needs (bootfiles for) Racket's fork of Chez Scheme.
-;;     It also needs an existing Racket to compile Racket-implemented
-;;     parts of the runtime system to R6RS libraries.
-;;   - Chez Scheme also needs bootfiles for itself, but Racket can simulate
-;;     enough of Chez Scheme to load Racket's fork of the Chez Scheme compiler
-;;     purely from source into Racket and apply the compiler to itself,
-;;     producing the needed bootfiles (albeit very slowly).
-;;     Any variant of Racket since version 7.1 can run the simulation.
-;;
-;; So, we build CGC to build 3M to build bootfiles and CS.
-;;
-;; One remaining bootstrapping limitation is that Racket's reader, module
-;; system, and macro expander are implemented in Racket. For Racket CS,
-;; they are compiled to R6RS libraries as discussed above. This note from the
-;; README file applies to all such subsystems:
-;;
-;;     The Racket version must be practically the same as the current Racket
-;;     verson, although it can be the Racket BC implementation (instead of
-;;     the Racket CS implementation).
-;;
-;;     Unlike Chez Scheme boot files, the files generated in "schemified"
-;;     are human-readable and -editable Scheme code. That provides a way
-;;     out of bootstrapping black holes, even without BC.
-;;
-;; However, other Racket subsystems implemented in Racket for Racket CS
-;; use older C implementations for Racket BC, whereas the reader, expander,
-;; and module system were completely replaced with the Racket implementation
-;; as of Racket 7.0.
-;;
-;; For Racket BC, the compiled "linklet" s-expressions (primitive modules)
-;; are embeded in C as a static string constant. Eventually, they are further
-;; compiled by the C-implemented Racket BC bytecode and JIT compilers.
-;; (On platforms where Racket BC's JIT is not supported, yet another compiler
-;; instead compiles the linklets to C code, but this is not a bootstrapping
-;; issue.)
-;;
-;; Code:
-
-(define cfg-flag:sh-for-rktio
-  `(string-append "CPPFLAGS=-DGUIX_RKTIO_PATCH_BIN_SH="
-                  (assoc-ref %build-inputs "sh")
-                  "/bin/sh"))
-(define cfg-flag:enable-lt
-  `(string-append "--enable-lt="
-                  (assoc-ref %build-inputs "libtool")
-                  "/bin/libtool"))
-(define cfg-flag:enable-racket
-  `(let ((racket (assoc-ref %build-inputs "racket")))
-     (string-append "--enable-racket="
-                    racket
-                    "/bin/racket")))
-
-(define unpack-nanopass+stex
-  ;; Copied from chez-scheme.
-  ;; TODO: Eventually, we should refactor Chez Scheme
-  ;; enough to share more directly, so that we can make
-  ;; Racket's version of Chez avalable as a Guix package,
-  ;; e.g. for architectures not supported upstream.
-  ;; For now, we let Racket drive the Chez build process
-  ;; other than this step.
-  `(for-each (lambda (dep)
-               (define src
-                 (assoc-ref (or native-inputs inputs) dep))
-               (copy-recursively src dep
-                                 #:keep-mtime? #t))
-             '("nanopass" "stex")))
-
+  #:use-module (gnu packages xorg)
+  #:use-module ((guix licenses)
+                #:prefix license:))
 
 (define-public racket-minimal
   (package
     (name "racket-minimal")
-    (version "8.3")            ; note: remember to also update racket!
-    (source
-     (origin
-       (method git-fetch)
-       (uri (git-reference
-             (url "https://github.com/racket/racket")
-             (commit (string-append "v" version))))
-       (sha256
-        "1i1jnv1wb0kanfg47hniafx2vhwjc33qqx66lq7wkf5hbmgsyws3")
-       (file-name (git-file-name name version))
-       (patches (search-patches "racket-minimal-sh-via-rktio.patch"))
-       (modules '((guix build utils)))
-       (snippet
-        (with-imported-modules '((guix build utils))
-          #~(begin
-              ;; Unbundle Chez submodules.
-              (with-directory-excursion "racket/src/ChezScheme"
-                ;; Remove bundled libraries (copied from 'chez-scheme').
-                (for-each delete-file-recursively
-                          '("stex"
-                            "nanopass"
-                            "lz4"
-                            "zlib")))
-              ;; Unbundle libffi.
-              (delete-file-recursively "racket/src/bc/foreign/libffi"))))))
-    (inputs
-     `(;; common to all racket-minimal variants:
-       ("openssl" ,openssl)
-       ("sqlite" ,sqlite)
-       ("sh" ,bash-minimal)
-       ;; only for CS
-       ("zlib" ,zlib)
-       ("zlib:static" ,zlib "static")
-       ("lz4" ,lz4)
-       ("lz4:static" ,lz4 "static")))
-    (native-inputs
-     `(("bootfiles" ,racket-bootstrap-chez-bootfiles)
-       ,@(package-native-inputs racket-bootstrap-chez-bootfiles)))
+    (version (package-version (racket-vm-for-system)))
+    (source (package-source (racket-vm-for-system)))
+    ;; For cross-compilation, Matthew Flatt recommends reusing
+    ;; as much of `raco cross` as possible. So, put that off until
+    ;; we have a build system for Racket packages.
+    (inputs (list openssl sqlite (racket-vm-for-system)))
     (build-system gnu-build-system)
     (arguments
-     `(#:configure-flags
-       (list "--enable-csonly"
-             "--enable-libz"
-             "--enable-liblz4"
-             ,cfg-flag:enable-racket
-             ,cfg-flag:sh-for-rktio)
-       #:out-of-source? #true
-       ;; Tests are in packages like racket-test-core and
-       ;; main-distribution-test that aren't part of the main distribution.
-       #:tests? #f
-       #:modules ((ice-9 match)
-                  (guix build gnu-build-system)
-                  (guix build utils))
-       #:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'unpack-nanopass+stex
-           (lambda* (#:key inputs native-inputs #:allow-other-keys)
-             (with-directory-excursion "racket/src/ChezScheme"
-               ,unpack-nanopass+stex)
-             #t))
-         (add-after 'unpack-nanopass+stex 'unpack-bootfiles
-           (lambda* (#:key inputs #:allow-other-keys)
-             (with-directory-excursion "racket/src/ChezScheme"
-               (copy-recursively
-                (string-append (assoc-ref inputs "bootfiles") "/boot")
-                "boot"))
-             #t))
-         (add-before 'configure 'initialize-config.rktd
-           (lambda* (#:key inputs #:allow-other-keys)
-             (define (write-racket-hash alist)
-               ;; inside must use dotted pair notation
-               (display "#hash(")
-               (for-each (match-lambda
-                           ((k . v)
-                            (format #t "(~s . ~s)" k v)))
-                         alist)
-               (display ")\n"))
-             (mkdir-p "racket/etc")
-             (with-output-to-file "racket/etc/config.rktd"
-               (lambda ()
-                 (write-racket-hash
-                  `((lib-search-dirs
-                     . (#f ,@(map (lambda (lib)
-                                    (string-append (assoc-ref inputs lib)
-                                                   "/lib"))
-                                  '("openssl"
-                                    "sqlite"))))
-                    (build-stamp . "")
-                    (catalogs
-                     . (,(string-append
-                          "https://download.racket-lang.org/releases/"
-                          ,version
-                          "/catalog/")
-                        #f))))))
-             #t))
-         (add-before 'configure 'change-directory
-           (lambda _
-             (chdir "racket/src")
-             #t))
-         (add-after 'install 'remove-pkgs-directory
-           ;; If the configured pkgs-dir exists, "pkgs.rktd" does not
-           ;; exist, and a lock file does not exist, commands like
-           ;; `raco pkg show` will try to create a lock file and fail
-           ;; due to the read-only store.
-           ;; Arguably this may be a bug in `pkg/private/lock`:
-           ;; see <https://github.com/racket/racket/issues/3851>.
-           ;; As a workaround, remove the directory.
-           (lambda* (#:key outputs #:allow-other-keys)
-             ;; rmdir because we want an error if it isn't empty
-             (rmdir (string-append (assoc-ref outputs "out")
-                                   "/share/racket/pkgs"))
-             #t)))))
+     (list
+      #:configure-flags
+      #~`("--tethered"
+          "--extra-foreign-lib-search-dirs"
+          ,(format #f "~s"
+                   (list #$(file-append (this-package-input "openssl") "/lib")
+                         #$(file-append (this-package-input "sqlite") "/lib"))))
+      #:make-flags #~`("base")
+      #:tests? #f ;; packaged separately
+      #:modules '((guix build gnu-build-system)
+                  (guix build utils)
+                  (ice-9 match))
+      #:phases
+      #~(modify-phases %standard-phases
+          (replace 'configure
+            (lambda* (#:key inputs configure-flags make-flags
+                            #:allow-other-keys)
+              (let* ((vm-dir (search-input-directory inputs "opt/racket-vm"))
+                     (racket (string-append vm-dir "/bin/racket")))
+                (apply invoke
+                       racket
+                       #$make-installation-layer.rkt
+                       `(,@(cond
+                            ((false-if-exception
+                              (search-input-file
+                               inputs "etc/racket/config.rktd"))
+                             => (lambda (file)
+                                  `("--parent"
+                                    ,(dirname (dirname (dirname file))))))
+                            (else
+                             '()))
+                         ,@configure-flags
+                         ,vm-dir
+                         ,#$output))
+                (invoke racket
+                        "--config" (string-append #$output "/etc/racket")
+                        "-l" "raco" "setup"
+                        "--no-user"))))
+          (replace 'build
+            (lambda* (#:key inputs #:allow-other-keys)
+              (mkdir-p (string-append #$output "/lib/racket/pkgs"))
+              (for-each (lambda (name)
+                          (copy-recursively
+                           (string-append "pkgs/" name)
+                           (string-append #$output "/lib/racket/pkgs/" name)))
+                        '("base" "racket-lib"))))
+          (replace 'install
+            (lambda* (#:key inputs make-flags #:allow-other-keys)
+              (let ((racket
+                     (search-input-file inputs "/opt/racket-vm/bin/racket")))
+                (unless (null? make-flags)
+                  (invoke racket
+                          "-l-"
+                          "pkg/dirs-catalog"
+                          "--link"
+                          "local-catalog"
+                          (string-append #$output "/lib/racket/pkgs"))
+                  (apply invoke
+                         racket
+                         "--config" (string-append #$output "/etc/racket")
+                         "-l" "raco"
+                         "pkg" "install"
+                         "--installation"
+                         "--auto"
+                         "--catalog" "local-catalog"
+                         make-flags))))))))
     (home-page "https://racket-lang.org")
     (synopsis "Racket without bundled packages such as DrRacket")
     (description
@@ -254,280 +142,77 @@  (define (write-racket-hash alist)
 DrRacket IDE, are not included.")
     ;; https://download.racket-lang.org/license.html
     ;; The LGPL components are only used by Racket BC.
-    (license (list asl2.0 expat))))
-
-
-(define-public racket-minimal-bc-3m
-  (hidden-package
-   (package
-     (inherit racket-minimal)
-     (name "racket-minimal-bc-3m")
-     (inputs
-      (modify-inputs (package-inputs racket-minimal)
-        (delete "zlib" "zlib:static" "lz4" "lz4:static")
-        (prepend libffi ;; <- only for BC variants
-                 )))
-     (native-inputs
-      `(("libtool" ,libtool)
-        ("racket" ,(if (%current-target-system)
-                       racket-minimal
-                       racket-minimal-bc-cgc))))
-     (arguments
-      (substitute-keyword-arguments (package-arguments racket-minimal)
-        ((#:configure-flags _ '())
-         `(list "--enable-bconly"
-                ,cfg-flag:enable-racket
-                ,cfg-flag:enable-lt
-                ,cfg-flag:sh-for-rktio))
-        ((#:phases usual-phases)
-         `(modify-phases ,usual-phases
-            (delete 'unpack-nanopass+stex)
-            (delete 'unpack-bootfiles)))))
-     (synopsis "Minimal Racket with the BC [3M] runtime system")
-     (description "The Racket BC (``before Chez'' or ``bytecode'')
-implementation was the default before Racket 8.0.  It uses a compiler written
-in C targeting architecture-independent bytecode, plus a JIT compiler on most
-platforms.  Racket BC has a different C API and supports a slightly different
-set of architectures than the current default runtime system, Racket CS (based
-on ``Chez Scheme'').
-
-This package is the normal implementation of Racket BC with a precise garbage
-collector, 3M (``Moving Memory Manager'').")
-     ;; https://download.racket-lang.org/license.html
-     ;; The LGPL components are only used by Racket BC.
-     (license (list lgpl3+ asl2.0 expat)))))
-
-
-(define-public racket-minimal-bc-cgc
-  (package
-    (inherit racket-minimal-bc-3m)
-    (name "racket-minimal-bc-cgc")
-    (native-inputs
-     (alist-delete "racket" (package-native-inputs racket-minimal-bc-3m)))
-    (arguments
-     (substitute-keyword-arguments (package-arguments racket-minimal-bc-3m)
-       ((#:configure-flags _ '())
-        `(list "--enable-cgcdefault"
-               ,cfg-flag:enable-lt
-               ,cfg-flag:sh-for-rktio))))
-    (synopsis "Old Racket implementation used for bootstrapping")
-    (description "This variant of the Racket BC (``before Chez'' or
-``bytecode'') implementation is not recommended for general use.  It uses
-CGC (a ``Conservative Garbage Collector''), which was succeeded as default in
-PLT Scheme version 370 (which translates to 3.7 in the current versioning
-scheme) by the 3M variant, which in turn was succeeded in version 8.0 by the
-Racket CS implementation.
-
-Racket BC [CGC] is primarily used for bootstrapping Racket BC [3M].  It may
-also be used for embedding applications without the annotations needed in C
-code to use the 3M garbage collector.")))
-
-
-(define-public racket-bootstrap-chez-bootfiles
-  (hidden-package
-   (package
-     (inherit racket-minimal)
-     (name "racket-bootstrap-chez-bootfiles")
-     (inputs `())
-     (native-inputs
-      `(("racket" ,(if (%current-target-system)
-                       racket-minimal
-                       racket-minimal-bc-3m))
-        ("stex" ,(package-source stex))
-        ("nanopass" ,(package-source chez-nanopass))))
-     (arguments
-      `(#:phases
-        (modify-phases %standard-phases
-          (add-after 'unpack 'unpack-nanopass+stex
-            (lambda* (#:key inputs native-inputs #:allow-other-keys)
-              (with-directory-excursion "racket/src/ChezScheme"
-                ,unpack-nanopass+stex)
-              #t))
-          (delete 'configure)
-          (delete 'patch-generated-file-shebangs)
-          (replace 'build
-            (lambda* (#:key inputs outputs #:allow-other-keys)
-              (with-directory-excursion "racket/src/ChezScheme"
-                (invoke (string-append (assoc-ref inputs "racket")
-                                       "/bin/racket")
-                        "rktboot/main.rkt"
-                        "--dest" (assoc-ref outputs "out")))
-              #t))
-          (delete 'check)
-          (delete 'install))))
-     (synopsis "Chez Scheme bootfiles bootstrapped by Racket")
-     (description "Chez Scheme is a self-hosting compiler: building it
-requires ``bootfiles'' containing the Scheme-implemented portions compiled for
-the current platform.  (Chez can then cross-compile bootfiles for all other
-supported platforms.)
-
-The Racket package @code{cs-bootstrap} (part of the main Racket Git
-repository) implements enough of a Chez Scheme simulation to load the Chez
-Scheme compiler purely from source into Racket and apply the compiler to
-itself, thus bootstrapping Chez Scheme.  Bootstrapping takes about 10 times as
-long as using an existing Chez Scheme, but @code{cs-bootstrap} supports Racket
-7.1 and later, including the Racket BC variant.
-
-Note that the generated bootfiles are specific to Racket's fork of Chez
-Scheme, and @code{cs-bootstrap} does not currently support building upstream
-Chez Scheme.")
-     (license (list asl2.0)))))
-
-
-(define %installer-mirrors
-  ;; Source:
-  ;; https://github.com/racket/racket-lang-org/blob/master/download/data.rkt#L58
-  ;; Matthew Flatt says: "note that many are commented out"
-  ;; INVARIANT: End with a trailing "/"!
-  '("https://mirror.racket-lang.org/installers/"
-    "https://www.cs.utah.edu/plt/installers/"
-    "https://plt.cs.northwestern.edu/racket-mirror/"
-    "https://mirror.csclub.uwaterloo.ca/racket/racket-installers/"
-    ;; Universität Tübingen is using a self-signed HTTPS certificate:
-    "http://mirror.informatik.uni-tuebingen.de/mirror/racket/"
-    "https://racket.infogroep.be/"
-    ))
-
-(define %main-repo-main-distribution-pkgs
-  ;; These are the packages developed in the main Racket Git repository
-  ;; that are part of the main distribution.
-  '("at-exp-lib"
-    "base"
-    "compiler-lib"
-    ;; NOT "compiler-test"
-    "compiler"
-    "net-doc"
-    "net-lib"
-    ;; NOT "net-test"
-    "net"
-    ;; NOT "plt-services"
-    ;; NOT "racket-benchmarks"
-    ;; NOT "racket-build-guide"
-    "racket-doc"
-    "racket-index"
-    "racket-lib"
-    ;; NOT "racket-test-core"
-    ;; NOT "racket-test-extra"
-    ;; NOT "racket-test"
-    "zo-lib"))
-
+    (license (list license:asl2.0 license:expat))))
 
 (define-public racket
   (package
     (inherit racket-minimal)
     (name "racket")
-    (version (package-version racket-minimal)) ; needed for origin uri to work
-    (source
-     (origin
-       (method url-fetch)
-       (uri (map (lambda (base)
-                   (string-append base version "/racket-src.tgz"))
-                 %installer-mirrors))
-       (sha256
-        (base32
-         "0jdr0y7scvv2a3sq456ifrgq0yfsbiwavdf2m86zmrapp481mby4"))
-       (snippet
-        #~(begin
-            (use-modules (guix build utils)
-                         (ice-9 match)
-                         (ice-9 regex))
-            ;; unbundle minimal Racket
-            (for-each delete-file-recursively
-                      '("collects"
-                        "doc"
-                        "etc"
-                        "README"
-                        "src"))
-            ;; unbundle package sources included elsewhere
-            (with-directory-excursion "share/pkgs"
-              (for-each delete-file-recursively
-                        '#+%main-repo-main-distribution-pkgs))
-            #t))))
+    (source #f)
     (inputs
-     `(("cairo" ,cairo)
-       ("fontconfig" ,fontconfig)
-       ("glib" ,glib)
-       ("glu" ,glu)
-       ("gmp" ,gmp)
-       ("gtk+" ,gtk+)                   ; propagates gdk-pixbuf+svg
-       ("libjpeg" ,libjpeg-turbo)
-       ("libpng" ,libpng)
-       ("libx11" ,libx11)
-       ("mesa" ,mesa)
-       ("mpfr" ,mpfr)
-       ("pango" ,pango)
-       ("unixodbc" ,unixodbc)
-       ("libedit" ,libedit)))
-    (native-inputs
-     `(("racket" ,racket-minimal)
-       ("extend-layer" ,extend-layer)
-       ("main-repo" ,(package-source racket-minimal))))
+     (list cairo
+           fontconfig
+           glib
+           glu
+           gmp
+           gtk+ ;; propagates gdk-pixbuf+svg
+           libjpeg-turbo
+           libpng
+           libx11 ;; ?? wayland ??
+           mesa
+           mpfr
+           pango
+           unixodbc
+           libedit ;; TODO reconsider in light of expeditor and readline-gpl
+           racket-minimal ;; <-- TODO non-tethered layer
+           (racket-vm-for-system)))
     (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-before 'configure 'unpack-packages
-           (let ((unpack (assoc-ref %standard-phases 'unpack)))
-             (lambda* (#:key  native-inputs inputs outputs #:allow-other-keys)
-               (let* ((racket (assoc-ref (or native-inputs inputs) "racket"))
-                      (prefix (assoc-ref outputs "out"))
-                      (pkgs-dir (string-append prefix "/share/racket/pkgs")))
-                 (mkdir-p pkgs-dir)
-                 (copy-recursively
-                  "share/links.rktd"
-                  (string-append prefix "/share/racket/links.rktd"))
-                 (copy-recursively "share/pkgs" pkgs-dir)
-                 ;; NOTE: unpack changes the working directory
-                 (unpack #:source (assoc-ref (or native-inputs inputs)
-                                             "main-repo"))
-                 (for-each (lambda (pkg)
-                             (define dest (string-append pkgs-dir "/" pkg))
-                             (mkdir-p dest)
-                             (copy-recursively (string-append "pkgs/" pkg)
-                                               dest))
-                           ',%main-repo-main-distribution-pkgs)
-                 #t))))
-         (replace 'configure
-           (lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
-             (let ((racket (assoc-ref (or native-inputs inputs) "racket"))
-                   (prefix (assoc-ref outputs "out")))
-               (apply invoke
-                      (string-append racket "/bin/racket")
-                      (assoc-ref inputs "extend-layer")
-                      racket
-                      prefix
-                      (map
-                       (lambda (lib)
-                         (string-append (assoc-ref inputs lib) "/lib"))
-                       '("cairo"
-                         "fontconfig"
-                         "glib"
-                         "glu"
-                         "gmp"
-                         "gtk+"
-                         "libjpeg"
-                         "libpng"
-                         "libx11"
-                         "mesa"
-                         "mpfr"
-                         "pango"
-                         "unixodbc"
-                         "libedit")))
-               #t)))
-         (replace 'build
-           (lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
-             (invoke (string-append (assoc-ref (or native-inputs inputs)
-                                               "racket")
-                                    "/bin/racket")
-                     "--config"
-                     (string-append (assoc-ref outputs "out")
-                                    "/etc/racket")
-                     "-l"
-                     "raco"
-                     "setup")
-             #t))
-         (delete 'install))
-       ;; we still don't have these:
-       #:tests? #f))
+     (substitute-keyword-arguments (package-arguments racket-minimal)
+       ((#:configure-flags _ '())
+        #~`("--tethered"
+            "--extra-foreign-lib-search-dirs"
+            ,(format #f "~s"
+                     '(#$@(map (lambda (name)
+                                 (cond
+                                  ((this-package-input name)
+                                   => (cut file-append <> "/lib"))
+                                  (else
+                                   (raise-exception
+                                    (make-exception
+                                     (make-assertion-failure)
+                                     (make-exception-with-message
+                                      "missing input to the 'racket' package")
+                                     (make-exception-with-irritants
+                                      (list name)))))))
+                               '("cairo"
+                                 "fontconfig-minimal" ;; aka fontconfig
+                                 "glib"
+                                 "glu"
+                                 "gmp"
+                                 "gtk+"
+                                 "libjpeg-turbo"
+                                 "libpng"
+                                 "libx11"
+                                 "mesa"
+                                 "mpfr"
+                                 "pango"
+                                 "unixodbc"
+                                 "libedit"))))))
+       ((#:make-flags _ '())
+        #~`("main-distribution"))
+       ((#:phases parent-phases #~%standard-phases)
+        #~(modify-phases #$parent-phases
+            (delete 'unpack)
+            (replace 'build
+              (lambda args
+                (mkdir-p (string-append #$output "/lib/racket/pkgs"))
+                (for-each
+                 (match-lambda
+                   ((name src)
+                    (copy-recursively
+                     src
+                     (string-append #$output "/lib/racket/pkgs/" name))))
+                 '(#$@main-distribution-packages))))))))
     (synopsis "Programmable programming language in the Scheme family")
     (description
      "Racket is a general-purpose programming language in the Scheme family,
@@ -539,82 +224,899 @@  (define dest (string-append pkgs-dir "/" pkg))
 DrRacket IDE, libraries for GUI and web programming, and implementations of
 languages such as Typed Racket, R5RS and R6RS Scheme, Algol 60, and Datalog.")))
 
-
-(define extend-layer
+(define make-installation-layer.rkt
   (scheme-file
-   "extend-layer.rkt"
+   "make-installation-layer.rkt"
    `(module
-     extend-layer racket/base
+     make-installation-layer racket/base
      (require racket/cmdline
               racket/match
               racket/file
+              racket/port
               racket/list
               racket/pretty)
-     (define config-file-pth
-       "etc/racket/config.rktd")
      (define (build-path-string . args)
        (path->string (apply build-path args)))
      (define rx:racket
        ;; Guile's reader doesn't support #rx"racket"
        (regexp "racket"))
-     (command-line
-      #:args (parent-layer prefix . lib-dir*)
-      (let* ([config
-              (for/fold
-               ([config (file->value (build-path parent-layer
-                                                 config-file-pth))])
-               ([spec (in-list
-                       '((lib-dir lib-search-dirs "lib/racket")
-                         (share-dir share-search-dirs "share/racket")
-                         (links-file
-                          links-search-files
-                          "share/racket/links.rktd")
-                         (pkgs-dir pkgs-search-dirs "share/racket/pkgs")
-                         (bin-dir bin-search-dirs "bin")
-                         (man-dir man-search-dirs "share/man")
-                         (doc-dir doc-search-dirs "share/doc/racket")
-                         (include-dir
-                          include-search-dirs
-                          "include/racket")))])
-               (match-define (list main-key search-key pth) spec)
-               (hash-set*
-                config
-                main-key
-                (build-path-string prefix pth)
-                search-key
-                (list* #f
-                       (hash-ref config
-                                 main-key
-                                 (build-path-string parent-layer pth))
-                       (filter values (hash-ref config search-key null)))))]
-             [config
-              (hash-set config
-                        'apps-dir
-                        (build-path-string prefix "share/applications"))]
-             [config
-              ;; place new foreign lib-search-dirs before old
-              ;; foreign dirs, but after Racket layers
-              (let-values
-                  ([(rkt extra)
-                    (partition (lambda (pth)
-                                 (or (not pth)
-                                     (regexp-match? rx:racket pth)))
-                               (hash-ref config 'lib-search-dirs))])
-                (hash-set config
+     (define tethered? #f)
+     (define parent #f)
+     (define extra-foreign-lib-search-dirs '())
+     (define-values [vm-dir prefix]
+       (command-line
+        #:once-each
+        [("--tethered") "create a tethered layer"
+         (set! tethered? #t)]
+        [("--parent") dir "path of parent layer, if any"
+         (set! parent dir)]
+        [("--extra-foreign-lib-search-dirs") dir-list
+         "foreign library directories, as a list of strings in `read` syntax"
+         (set! extra-foreign-lib-search-dirs
+               (call-with-input-string dir-list read))]
+        #:args (vm-dir prefix)
+        (values vm-dir prefix)))
+     (let* ([config
+             (for/fold
+              ([config (file->value
+                        (if parent
+                            (build-path parent "etc/racket/config.rktd")
+                            (build-path vm-dir "etc/config.rktd")))])
+              ([spec
+                (in-list
+                 '((lib-dir lib-search-dirs "lib/racket" "lib")
+                   (share-dir share-search-dirs "share/racket" "share")
+                   (links-file links-search-files
+                               "lib/racket/links.rktd"
+                               "share/links.rktd")
+                   (pkgs-dir pkgs-search-dirs "lib/racket/pkgs" "share/pkgs")
+                   ;; Partial workaround for:
+                   ;; https://github.com/racket/racket/issues/4133
+                   #;(bin-dir bin-search-dirs "bin" "bin")
+                   (bin-dir bin-search-dirs "unused-untethered-bin" "bin")
+                   (man-dir man-search-dirs "share/man" "share/man")
+                   (doc-dir doc-search-dirs "share/doc/racket" "doc")
+                   (include-dir include-search-dirs
+                                "include/racket"
+                                "include")))])
+              (match-define (list main-key search-key pth vm-pth) spec)
+              (hash-set*
+               config
+               main-key
+               (build-path-string prefix pth)
+               search-key
+               (list* #f
+                      (hash-ref config
+                                main-key
+                                (lambda ()
+                                  (if parent
+                                      (build-path-string parent pth)
+                                      (build-path-string vm-dir vm-pth))))
+                      (filter values (hash-ref config search-key null)))))]
+            [config
+             (hash-update config
                           'lib-search-dirs
-                          (append rkt
-                                  lib-dir*
-                                  extra)))]
-             [bin-dir
-              (hash-ref config 'bin-dir)]
-             [config
-              (hash-set* config
-                         'config-tethered-console-bin-dir bin-dir
-                         'config-tethered-gui-bin-dir bin-dir)]
-             [new-config-pth
-              (build-path prefix config-file-pth)])
-        (make-parent-directory* new-config-pth)
-        (call-with-output-file*
-         new-config-pth
-         (lambda (out)
-           (pretty-write config out))))))))
+                          (lambda (dirs)
+                            ;; add after other layers, but before older
+                            ;; foreign lib search directories
+                            (define-values [rkt old-foreign-dirs]
+                              (partition (lambda (pth)
+                                           (or (not pth)
+                                               (regexp-match? rx:racket pth)))
+                                         dirs))
+                            (append rkt
+                                    extra-foreign-lib-search-dirs
+                                    old-foreign-dirs)))]
+            [config
+             (hash-set* config
+                        'apps-dir
+                        (build-path-string prefix "share/applications")
+                        'absolute-installation? #t
+                        ;; Let Guix coexist with other installation
+                        ;; methods without clobbering user-specific packages.
+                        ;; This could be set in various places, but doing
+                        ;; it here is convienient, at least until we support
+                        ;; cross-compilation.
+                        'installation-name
+                        (string-append (version)
+                                       "-guix"
+                                       (match (system-type 'gc)
+                                         ['cgc "-cgc"]
+                                         ;; workaroung Guile reader/printer:
+                                         ['|3m| "-bc"]
+                                         [_ ""])))]
+            [config
+             (cond
+              [tethered?
+               ;; Partial workaround for:
+               ;; https://github.com/racket/racket/issues/4133
+               #;(define bin-dir (hash-ref config 'bin-dir))
+               (define bin-dir (build-path-string prefix "bin"))
+               (hash-set* config
+                          'config-tethered-apps-dir (hash-ref config 'apps-dir)
+                          'config-tethered-console-bin-dir bin-dir
+                          'config-tethered-gui-bin-dir bin-dir)]
+              [else
+               config])])
+       (define new-config-pth
+         (build-path prefix "etc/racket/config.rktd"))
+       (make-parent-directory* new-config-pth)
+       (call-with-output-file*
+        new-config-pth
+        (lambda (out)
+          (pretty-write config out)))))))
+
+(define-public main-distribution-packages
+  (let* ((%racket-version (package-version (racket-vm-for-system)))
+         (%racket-commit (string-append "v" %racket-version)))
+    (append-map
+     (match-lambda
+       ((source . pkgs)
+        (map (match-lambda
+               ((? string? name)
+                (list name (file-append source (string-append "/" name))))
+               ((name ".")
+                (list name source))
+               ((name rel-path)
+                (list name (file-append source (string-append "/" rel-path)))))
+             pkgs)))
+     `((,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/2d")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1zzcz5qyjv7syi41vb8jkxjp1rqgj61zbsdrg0nlc4qy9qsafzgr"))
+           (file-name
+            (git-file-name "racket-2d" %racket-version)))
+        "2d" "2d-doc" "2d-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/algol60")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "09kj6asypmc24n29w0izc9p0q8hpga2hpkchsypfwn5c8zpvihlx"))
+           (file-name
+            (git-file-name "racket-algol60" %racket-version)))
+        ("algol60" "."))
+       (,(package-source (racket-vm-for-system))
+        ("at-exp-lib" "pkgs/at-exp-lib")
+        ("compiler" "pkgs/compiler")
+        ("compiler-lib" "pkgs/compiler-lib")
+        ("net" "pkgs/net")
+        ("net-doc" "pkgs/net-doc")
+        ("net-lib" "pkgs/net-lib")
+        ("racket-doc" "pkgs/racket-doc")
+        ("racket-index" "pkgs/racket-index")
+        ("sandbox-lib" "pkgs/sandbox-lib")
+        ("zo-lib" "pkgs/zo-lib"))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/cext-lib")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "00w38jpv88fpl4pgj6ndnysvn0s21rjvj0xhznay80msan0vc341"))
+           (file-name (git-file-name "racket-cext-lib" %racket-version)))
+        "cext-lib" "dynext-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/class-iop")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "08z57q83cr7wnh6g8ah3hdhmsmf9zp1jfs7yvxv188l3hzvygy5l"))
+           (file-name (git-file-name "racket-class-iop" %racket-version)))
+        "class-iop-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/compatibility")
+                 (commit "37f11132cdad7ef27386b68383d073f275d67c31")))
+           (sha256 (base32
+                    "0bfqwscjpyi325br5pa6g62g9c8lq18a80zp5g3d2qzn3n3mi6x0"))
+           (file-name (git-file-name "racket-compatibility" %racket-version)))
+        "compatibility" "compatibility-doc" "compatibility-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/contract-profile")
+                 (commit "95d980a076126b8e4e4284e912f2a7d9d3ab6860")))
+           (sha256 (base32
+                    "1xm2z8g0dpv5d9h2sg680vx1a8ix9gbsdpxxb8qv1w7akp73paj3"))
+           (file-name
+            (git-file-name "racket-contract-profile" %racket-version)))
+        ("contract-profile" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/data")
+                 (commit "e32d012b394e32e102e8a9adfcc885bb0541ab51")))
+           (sha256 (base32
+                    "10iabgrk9alaggvksnyb0hdq7f1p30pq6pq2bcakvhzpxwiv1f55"))
+           (file-name (git-file-name "racket-data" %racket-version)))
+        "data" "data-doc" "data-enumerate-lib" "data-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/datalog")
+                 (commit "7d160a86451af8298093d07674a2eb0e1a0161a4")))
+           (sha256 (base32
+                    "0n5j5gnqh7g31mvgx19ggl18hirzbvq2r189lbngmnrmbc7b73fp"))
+           (file-name (git-file-name "racket-datalog" %racket-version)))
+        ("datalog" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/db")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1n02ja0yj3mjjhmz0yv04yfhyvrsznbljn8bjviyfxnm4xf9rcc5"))
+           (file-name (git-file-name "racket-db" %racket-version)))
+        "db" "db-doc" "db-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/deinprogramm")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1is6fapgv6rxfjz47nh6qf3kh7y7sjdinakaxqffi46gf1al8prd"))
+           (file-name (git-file-name "racket-deinprogramm" %racket-version)))
+        "deinprogramm" "deinprogramm-signature")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/distributed-places")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1dajpkj9balqcpv6cdk9hwjz592h1vq8rrx5vncariiac4vbdpa0"))
+           (file-name
+            (git-file-name "racket-distributed-places" %racket-version)))
+        "distributed-places" "distributed-places-doc" "distributed-places-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/draw")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1xgjfbh70hqw67z88iqqajg98d04qwbzn6im2wj47rs28jxlm9ly"))
+           (file-name (git-file-name "racket-draw" %racket-version)))
+        "draw" "draw-doc" "draw-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/drracket")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0m3l4an3nq2ycd1h287s1az2v2zprjbzd8if2x7d5r71vaj4i00c"))
+           (file-name (git-file-name "racket-drracket" %racket-version)))
+        "drracket"
+        "drracket-plugin-lib"
+        "drracket-tool"
+        "drracket-tool-doc"
+        "drracket-tool-lib"
+        "drracket-tool-text-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/ds-store")
+                 (commit "949ca63dd00522b3ab8aec2d71c543ece8266872")))
+           (sha256 (base32
+                    "0ajr27kipp4dr1qlisaghsb3h7lhhjwrfw2r79b5myczsa1mp661"))
+           (file-name (git-file-name "racket-ds-store" %racket-version)))
+        "ds-store" "ds-store-doc" "ds-store-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/eli-tester")
+                 (commit "036e07d43a1f478ea1750881d5591d983ce1ffaf")))
+           (sha256 (base32
+                    "0icx6wn14gjm8kdmq1jppqgq87sxkras4qb5xmdr6wigxafhjqyk"))
+           (file-name (git-file-name "racket-eli-tester" %racket-version)))
+        ("eli-tester"  "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/eopl")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1fmiixj6rxsgzwvgva8lvrvv0gl49v2405mp3s0i7ipis5c4n27s"))
+           (file-name (git-file-name "racket-eopl" %racket-version)))
+        ("eopl" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/errortrace")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "14m7rhaxngj36070iw15am434hm438pfgmwjfsiqhsglz4pcxhip"))
+           (file-name (git-file-name "racket-errortrace"
+                                     (package-version (racket-vm-for-system)))))
+        "errortrace" "errortrace-doc" "errortrace-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/expeditor")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "07djzxs6307l51mcsk3yr2g4g47ayxa3878g7sf5xhqdr4hd9vxf"))
+           (file-name (git-file-name "racket-expeditor" %racket-version)))
+        "expeditor" "expeditor-doc" "expeditor-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/frtime")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0ydz2yn8vvv6z7brwlswcyx0f31a6y6d443i89rysfvd2xkhpfd5"))
+           (file-name (git-file-name "racket-frtime" %racket-version)))
+        ("frtime" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/future-visualizer")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1758qq769m0r14xf64sl2ix2l9z340kvapar0j7s5kdg42lmvnhm"))
+           (file-name
+            (git-file-name "racket-future-visualizer" %racket-version)))
+        "future-visualizer" "future-visualizer-pict" "future-visualizer-typed")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/games")
+
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0kpn3izlx1ccd0pj0dnvmnrhny51b85xy418a7psj70lz8j8415d"))
+           (file-name (git-file-name "racket-games" %racket-version)))
+        ("games" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/gui")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1x33jgrx3r32k7hgwr591z3xqv1m2r5nc4km2fnxv0ak2xa0j3gj"))
+           (patches
+            ;; remove in Racket 8.5
+            ;; see https://github.com/racket/racket/issues/4133
+            (search-patches "racket-gui-tethered-launcher-backport.patch"))
+           (file-name (git-file-name "racket-gui" %racket-version)))
+        "gui" "gui-doc" "gui-lib" "tex-table")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/gui-pkg-manager")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1ji9448d723nklqvycwdswj0ni28sabrncag14f9mx47did5myb5"))
+           (file-name
+            (git-file-name "racket-gui-pkg-manager" %racket-version)))
+        "gui-pkg-manager-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/htdp")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0r4ykybcpr10y2db9rlza9pr0xh58nd7ac389mjcxp8g386hgihl"))
+           (file-name (git-file-name "racket-htdp" %racket-version)))
+        "htdp" "htdp-doc" "htdp-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/html")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "18n1jnjgzfknc8nv8dppi85nb8q08gqdwkg6hfjk08x0p00anx2x"))
+           (file-name (git-file-name "racket-html" %racket-version)))
+        "html" "html-doc" "html-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/icons")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1s5a6j11fg3fdr6b7vm2q7q178d7q8b8igy73bs211r27qrd1gg7"))
+           (file-name (git-file-name "racket-icons" %racket-version)))
+        ("icons" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/images")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0rpjxqw34bq5m08kh1ldl1mr7s9z1lyydxxcyzb292kqh9qiqvfl"))
+           (file-name (git-file-name "racket-images" %racket-version)))
+        "images" "images-doc" "images-gui-lib" "images-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/lazy")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "176ylzgbdsbmqknpihaz519afq71pyjkv1h87j5v8jfbpbddyfsf"))
+           (file-name (git-file-name "racket-lazy" %racket-version)))
+        ("lazy" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/macro-debugger")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "14hyrwbkffr61fk44l02xb47bhv5zccw0ymaa9kxld86hvyqhqbm"))
+           (file-name (git-file-name "racket-macro-debugger" %racket-version)))
+        "macro-debugger" "macro-debugger-text-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/main-distribution")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0m2n9s32s8a4a2gn4ywrm9l8jycdm5ayi5w9kh5wchhrrw7qzq7y"))
+           (file-name
+            (git-file-name "racket-main-distribution" %racket-version)))
+        ("main-distribution" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/make")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "10852fj30bz5r46c3d99s37fkgy5yh44gb01j29sf3kxnhi0g2sa"))
+           (file-name (git-file-name "racket-make" %racket-version)))
+        ("make" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/math")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "02sqbnvxvmvslk33b44fx4v93zafcvhva0cx8z21jqbl5wp217ac"))
+           (file-name (git-file-name "racket-math" %racket-version)))
+        "math" "math-doc" "math-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/mysterx")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "11p9jzrafw0hizhl0cs4sxx7rv281185q8hryic2rpk0kzjdyr48"))
+           (file-name (git-file-name "racket-mysterx" %racket-version)))
+        ("mysterx" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/mzcom")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0rc9pfj7gwm5azghqvcibz6si1x5s2v8mr2yngk7ssq9gzfbi6a4"))
+           (file-name (git-file-name "racket-mzcom" %racket-version)))
+        ("mzcom" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/mzscheme")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "192c52zi726h5wjamxrhivjw2waq1im0zpyxhbrkrxknm8x84bs9"))
+           (file-name (git-file-name "racket-mzscheme" %racket-version)))
+        "mzscheme" "mzscheme-doc" "mzscheme-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/RenaissanceBug/racket-cookies")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0k0hifxhywl5c3hjcaiizc098dpyk001d981p572gly116yvjxc1"))
+           (file-name
+            (git-file-name "RenaissanceBug-racket-cookies" %racket-version)))
+        "net-cookies" "net-cookies-doc" "net-cookies-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/stamourv/optimization-coach")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0b27sw48d7rhz0hin88c7rbr9vpg1c23sn82nd4jkmq54h6gasr1"))
+           (file-name
+            (git-file-name "stamourv-optimization-coach" %racket-version)))
+        ("optimization-coach" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/option-contract")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "026b7n5l0c3024nymshz8zp1yhn493rdzgpflzfd52hj7awafqhk"))
+           (file-name
+            (git-file-name "racket-option-contract" %racket-version)))
+        "option-contract" "option-contract-doc" "option-contract-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/parser-tools")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "08pvz4zramirzm3j64hbhjm0mmh5zfy37iv4s3vmq0rj49cr8fl3"))
+           (file-name (git-file-name "racket-parser-tools" %racket-version)))
+        "parser-tools" "parser-tools-doc" "parser-tools-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/pconvert")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "00czi0p399mmyrvxyrs5kniizpkqfxyz2ncxqi2jy79a7wk79pb1"))
+           (file-name (git-file-name "racket-pconvert" %racket-version)))
+        "pconvert-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/pict")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0g1iwdr6qh1xb0crhj96830vjjnbds409xbpqn7j5sh0ksy6vr5x"))
+           (file-name (git-file-name "racket-pict" %racket-version)))
+        "pict" "pict-doc" "pict-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/pict-snip")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "081nwiy4a0n4f7xws16hqbhf0j3kz5alizndi3nnyr3chm4kng6x"))
+           (file-name (git-file-name "racket-pict-snip" %racket-version)))
+        "pict-snip" "pict-snip-doc" "pict-snip-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/picturing-programs")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1g6xr39hx1j03gb3d4dljm3v91xcj2gfpq3dgy5xvplzr6cmmxgr"))
+           (file-name
+            (git-file-name "racket-picturing-programs" %racket-version)))
+        ("picturing-programs" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/plai")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0i983sh0r0zm2ng4j44m5aw9669kh5fhp91bzpc9jm280rfcqvyl"))
+           (file-name (git-file-name "racket-plai" %racket-version)))
+        "plai" "plai-doc" "plai-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/planet")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0r2yqrzrmdjjyr14k6hhlzc5kzrcx3583m1s02mhrcmpfw0s85w9"))
+           (file-name (git-file-name "racket-planet" %racket-version)))
+        "planet" "planet-doc" "planet-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/plot")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "07kq32si34ybcwz8idxxcrzssg8diyrp1nfgkcj0mmvr45321zm7"))
+           (file-name (git-file-name "racket-plot" %racket-version)))
+        "plot" "plot-compat" "plot-doc" "plot-gui-lib" "plot-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/preprocessor")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1p5aid58ifnjy4xl0ysh85cq39k25661v975jrpk182z3k5621mg"))
+           (file-name (git-file-name "racket-preprocessor" %racket-version)))
+        ("preprocessor" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/profile")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "179i86lyby29nywz60l4vnadi02w8b12h7501nm5h5g4pq9jjmbb"))
+           (file-name (git-file-name "racket-profile" %racket-version)))
+        "profile" "profile-doc" "profile-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/Metaxal/quickscript")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "100g3yqhbjdq06b6l6d72ywsw29awgy8crqg33wj7h12xq07nzcr"))
+           (file-name (git-file-name "Metaxal-quickscript" %racket-version)))
+        ("quickscript" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/r5rs")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1g3cysj7z88r38vkzvi8g2fb2hn4yg1fdhy5smxw303jxgl3inp6"))
+           (file-name (git-file-name "racket-r5rs" %racket-version)))
+        "r5rs" "r5rs-doc" "r5rs-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/r6rs")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0b1ymzdp10r0flw2acbidjsh5ma1pm5hy54jss37sxf89z3xbvm4"))
+           (file-name (git-file-name "racket-r6rs" %racket-version)))
+        "r6rs" "r6rs-doc" "r6rs-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/jeapostrophe/racket-cheat")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "06wcj558rzkbl2bwkmikyspya9v1f4iwlzwnwxpkc33h2xapwabr"))
+           (file-name
+            (git-file-name "jeapostrophe-racket-cheat" %racket-version)))
+        ("racket-cheat" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/racklog")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1rgrvwy3kr9b9w5cghsffiv3ly00yfvvzr5xaaw83g1w7yin0mnb"))
+           (file-name (git-file-name "racket-racklog" %racket-version)))
+        ("racklog" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/rackunit")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "057z31rja6h3nabh5b2xgwfrzmlm6h1cv1qcgf3xfy4g2q5dqn5p"))
+           (file-name (git-file-name "racket-rackunit" %racket-version)))
+        "rackunit"
+        "rackunit-doc"
+        "rackunit-gui"
+        "rackunit-lib"
+        "rackunit-plugin-lib"
+        "rackunit-typed"
+        "schemeunit"
+        "testing-util-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/readline")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "13kbcn2wchv82d709mw3r8n37bk8iwq0y4kpvm9dbzx0w2pxkfwn"))
+           (file-name (git-file-name "racket-readline" %racket-version)))
+        "readline" "readline-doc" "readline-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/realm")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0hxcgla08iack54j8v40fj51811chpy66ym2zq76zb52c7kzn0hi"))
+           (file-name (git-file-name "racket-realm" %racket-version)))
+        ("realm" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/redex")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0vlgxbnbgrlihk1hh5zd6hsc4566ldi4q76f87z5vai54dxkwy2f"))
+           (file-name (git-file-name "racket-redex" %racket-version)))
+        "redex"
+        "redex-benchmark"
+        "redex-doc"
+        "redex-examples"
+        "redex-gui-lib"
+        "redex-lib"
+        "redex-pict-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/sasl")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0ibh4wb4gn8pggx6gkv4vk4d6rwzn5nrvjibhvkzhaynf6lhb824"))
+           (file-name (git-file-name "racket-sasl" %racket-version)))
+        "sasl" "sasl-doc" "sasl-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/scheme-lib")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0pcf0y8rp4qyjhaz5ww5sr5diq0wpcdfrrnask7zapyklzx1jx8x"))
+           (file-name (git-file-name "racket-scheme-lib" %racket-version)))
+        ("scheme-lib" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/scribble")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0rgvnsykrxkah6s5fw1vyp9lxsb4z9w6hgwk5j6wbwjp2gsfczbm"))
+           (file-name (git-file-name "racket-scribble" %racket-version)))
+        "scribble"
+        "scribble-doc"
+        "scribble-html-lib"
+        "scribble-lib"
+        "scribble-text-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/serialize-cstruct-lib")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1rq3n1fa7ldjwx3lrh9ybhig7jlsw1crpzyklbzp3xqdw6jymfnz"))
+           (file-name
+            (git-file-name "racket-serialize-cstruct-lib" %racket-version)))
+        ("serialize-cstruct-lib" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/sgl")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0nkymhdyjrwi5h199j4w5zh7y3x3ai42gsiwxzh0hy7yqrqqg9zv"))
+           (file-name (git-file-name "racket-sgl" %racket-version)))
+        ("sgl" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/shell-completion")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "04m144gy2mp4fiq6rcbf12wjr8mws8k9scfhg9lc38vqppp4lxsj"))
+           (file-name
+            (git-file-name "racket-shell-completion" %racket-version)))
+        ("shell-completion" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/simple-tree-text-markup")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "0fyd9gfz6bnv0m1901wv5mnhc05rm8hw9i6ddrqx33hs6qsg2zqr"))
+           (file-name
+            (git-file-name "racket-simple-tree-text-markup" %racket-version)))
+        "simple-tree-text-markup"
+        "simple-tree-text-markup-doc"
+        "simple-tree-text-markup-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/slatex")
+                 (commit "47e1d3e3e33d826bc2b26f9e8998eb235b23a9a5")))
+           (sha256 (base32
+                    "0pkm2isbbdk63slrbsxcql7rr0wdrw5kapw1xq4ps5k8dhlzv8x0"))
+           (file-name (git-file-name "racket-slatex" %racket-version)))
+        ("slatex" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/slideshow")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1znv1i2d0610hhy71q932xy7wka00q3q50in1xfnk8ibg7nzkagm"))
+           (file-name (git-file-name "racket-slideshow" %racket-version)))
+        "slideshow" "slideshow-doc" "slideshow-exe" "slideshow-lib"
+        "slideshow-plugin")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/snip")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "01r9wc5xr3q3n4yyif6j0a37rgdzmpslxn05k13ksik73b3wj6hj"))
+           (file-name (git-file-name "racket-snip" %racket-version)))
+        "snip" "snip-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/typed-racket")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1462kj9yswsxbnw71casylzlvhd7cxrml2v9j7rcsnn9hmrqx4vv"))
+           (file-name (git-file-name "racket-typed-racket" %racket-version)))
+        "source-syntax"
+        "typed-racket"
+        "typed-racket-compatibility"
+        "typed-racket-doc"
+        "typed-racket-lib"
+        "typed-racket-more")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/srfi")
+                 ;; Includes an FSDG fix: return to %racket-commit in 8.5.
+                 ;; See <https://github.com/racket/srfi/pull/15>.
+                 (commit "7243029b135741ce08ae30f877e2f49a2a460b22")))
+           (sha256 (base32
+                    "0aqbcdv2dfc2xnk0h6zfi56p7bpwqji8s88qds3d03hhh9k28gvn"))
+           ;; Use the relevant version for srfi-doc and srfi-lib,
+           ;; since we're using a newer commit than the v8.4 tag.
+           (file-name (git-file-name "racket-srfi" "1.1")))
+        "srfi" "srfi-doc" "srfi-lib" "srfi-lite-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/string-constants")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1qizjq4n0hzdgdcjjpr94464gsywpsk2g9mnvwzqr7dcqbrsfvn6"))
+           (file-name
+            (git-file-name "racket-string-constants" %racket-version)))
+        "string-constants" "string-constants-doc" "string-constants-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/swindle")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "164gdsphjzdl2vv7zxz7dfk9jwax8njpmim6sidm8qz8a8589y67"))
+           (file-name (git-file-name "racket-swindle" %racket-version)))
+        ("swindle" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/syntax-color")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1vf2fc3qvx8a1igi7swsg8gaqhx786sa0vqxd18xhbsidfgb5ywp"))
+           (file-name (git-file-name "racket-syntax-color" %racket-version)))
+        "syntax-color" "syntax-color-doc" "syntax-color-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/trace")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "070ihla5j796hdarn5wxdwn4xj0xnkm50shgh49jy994mribvhia"))
+           (file-name (git-file-name "racket-trace" %racket-version)))
+        ("trace" "."))
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/unix-socket")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "02dfwas5ynbpyz74w9kwb4wgb37y5wys7svrlmir8k0n9ph9vq0y"))
+           (file-name (git-file-name "racket-unix-socket" %racket-version)))
+        "unix-socket" "unix-socket-doc" "unix-socket-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/web-server")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1zgb6jl7zx6258ljs8f3lvryrq5n5zpd71dqzr698m92kw3x2pkn"))
+           (file-name (git-file-name "racket-web-server" %racket-version)))
+        "web-server" "web-server-doc" "web-server-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/wxme")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "1qp5gr9gqsakiq3alw6m4yyv5vw4i3hp4y4nhq8vl2nkjmirvn0b"))
+           (file-name (git-file-name "racket-wxme" %racket-version)))
+        "wxme" "wxme-lib")
+       (,(origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "https://github.com/racket/xrepl")
+                 (commit %racket-commit)))
+           (sha256 (base32
+                    "12zjgsy5zqm3fck3ihg4a70wj56s2cnnjyb4jlfi5nnsfqyrnxg3"))
+           (file-name (git-file-name "racket-xrepl" %racket-version)))
+        "xrepl" "xrepl-doc" "xrepl-lib")))))