diff mbox series

[bug#57050,v2,05/13] gnu: racket: Update to 8.6.

Message ID 5e784e0d35bf5b342bd7df77c4fa137deb942e47.1660215295.git.philip@philipmcgrath.com
State Accepted
Headers show
Series gnu: Update Racket to 8.6. Add Zuo. | 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

Commit Message

Philip McGrath Aug. 11, 2022, 11:08 a.m. UTC
Also, update 'chez-scheme-for-racket' to 9.5.9.2.

* gnu/packages/patches/racket-chez-scheme-bin-sh.patch: Refresh patch.
* gnu/packages/patches/racket-backport-8.6-cross-install.patch,
gnu/packages/patches/racket-backport-8.6-docindex-write.patch,
gnu/packages/patches/racket-backport-8.6-hurd.patch: New patches.
* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/racket.scm (%racket-origin)[patches]: Use them and the
patches for Zuo.
(%racket-version): Update to 8.6.
(zuo)[version]: Refer to '%racket-version'.
[origin]: Use '%racket-origin'.
(racket-vm-cgc)[native-inputs]: Add 'zuo'.
[arguments]<#:make-flags>: Use 'zuo' from 'native-inputs'.
(racket)[inputs]<data, db, deinprogramm, draw, drracket, errortrace,
gui, htdp, math, option-contract, parser-tools, pict, rackunit, realm,
redex, scribble, typed-racket, string-constants, swindle, syntax-color,
web-server>: Update checksums.
* gnu/packages/chez.scm (target-chez-os): Handle Hurd and QNX.
(%chez-features-table): Likewise.
(chez-scheme-for-racket): Update to 9.5.9.2.
[native-inputs]: Add 'zuo'.
[arguments]<#:out-of-source?>: Use out-of-source build.
<#:tests?>: Skip them due to ongoing problems.
<#:configure-flags>: Add '--install-csug=' and '--installreleasenotes='.
<#:make-flags>: Use 'zuo' from 'native-inputs'. Supply 'STEXLIB=' here,
rather than in a phase.
<#:phases>: Replace 'install-docs' using new 'make' target.
---
 gnu/packages/chez.scm                         |  52 +-
 .../racket-backport-8.6-cross-install.patch   |  32 +
 .../racket-backport-8.6-docindex-write.patch  |  36 ++
 .../patches/racket-backport-8.6-hurd.patch    | 609 ++++++++++++++++++
 .../patches/racket-chez-scheme-bin-sh.patch   |  16 +-
 gnu/packages/racket.scm                       | 121 ++--
 6 files changed, 794 insertions(+), 72 deletions(-)
 create mode 100644 gnu/packages/patches/racket-backport-8.6-cross-install.patch
 create mode 100644 gnu/packages/patches/racket-backport-8.6-docindex-write.patch
 create mode 100644 gnu/packages/patches/racket-backport-8.6-hurd.patch

Comments

Liliana Marie Prikler Aug. 11, 2022, 11:44 a.m. UTC | #1
Am Donnerstag, dem 11.08.2022 um 07:08 -0400 schrieb Philip McGrath:
> Also, update 'chez-scheme-for-racket' to 9.5.9.2.
As with Zuo, can this be split into a separate patch?  If not, why does
it get mentioned here as something noteworthy rather than just being
part of the ChangeLog?

> [...]
> @@ -448,18 +456,52 @@ (define-public chez-scheme-for-racket
>         (delete "libx11" "util-linux:lib")))
>      (native-inputs
>       (modify-inputs (package-native-inputs chez-scheme)
> +       (append zuo)
>         (replace "chez-scheme-bootstrap-bootfiles"
>           chez-scheme-for-racket-bootstrap-bootfiles)))
Prefer prepend over append.

>      (arguments
>       (substitute-keyword-arguments (package-arguments chez-scheme)
> +       ((#:out-of-source? _ #f)
> +        #t)
> +       ((#:tests? _ #t)
> +        ;; FIXME: There have been some flaky test failures. Some have
> been
> +        ;; fixed upstream post-release but have proven non-trivial to
> +        ;; backport; at least one issue remains. Re-enable tests once
> +        ;; https://github.com/racket/racket/issues/4359 is fixed.
> +        #f)
Rather than skipping tests altogether, skip just the flaky ones.

> @@ -130,12 +132,12 @@ (define-module (gnu packages racket)
>  ;; output. The function 'racket-vm-for-system' returns the
> recomended Racket
>  ;; VM package for a given system.
>  ;;
> -;; The file 'racket.scm' builds on these packages to define 'racket-
> minimal'
> -;; and 'racket' packages. These use Racket's support for ``layered
> -;; installations'', which allow an immutable base layer to be
> extended with
> -;; additional packages. They use the layer configuration directly
> provide
> -;; ready-to-install FHS-like trees, rather than relying on the built
> in
> -;; ``Unix-style install'' mechanism.
> +;; We then define the packages 'racket-minimal' and
> +;; 'racket'. These use Racket's support for ``layered
> installations'', which
> +;; allow an immutable base layer to be extended with additional
> packages.
> +;; They use the layer configuration directly provide ready-to-
> install FHS-like
> +;; trees, rather than relying on the built in ``Unix-style install''
> +;; mechanism.
>  ;;
>  ;; Bootstrapping Racket:
>  ;; ---------------------
This is a leftover from 8.6, but do the "FHS-like" installations
actually adhere to the FHS or just to the bit that says "opt means we
can do whatever we want 😎️"?

> @@ -178,16 +180,18 @@ (define-module (gnu packages racket)
>  ;; 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.
> +;; as of Racket 7.0. See also
> <https://racket.discourse.group/t/951/4>.
>  ;;
>  ;; 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:
> +;; Zuo is notably *not* a problem for bootstrapping. The
> implementation is a
> +;; single hand-written C file designed to build with just `cc -o zuo
> zuo.c`,
> +;; even with very old or limited compilers. (We use the Autoconf
> support for
> +;; convienience.)
> +;;
> +;; CODE:
Is that something that needs be mentioned?

As always, Racket contains a gazillion of updated hashes that I will
simply trust you on until a build fails.

Cheers
Philip McGrath Aug. 11, 2022, 10:40 p.m. UTC | #2
Hi,

On Thu, Aug 11, 2022, at 7:44 AM, Liliana Marie Prikler wrote:
> Am Donnerstag, dem 11.08.2022 um 07:08 -0400 schrieb Philip McGrath:
>> Also, update 'chez-scheme-for-racket' to 9.5.9.2.
> As with Zuo, can this be split into a separate patch?  If not, why does
> it get mentioned here as something noteworthy rather than just being
> part of the ChangeLog?
>

This absolutely should not be split into more patches. While I split out Zuo as you requested, I continue to believe that it was better as a single patch.

More broadly, I hope to put together a 'racket-build-system' before the 8.7 release. Whenever that happens, it will mean turning the inputs of the 'racket' and 'racket-minimal' packages into, last I counted, 203 additional packages. I think it would be bad for everyone—patch writers, patch reviewers, users, and people reading the history later—to break Racket releases into a deluge of little patches, many of which would leave the Racket universe as a whole in states no one had ever built or tested, because Racket has combinations of technical and social mechanisms to make certain potentially problematic states difficult to fall into.

A Racket release is an update to a family of packages that are developed and released together. Like a TeX Live update (cf. ee25e3fcab9d2e24c2826b771b52d797c152193b) or the KDE Frameworks libraries (cf. 9d3965edca29f80667374da45214cc6f22a85be4), the contents of a Racket release should be updated together. I wouldn't insist on one commit in all imaginable circumstances, but I think it should be the norm. That's all the more true of Racket components that share a canonical Git repository, for which Racket tools take steps to warn you if not fail if you have mismatched versions.

I also want to emphasize that splitting up patches is not free. Splitting/rebasing v2 of this series took hours of work. Even specifically in splitting off Zuo, I made a (trivial) error in my first version of this particular patch and had to amend the commit and rebuild. Splitting this any further would get farther away both from how I actually wrote and tested this patch series over the past four months and from the way Racket is developed and released. It would take a non-negligible amount of effort, all to produce a result that I believe would be worse.

I mention the version number for 'chez-scheme-for-racket' because it shows up relatively prominently in Guix tooling and even e.g. in the path of the package documentation. I don't know why it would be a problem to do so, but I would vastly prefer to remove the mention than to split the patch, if it really has to be a choice. The Racket release notes don't mention the corresponding version of Chez Scheme.

>> [...]
>> @@ -448,18 +456,52 @@ (define-public chez-scheme-for-racket
>>         (delete "libx11" "util-linux:lib")))
>>      (native-inputs
>>       (modify-inputs (package-native-inputs chez-scheme)
>> +       (append zuo)
>>         (replace "chez-scheme-bootstrap-bootfiles"
>>           chez-scheme-for-racket-bootstrap-bootfiles)))
> Prefer prepend over append.
>

Why?

>>      (arguments
>>       (substitute-keyword-arguments (package-arguments chez-scheme)
>> +       ((#:out-of-source? _ #f)
>> +        #t)
>> +       ((#:tests? _ #t)
>> +        ;; FIXME: There have been some flaky test failures. Some have
>> been
>> +        ;; fixed upstream post-release but have proven non-trivial to
>> +        ;; backport; at least one issue remains. Re-enable tests once
>> +        ;; https://github.com/racket/racket/issues/4359 is fixed.
>> +        #f)
> Rather than skipping tests altogether, skip just the flaky ones.
>

If I knew how to do that, I absolutely would. Well, short of making the `process` function silently fail to run `/bin/sh` again, maybe. If you look at the linked issue, you'll see that I've been chasing down failures for the last month. For a while I had cherry-picked 153ff9acb7ad63717a50bb26cd5aaa053870c666, which fixed the only issue with the implementation (a race condition in one mode of the garbage collector), but it didn't seem worth carrying the patch when things were still failing. The other issues seem to be problems with running the test suite. Probably they appeared now because we hadn't actually been running as much of it as we seemed to be. So far, I haven't had failures building with current master, but there aren't any commits touching anything obviously related, and Unicode 14 and grapheme cluster support have landed since the release branch, so it wouldn't be reasonable to just sweep in all the changes indiscriminately. Further, it's at least possible that I may just have been winning the race recently and that the actual problem might still be there. The Chez test suite takes an hour to run (maybe more), and I haven't been able to reproduce the failures outside of Guix, so it's not exactly rapid iteration. All in all, I don't know any change to make other than turning off tests that I can feel confident will work reliably for Guix users.

For what it's worth, difficulty running the Chez tests is not unique to Guix. In the course of adding Zuo, Matthew Flatt commented, "After this conversion, I was able to run the Chez Scheme test suite on Windows for the first time; it must have been possible before, but I never quite got the right tools installed in the right way to make it work." [1] AFAICT Debian skips the Chez test suite unless it is specifically requested [2]: I don't know why, maybe just because it takes so long.

[1]: https://github.com/racket/racket/pull/4179#issuecomment-1094137092
[2]: https://salsa.debian.org/scheme-team/chezscheme/-/blob/fbfa9c35db184f5b22ac6c0058d754e1a45f5f68/debian/rules#L66-69

>> @@ -130,12 +132,12 @@ (define-module (gnu packages racket)
>>  ;; output. The function 'racket-vm-for-system' returns the
>> recomended Racket
>>  ;; VM package for a given system.
>>  ;;
>> -;; The file 'racket.scm' builds on these packages to define 'racket-
>> minimal'
>> -;; and 'racket' packages. These use Racket's support for ``layered
>> -;; installations'', which allow an immutable base layer to be
>> extended with
>> -;; additional packages. They use the layer configuration directly
>> provide
>> -;; ready-to-install FHS-like trees, rather than relying on the built
>> in
>> -;; ``Unix-style install'' mechanism.
>> +;; We then define the packages 'racket-minimal' and
>> +;; 'racket'. These use Racket's support for ``layered
>> installations'', which
>> +;; allow an immutable base layer to be extended with additional
>> packages.
>> +;; They use the layer configuration directly provide ready-to-
>> install FHS-like
>> +;; trees, rather than relying on the built in ``Unix-style install''
>> +;; mechanism.
>>  ;;
>>  ;; Bootstrapping Racket:
>>  ;; ---------------------
> This is a leftover from 8.6, but do the "FHS-like" installations
> actually adhere to the FHS or just to the bit that says "opt means we
> can do whatever we want 😎️"?
>

The 'racket' and 'racket-minimal' packages follow FHS. (Pedantically, because compiled Racket code may or may not be architecture specific, and used to always be architecture-independent, some configuration modes put things in "share" that belong in "lib", but the current upstream "Unix-style" defaults and out packages do not do that.)

Here's a comparison of the hierarchy of our non-VM Racket packages vs. an in-place Racket installation, with the bracketed numbers indicating how the two match up:

/gnu/store/xyz-racket-8.5/
├── bin/ [1]
├── etc/
│   └── racket/
│       └── config.rktd [2]
├── lib/
│   └── racket/ [3]
│       ├── links.rktd
│       ├── mans.rktd
│       └── pkgs/ [4]
└── share/
    ├── applications/ [5]
    │       └── drracket.desktop
    ├── doc/
    │       └── racket/ [6]
    │           └── index.html
    ├── man/ [7]
    │       └── man1/
    │           └── racket.1.gz
    └── racket/ [8]
             └── infocache.rktd

/gnu/store/xyz-racket-vm-cs-8.5/opt/racket-vm/
├── bin/ [1]
├── collects/ [would be share/racket/collects, but not duplicated in layers]
├── doc/ [6]
├── etc/
│   └── config.rktd [2]
├── include/
│   ├── chezscheme.h
│   ├── racketcsboot.h
│   └── racketcs.h
├── lib/ [3]
│   ├── libracketcs.a
│   ├── petite.boot
│   ├── racket.boot
│   └── scheme.boot
├── man/ [7]
│   └── man1/
└── share/ [8]
    ├── applications/ [5]
    └── pkgs/ [4]


>>  ;;
>> -;; Code:
>> +;; Zuo is notably *not* a problem for bootstrapping. The
>> implementation is a
>> +;; single hand-written C file designed to build with just `cc -o zuo
>> zuo.c`,
>> +;; even with very old or limited compilers. (We use the Autoconf
>> support for
>> +;; convienience.)
>> +;;
>> +;; CODE:
> Is that something that needs be mentioned?
>

Some people have asked whether the Zuo implementation does or should share things with Racket and/or Chez Scheme. It seemed worth noting that it intentionally does not, for the sake of bootstrapping.

-Philip
Liliana Marie Prikler Aug. 12, 2022, 6:34 a.m. UTC | #3
Am Donnerstag, dem 11.08.2022 um 18:40 -0400 schrieb Philip McGrath:
> Hi,
> 
> On Thu, Aug 11, 2022, at 7:44 AM, Liliana Marie Prikler wrote:
> > Am Donnerstag, dem 11.08.2022 um 07:08 -0400 schrieb Philip
> > McGrath:
> > 
> > > Also, update 'chez-scheme-for-racket' to 9.5.9.2.
> > As with Zuo, can this be split into a separate patch?  If not, why
> > does it get mentioned here as something noteworthy rather than just
> > being part of the ChangeLog?
> > 
> 
> This absolutely should not be split into more patches. While I split
> out Zuo as you requested, I continue to believe that it was better as
> a single patch.
Belief is one thing, but I think you're cherry-picking commits to not
have said beliefs questioned, which imho is a dangerous thing to do.

> More broadly, I hope to put together a 'racket-build-system' before
> the 8.7 release. Whenever that happens, it will mean turning the
> inputs of the 'racket' and 'racket-minimal' packages into, last I
> counted, 203 additional packages.
That's great.  I hope this will also let us unvendor some of racket
itself.

> I think it would be bad for everyone—patch writers, patch reviewers,
> users, and people reading the history later—to break Racket releases
> into a deluge of little patches
Well, first of all that's debatable, second we do have wip branches for
big workloads like gnome, r, and some others, and I think racket would
probably fit into that category.  Thus, users sitting on the main
branch would only observe the "merge wip-racket into master" commit,
whereas reviewers can take their time to observe each package in
isolation.

> combinations of technical and social mechanisms to make certain
> potentially problematic states difficult to fall into.
Just call it a monorepo.

> A Racket release is an update to a family of packages that are
> developed and released together. Like a TeX Live update (cf.
> ee25e3fcab9d2e24c2826b771b52d797c152193b) or the KDE Frameworks
> libraries (cf. 9d3965edca29f80667374da45214cc6f22a85be4), the
> contents of a Racket release should be updated together. I wouldn't
> insist on one commit in all imaginable circumstances, but I think it
> should be the norm. That's all the more true of Racket components
> that share a canonical Git repository, for which Racket tools take
> steps to warn you if not fail if you have mismatched versions.
The difference between the two commits you mention and the one you
provide is that the upgrades to those derived packages mostly come for
free, whereas yours doesn't.  Compare 

> * gnu/packages/kde-frameworks.scm (extra-cmake-modules, attica,
> bluez-qt,
> breeze-icons, kapidox, karchive, kcalendarcore, kcodecs, kconfig,
> kcoreaddons,
> kdbusaddons, kdnssd, kguiaddons, kholidays, ki18n, kidletime,
> kirigami,
> kitemmodels, kitemviews, kplotting, ksyntaxhighlighting,
> kwidgetsaddons,
> kwindowsystem, modemmanager-qt, networkmanager-qt, oxygen-icons,
> prison,
> qqc2-desktop-style, solid, sonnet, threadweaver, kactivities, kauth,
> kcompletion, kcontacts, kcrash, kdoctools, kfilemetadata,
> kimageformats,
> kjobwidgets, knotifications, kpackage, kpty, kunitconversion,
> syndication,
> baloo, kactivities-stats, kbookmarks, kcmutils, kconfigwidgets,
> kdeclarative,
> kded, kdesignerplugin, kdesu, kdewebkit, kemoticons, kglobalaccel,
> kiconthemes, kinit, knewstuff, knotifyconfig ,kparts, kpeople,
> krunner,
> kservice, ktextwidgets, kwallet, kxmlgui, kxmlrpcclient, purpose,
> kde-frameworkintegration, kdelibs4support, khtml, kjs, kjsembed,
> kmediaplayer,
> kross): Update to 5.70.0.
to
> (chez-scheme-for-racket): Update to 9.5.9.2.
> [native-inputs]: Add 'zuo'.
> [arguments]<#:out-of-source?>: Use out-of-source build.
> <#:tests?>: Skip them due to ongoing problems.
> <#:configure-flags>: Add '--install-csug=' and '--
> installreleasenotes='.
> <#:make-flags>: Use 'zuo' from 'native-inputs'. Supply 'STEXLIB='
> here,
> rather than in a phase.
> <#:phases>: Replace 'install-docs' using new 'make' target.

> I also want to emphasize that splitting up patches is not free.
I also want to emphasize that reviewing patches is not free.

> Splitting/rebasing v2 of this series took hours of work. Even
> specifically in splitting off Zuo, I made a (trivial) error in my
> first version of this particular patch and had to amend the commit
> and rebuild. Splitting this any further would get farther away both
> from how I actually wrote and tested this patch series over the past
> four months and from the way Racket is developed and released. It
> would take a non-negligible amount of effort, all to produce a result
> that I believe would be worse.
As someone who's authored larger series myself, I can somewhat
understand your pain.  However, I don't think the development
guidelines of any particular package ought to influence how we do
things in Guix.  Otherwise, we'd have adopted emoji commit messages for
some of them by now.

> I mention the version number for 'chez-scheme-for-racket' because it
> shows up relatively prominently in Guix tooling and even e.g. in the
> path of the package documentation. I don't know why it would be a
> problem to do so, but I would vastly prefer to remove the mention
> than to split the patch, if it really has to be a choice. The Racket
> release notes don't mention the corresponding version of Chez Scheme.
If chez and racket were that tightly coupled, you'd think they go
together without mention, no?  For instance, when upgrading Emacs to
28.1, I don't have to mention all the built-in packages that've been
updated, you get those from the release notes.

However, looking at the ChangeLog above, I don't think these two are
tightly enough coupled to just say that simultaneous upgrades come for
free (as they do with Emacs, but also Renpy, WebkitGTK, and a bunch of
others that I'm not personally involved with).

> > > [...]
> > > @@ -448,18 +456,52 @@ (define-public chez-scheme-for-racket
> > >         (delete "libx11" "util-linux:lib")))
> > >      (native-inputs
> > >       (modify-inputs (package-native-inputs chez-scheme)
> > > +       (append zuo)
> > >         (replace "chez-scheme-bootstrap-bootfiles"
> > >           chez-scheme-for-racket-bootstrap-bootfiles)))
> > Prefer prepend over append.
> > 
> 
> Why?
Prepend is a cons internally, so it's both faster and more natural. 
Alphabetic ordering doesn't matter here and I hope neither do search
paths in your use case.

> > >      (arguments
> > >       (substitute-keyword-arguments (package-arguments chez-
> > > scheme)
> > > +       ((#:out-of-source? _ #f)
> > > +        #t)
> > > +       ((#:tests? _ #t)
> > > +        ;; FIXME: There have been some flaky test failures. Some
> > > have
> > > been
> > > +        ;; fixed upstream post-release but have proven non-
> > > trivial to
> > > +        ;; backport; at least one issue remains. Re-enable tests
> > > once
> > > +        ;; https://github.com/racket/racket/issues/4359 is
> > > fixed.
> > > +        #f)
> > Rather than skipping tests altogether, skip just the flaky ones.
> > 
> 
> If I knew how to do that, I absolutely would. Well, short of making
> the `process` function silently fail to run `/bin/sh` again, maybe.
> If you look at the linked issue, you'll see that I've been chasing
> down failures for the last month. For a while I had cherry-picked
> 153ff9acb7ad63717a50bb26cd5aaa053870c666, which fixed the only issue
> with the implementation (a race condition in one mode of the garbage
> collector), but it didn't seem worth carrying the patch when things
> were still failing. The other issues seem to be problems with running
> the test suite. Probably they appeared now because we hadn't actually
> been running as much of it as we seemed to be. So far, I haven't had
> failures building with current master, but there aren't any commits
> touching anything obviously related, and Unicode 14 and grapheme
> cluster support have landed since the release branch, so it wouldn't
> be reasonable to just sweep in all the changes indiscriminately.
> Further, it's at least possible that I may just have been winning the
> race recently and that the actual problem might still be there. The
> Chez test suite takes an hour to run (maybe more), and I haven't been
> able to reproduce the failures outside of Guix, so it's not exactly
> rapid iteration. All in all, I don't know any change to make other
> than turning off tests that I can feel confident will work reliably
> for Guix users.
There surely must be more than a single test file, no?  The typical way
to do this in autotools would be to specify TESTS="the tests to run",
or to (substitute* "tests/Makefile.am" ((" bad-test") "")).  HTH

> For what it's worth, difficulty running the Chez tests is not unique
> to Guix. In the course of adding Zuo, Matthew Flatt commented, "After
> this conversion, I was able to run the Chez Scheme test suite on
> Windows for the first time; it must have been possible before, but I
> never quite got the right tools installed in the right way to make it
> work." [1] AFAICT Debian skips the Chez test suite unless it is
> specifically requested [2]: I don't know why, maybe just because it
> takes so long.
> 
> [1]:
> https://github.com/racket/racket/pull/4179#issuecomment-1094137092
> [2]:
> https://salsa.debian.org/scheme-team/chezscheme/-/blob/fbfa9c35db184f5b22ac6c0058d754e1a45f5f68/debian/rules#L66-69
That's horrible.

> > > @@ -130,12 +132,12 @@ (define-module (gnu packages racket)
> > >  ;; output. The function 'racket-vm-for-system' returns the
> > > recomended Racket
> > >  ;; VM package for a given system.
> > >  ;;
> > > -;; The file 'racket.scm' builds on these packages to define
> > > 'racket-
> > > minimal'
> > > -;; and 'racket' packages. These use Racket's support for
> > > ``layered
> > > -;; installations'', which allow an immutable base layer to be
> > > extended with
> > > -;; additional packages. They use the layer configuration
> > > directly
> > > provide
> > > -;; ready-to-install FHS-like trees, rather than relying on the
> > > built
> > > in
> > > -;; ``Unix-style install'' mechanism.
> > > +;; We then define the packages 'racket-minimal' and
> > > +;; 'racket'. These use Racket's support for ``layered
> > > installations'', which
> > > +;; allow an immutable base layer to be extended with additional
> > > packages.
> > > +;; They use the layer configuration directly provide ready-to-
> > > install FHS-like
> > > +;; trees, rather than relying on the built in ``Unix-style
> > > install''
> > > +;; mechanism.
> > >  ;;
> > >  ;; Bootstrapping Racket:
> > >  ;; ---------------------
> > This is a leftover from 8.6, but do the "FHS-like" installations
> > actually adhere to the FHS or just to the bit that says "opt means
> > we
> > can do whatever we want 😎️"?
> > 
> 
> The 'racket' and 'racket-minimal' packages follow FHS. (Pedantically,
> because compiled Racket code may or may not be architecture specific,
> and used to always be architecture-independent, some configuration
> modes put things in "share" that belong in "lib", but the current
> upstream "Unix-style" defaults and out packages do not do that.)
> 
> Here's a comparison of the hierarchy of our non-VM Racket packages
> vs. an in-place Racket installation, with the bracketed numbers
> indicating how the two match up:
> 
> /gnu/store/xyz-racket-8.5/
> ├── bin/ [1]
> ├── etc/
> │   └── racket/
> │       └── config.rktd [2]
> ├── lib/
> │   └── racket/ [3]
> │       ├── links.rktd
> │       ├── mans.rktd
> │       └── pkgs/ [4]
> └── share/
>     ├── applications/ [5]
>     │       └── drracket.desktop
>     ├── doc/
>     │       └── racket/ [6]
>     │           └── index.html
>     ├── man/ [7]
>     │       └── man1/
>     │           └── racket.1.gz
>     └── racket/ [8]
>              └── infocache.rktd
> 
> /gnu/store/xyz-racket-vm-cs-8.5/opt/racket-vm/
> ├── bin/ [1]
> ├── collects/ [would be share/racket/collects, but not duplicated in
> layers]
> ├── doc/ [6]
> ├── etc/
> │   └── config.rktd [2]
> ├── include/
> │   ├── chezscheme.h
> │   ├── racketcsboot.h
> │   └── racketcs.h
> ├── lib/ [3]
> │   ├── libracketcs.a
> │   ├── petite.boot
> │   ├── racket.boot
> │   └── scheme.boot
> ├── man/ [7]
> │   └── man1/
> └── share/ [8]
>     ├── applications/ [5]
>     └── pkgs/ [4]
Your [8] seems broken.

But understanding this correctly, we'd have to move vm collects to lib
or share and man+doc to share?  This doesn't look too bad, but I bet
there's some complication with layers.
> 
> > >  ;;
> > > -;; Code:
> > > +;; Zuo is notably *not* a problem for bootstrapping. The
> > > implementation is a
> > > +;; single hand-written C file designed to build with just `cc -o
> > > zuo
> > > zuo.c`,
> > > +;; even with very old or limited compilers. (We use the Autoconf
> > > support for
> > > +;; convienience.)
> > > +;;
> > > +;; CODE:
> > Is that something that needs be mentioned?
> > 
> 
> Some people have asked whether the Zuo implementation does or should
> share things with Racket and/or Chez Scheme. It seemed worth noting
> that it intentionally does not, for the sake of bootstrapping.
In reply to this bug?  In Chez/Racket spaces?  I think the package
description for zuo should make it clear that it can be used for
bootstrapping, so from a Guix side that comment seems superfluous.

Cheers
Efraim Flashner Aug. 22, 2022, 8:41 a.m. UTC | #4
On Thu, Aug 11, 2022 at 07:08:15AM -0400, Philip McGrath wrote:
> Also, update 'chez-scheme-for-racket' to 9.5.9.2.

> -(define %racket-version "8.5") ; Remember to update chez-scheme-for-racket!
> +(define %racket-version "8.6") ; Remember to update chez-scheme-for-racket!
>  (define %zuo-version "1.0") ; defined in racket/src/zuo/zuo.c
>  (define %racket-commit
>    (string-append "v" %racket-version))
> @@ -211,10 +215,15 @@ (define %racket-origin
>            (url "https://github.com/racket/racket")
>            (commit %racket-commit)))
>      (sha256
> -     (base32 "0f9zyhdvbh4xsndrqjzl85j5ziz0rmqi676g9s1lw3h3skq2636h"))
> +     (base32 "1yi36nr7zrdwrnvpmliirxxjz4pyfyhkar6yvk3rapvmg4q2vmnk"))
>      (file-name (git-file-name "racket" %racket-version))

I got a different hash just now, and the tag on GitHub says it's from
6 days ago. It looks like the tagged commit might've changed in the past
week or two.
Philip McGrath Aug. 22, 2022, 6:56 p.m. UTC | #5
On Mon, Aug 22, 2022, at 4:41 AM, Efraim Flashner wrote:
> On Thu, Aug 11, 2022 at 07:08:15AM -0400, Philip McGrath wrote:
>> Also, update 'chez-scheme-for-racket' to 9.5.9.2.
>
>> -(define %racket-version "8.5") ; Remember to update chez-scheme-for-racket!
>> +(define %racket-version "8.6") ; Remember to update chez-scheme-for-racket!
>>  (define %zuo-version "1.0") ; defined in racket/src/zuo/zuo.c
>>  (define %racket-commit
>>    (string-append "v" %racket-version))
>> @@ -211,10 +215,15 @@ (define %racket-origin
>>            (url "https://github.com/racket/racket")
>>            (commit %racket-commit)))
>>      (sha256
>> -     (base32 "0f9zyhdvbh4xsndrqjzl85j5ziz0rmqi676g9s1lw3h3skq2636h"))
>> +     (base32 "1yi36nr7zrdwrnvpmliirxxjz4pyfyhkar6yvk3rapvmg4q2vmnk"))
>>      (file-name (git-file-name "racket" %racket-version))
>
> I got a different hash just now, and the tag on GitHub says it's from
> 6 days ago. It looks like the tagged commit might've changed in the past
> week or two.
>

Thanks for the report. Yes, the tag apparently changed to point to 3c5e37774fa7acd04fb648187e080a3c62a0d4ea instead of 90d2dac7976b6ac0369c267f0adec3f37bd98460. (The change doesn't affect the Guix packages at all.) I've reminded upstream about the problems this causes---it is definitely not Racket's normal practice!---and I'll send a v3 of this series soon.

-Philip
diff mbox series

Patch

diff --git a/gnu/packages/chez.scm b/gnu/packages/chez.scm
index 66098c7a24..dde2c22ca5 100644
--- a/gnu/packages/chez.scm
+++ b/gnu/packages/chez.scm
@@ -116,7 +116,7 @@  (define* (target-chez-os #:optional (system (or (%current-target-system)
    ((target-linux? system)
     "le")
    ((target-hurd? system)
-    #f)
+    "gnu")
    ((target-mingw? system)
     "nt")
    ;; missing (guix utils) predicates
@@ -132,6 +132,8 @@  (define* (target-chez-os #:optional (system (or (%current-target-system)
    ;; Nix says "x86_64-solaris", but accommodate "-solaris2"
    ((string-contains system "solaris")
     "s2")
+   ((string-suffix? "-qnx" system)
+    "qnx")
    ;; unknown
    (else
     #f)))
@@ -168,6 +170,9 @@  (define %chez-features-table
      ("arm32" bootstrap-bootfiles)
      ("arm64" . #f)
      ("ppc32" threads))
+    ;; Hurd
+    ("gnu"
+     ("i3" . #f))
     ;; FreeBSD
     ("fb"
      ("i3" threads) ;; commented out
@@ -193,6 +198,9 @@  (define %chez-features-table
     ("s2"
      ("i3" threads) ;; commented out
      ("a6" threads)) ;; commented out
+    ;; QNX
+    ("qnx"
+     ("i3" . #f))
     ;; Windows
     ("nt"
      ("i3" threads bootstrap-bootfiles)
@@ -437,7 +445,7 @@  (define-public chez-scheme-for-racket
   (package
     (inherit chez-scheme)
     (name "chez-scheme-for-racket")
-    (version "9.5.7.6")
+    (version "9.5.9.2")
     ;; The version should match `(scheme-fork-version-number)`.
     ;; See racket/src/ChezScheme/s/cmacros.ss c. line 360.
     ;; It will always be different than the upstream version!
@@ -448,18 +456,52 @@  (define-public chez-scheme-for-racket
        (delete "libx11" "util-linux:lib")))
     (native-inputs
      (modify-inputs (package-native-inputs chez-scheme)
+       (append zuo)
        (replace "chez-scheme-bootstrap-bootfiles"
          chez-scheme-for-racket-bootstrap-bootfiles)))
     (arguments
      (substitute-keyword-arguments (package-arguments chez-scheme)
+       ((#:out-of-source? _ #f)
+        #t)
+       ((#:tests? _ #t)
+        ;; FIXME: There have been some flaky test failures. Some have been
+        ;; fixed upstream post-release but have proven non-trivial to
+        ;; backport; at least one issue remains. Re-enable tests once
+        ;; https://github.com/racket/racket/issues/4359 is fixed.
+        #f)
        ((#:configure-flags cfg-flags #~'())
-        #~(cons* "--disable-x11"
-                 "--threads" ;; ok to potentially duplicate
-                 #$cfg-flags))
+        #~`("--disable-x11"
+            "--threads" ;; ok to potentially duplicate
+            ,@(let* ((chez+version (strip-store-file-name #$output))
+                     (doc-prefix (assoc-ref %outputs "doc"))
+                     (doc-dir (string-append doc-prefix
+                                             "/share/doc/"
+                                             chez+version)))
+                (list (string-append "--installcsug="
+                                     doc-dir
+                                     "/csug")
+                      (string-append "--installreleasenotes="
+                                     doc-dir
+                                     "/release_notes")))
+            ,@#$cfg-flags))
+       ((#:make-flags mk-flags #~'())
+        #~(cons* (string-append "ZUO="
+                                #+(this-package-native-input "zuo")
+                                "/bin/zuo")
+                 (string-append "STEXLIB="
+                                #+(this-package-native-input "stex")
+                                "/lib/stex")
+                 #$mk-flags))
        ((#:phases those-phases #~%standard-phases)
         #~(let* ((those-phases #$those-phases)
                  (unpack (assoc-ref those-phases 'unpack)))
             (modify-phases those-phases
+              (replace 'install-docs
+                (lambda* (#:key make-flags #:allow-other-keys)
+                  (apply invoke
+                         "make"
+                         "install-docs"
+                         make-flags)))
               (replace 'unpack
                 (lambda args
                   (unpack #:source #$(or (package-source this-package)
diff --git a/gnu/packages/patches/racket-backport-8.6-cross-install.patch b/gnu/packages/patches/racket-backport-8.6-cross-install.patch
new file mode 100644
index 0000000000..4f7849ecc6
--- /dev/null
+++ b/gnu/packages/patches/racket-backport-8.6-cross-install.patch
@@ -0,0 +1,32 @@ 
+From 585215c5c42f7ee0fee05e6a637ab1bc17f5e8e0 Mon Sep 17 00:00:00 2001
+From: Matthew Flatt <mflatt@racket-lang.org>
+Date: Sat, 30 Jul 2022 07:06:55 -0600
+Subject: [PATCH] CS makefiles: fix Unix-style install for cross compilation
+
+Closes #4377
+
+(cherry picked from commit 053be470e7c5454cdf48e934f3254d2d916bbbc5)
+---
+ racket/src/cs/c/build.zuo | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/racket/src/cs/c/build.zuo b/racket/src/cs/c/build.zuo
+index 8d3950bb27..d8b74c509d 100644
+--- a/racket/src/cs/c/build.zuo
++++ b/racket/src/cs/c/build.zuo
+@@ -1016,10 +1016,9 @@
+   (define (setup)
+     (call-with-dest-racket
+      (lambda (bindir dest-racket)
+-       (define copytree-racket (and cross? (config-bootstrap-racket)))
++       (define copytree-racket (and cross? (hash-ref (config-bootstrap-racket) 'racket)))
+        (maybe-copytree config dest-racket copytree-racket at-dir)
+-       (run-raco-setup config dest-racket
+-                       (and cross? (hash-ref (config-bootstrap-racket) 'racket))
++       (run-raco-setup config dest-racket copytree-racket
+                        ;; this can be redundant if it's also supplied via `SETUP_MACHINE_FLAGS`,
+                        ;; but redundant should be ok:
+                        (list "-MCR" (~a (at-dir "compiled") ":")
+-- 
+2.32.0
+
diff --git a/gnu/packages/patches/racket-backport-8.6-docindex-write.patch b/gnu/packages/patches/racket-backport-8.6-docindex-write.patch
new file mode 100644
index 0000000000..abe1984507
--- /dev/null
+++ b/gnu/packages/patches/racket-backport-8.6-docindex-write.patch
@@ -0,0 +1,36 @@ 
+From 8b4d686a62fd66dedfc40ecdcf3698316993d614 Mon Sep 17 00:00:00 2001
+From: Philip McGrath <philip@philipmcgrath.com>
+Date: Sun, 17 Jul 2022 22:51:44 -0400
+Subject: [PATCH] racket-index: set write permission when copying
+ `docindex.sqlite`
+
+Fixes https://github.com/racket/racket/issues/4357
+
+(cherry picked from commit 55b6cbdca1f36a4f37bab1519c1b658717d3cad2)
+---
+ pkgs/racket-index/setup/scribble.rkt | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/pkgs/racket-index/setup/scribble.rkt b/pkgs/racket-index/setup/scribble.rkt
+index 6694f0b793..e27a8fa348 100644
+--- a/pkgs/racket-index/setup/scribble.rkt
++++ b/pkgs/racket-index/setup/scribble.rkt
+@@ -252,7 +252,14 @@
+     (unless (file-exists? db-file)
+       (define-values (base name dir?) (split-path db-file))
+       (make-directory* base)
+-      (when copy-from (copy-file copy-from db-file))
++      (when copy-from
++        (copy-file copy-from db-file)
++        ;; we might not have write permissions for the previous layer:
++        ;; ensure that we do for the new file
++        (define orig-mode (file-or-directory-permissions db-file 'bits))
++        (define writeable-mode (bitwise-ior user-write-bit orig-mode))
++        (unless (= writeable-mode orig-mode)
++          (file-or-directory-permissions db-file writeable-mode)))
+       (doc-db-disconnect
+        (doc-db-file->connection db-file #t))))
+   (when (or (ormap can-build*? main-docs)
+-- 
+2.32.0
+
diff --git a/gnu/packages/patches/racket-backport-8.6-hurd.patch b/gnu/packages/patches/racket-backport-8.6-hurd.patch
new file mode 100644
index 0000000000..d593b01e62
--- /dev/null
+++ b/gnu/packages/patches/racket-backport-8.6-hurd.patch
@@ -0,0 +1,609 @@ 
+From f17b030fa2f902bb3666913d4a3cd6ba9c146d22 Mon Sep 17 00:00:00 2001
+From: Philip McGrath <philip@philipmcgrath.com>
+Date: Wed, 3 Aug 2022 03:13:03 -0400
+Subject: [PATCH 1/3] Chez Scheme: Fix build on GNU/Hurd
+
+Mostly GNU/Hurd should take the same options as GNU/Linux. One
+difference is that the Hurd does not define macros such as `PATH_MAX` or
+`NOFILE`, because it avoids imposing arbitrary limits on such resources.
+This patch provides alternatives for localized uses of those constants,
+but it accepts the pervasive use of `PATH_MAX` in finding bootfiles for
+now. See https://www.gnu.org/software/hurd/hurd/porting/guidelines.html.
+
+(cherry picked from commit 87eee6e2adb8c6bc11e60619c706fa6295096085)
+---
+ racket/src/ChezScheme/README.md    |  1 +
+ racket/src/ChezScheme/c/number.c   | 22 +++++++++----------
+ racket/src/ChezScheme/c/prim5.c    | 35 ++++++++++++++++++++++++++++--
+ racket/src/ChezScheme/c/scheme.c   | 34 +++++++++++++++++------------
+ racket/src/ChezScheme/c/version.h  |  7 ++++--
+ racket/src/ChezScheme/configure    | 17 ++++++++++-----
+ racket/src/ChezScheme/s/cmacros.ss |  1 +
+ racket/src/cs/c/configure          | 14 ++++++++++--
+ racket/src/cs/c/configure.ac       | 14 ++++++++++--
+ racket/src/cs/rumble/system.ss     |  3 +++
+ 10 files changed, 109 insertions(+), 39 deletions(-)
+
+diff --git a/racket/src/ChezScheme/README.md b/racket/src/ChezScheme/README.md
+index a4a11a5eef..25231dd9bb 100644
+--- a/racket/src/ChezScheme/README.md
++++ b/racket/src/ChezScheme/README.md
+@@ -13,6 +13,7 @@ Supported platforms (bytecode interpreter may work for others):
+  * OpenBSD: x86, x86_64, ARMv6, AArch64, PowerPC32
+  * NetBSD: x86, x86_64, ARMv6, AArch64, PowerPC32
+  * Solaris: x86, x86_64
++ * GNU/Hurd: x86
+  * Android: ARMv7, AArch64
+  * iOS: AArch64
+  * WebAssembly via Emscripten (bytecode interpreter only)
+diff --git a/racket/src/ChezScheme/c/number.c b/racket/src/ChezScheme/c/number.c
+index ede38cc626..e2bce0d2d3 100644
+--- a/racket/src/ChezScheme/c/number.c
++++ b/racket/src/ChezScheme/c/number.c
+@@ -1041,15 +1041,15 @@ floating-point operations
+ 
+ #ifdef IEEE_DOUBLE
+ /* exponent stored + 1024, hidden bit to left of decimal point */
+-#define bias 1023
+-#define bitstoright 52
+-#define m1mask 0xf
+-#ifdef WIN32
+-#define hidden_bit 0x10000000000000
+-#else
+-#define hidden_bit 0x10000000000000ULL
+-#endif
+-#ifdef LITTLE_ENDIAN_IEEE_DOUBLE
++# define bias 1023
++# define bitstoright 52
++# define m1mask 0xf
++# ifdef WIN32
++#  define hidden_bit 0x10000000000000
++# else
++#  define hidden_bit 0x10000000000000ULL
++# endif
++# ifdef LITTLE_ENDIAN_IEEE_DOUBLE
+ struct dblflt {
+     UINT m4: 16;
+     UINT m3: 16;
+@@ -1058,7 +1058,7 @@ struct dblflt {
+     UINT e: 11;
+     UINT sign: 1;
+ };
+-#else
++# else
+ struct dblflt {
+     UINT sign: 1;
+     UINT e: 11;
+@@ -1067,7 +1067,7 @@ struct dblflt {
+     UINT m3: 16;
+     UINT m4: 16;
+ };
+-#endif
++# endif
+ #endif
+ 
+ double S_random_double(U32 m1, U32 m2, U32 m3, U32 m4, double scale) {
+diff --git a/racket/src/ChezScheme/c/prim5.c b/racket/src/ChezScheme/c/prim5.c
+index 124d1e049c..82bbf8d687 100644
+--- a/racket/src/ChezScheme/c/prim5.c
++++ b/racket/src/ChezScheme/c/prim5.c
+@@ -23,6 +23,10 @@
+ #include <ctype.h>
+ #include <math.h>
+ 
++#if defined(__GNU__) /* Hurd */
++#include <sys/resource.h>
++#endif
++
+ /* locally defined functions */
+ static INT s_errno(void);
+ static IBOOL s_addr_in_heap(uptr x);
+@@ -58,7 +62,7 @@ static void s_showalloc(IBOOL show_dump, const char *outfn);
+ static ptr s_system(const char *s);
+ static ptr s_process(char *s, IBOOL stderrp);
+ static I32 s_chdir(const char *inpath);
+-#ifdef GETWD
++#if defined(GETWD) || defined(__GNU__) /* Hurd */
+ static char *s_getwd(void);
+ #endif
+ static ptr s_set_code_byte(ptr p, ptr n, ptr x);
+@@ -881,7 +885,18 @@ static ptr s_process(char *s, IBOOL stderrp) {
+         CLOSE(0); if (dup(tofds[0]) != 0) _exit(1);
+         CLOSE(1); if (dup(fromfds[1]) != 1) _exit(1);
+         CLOSE(2); if (dup(stderrp ? errfds[1] : 1) != 2) _exit(1);
++#ifndef __GNU__ /* Hurd */
+         {INT i; for (i = 3; i < NOFILE; i++) (void)CLOSE(i);}
++#else /* __GNU__ Hurd: no NOFILE */
++        {
++          INT i;
++          struct rlimit rlim;
++          getrlimit(RLIMIT_NOFILE, &rlim);
++          for (i = 3; i < rlim.rlim_cur; i++) {
++            (void)CLOSE(i);
++          }
++        }
++#endif /* __GNU__ Hurd */
+         execl("/bin/sh", "/bin/sh", "-c", s, NULL);
+         _exit(1) /* only if execl fails */;
+         /*NOTREACHED*/
+@@ -927,6 +942,22 @@ static I32 s_chdir(const char *inpath) {
+ static char *s_getwd() {
+   return GETWD(TO_VOIDP(&BVIT(S_bytevector(PATH_MAX), 0)));
+ }
++#elif defined(__GNU__) /* Hurd: no PATH_MAX */
++static char *s_getwd() {
++  char *path;
++  size_t len;
++  ptr bv;
++  path = getcwd(NULL, 0);
++  if (NULL == path) {
++    return NULL;
++  } else {
++    len = strlen(path);
++    bv = S_bytevector(len);
++    memcpy(TO_VOIDP(&BVIT(bv, 0)), path, len);
++    free(path);
++    return TO_VOIDP(&BVIT(bv, 0));
++  }
++}
+ #endif /* GETWD */
+ 
+ static ptr s_set_code_byte(ptr p, ptr n, ptr x) {
+@@ -1817,7 +1848,7 @@ void S_prim5_init(void) {
+     Sforeign_symbol("(cs)s_rational", (void *)S_rational);
+     Sforeign_symbol("(cs)sub", (void *)S_sub);
+     Sforeign_symbol("(cs)rem", (void *)S_rem);
+-#ifdef GETWD
++#if defined(GETWD) || defined(__GNU__) /* Hurd */
+     Sforeign_symbol("(cs)s_getwd", (void *)s_getwd);
+ #endif
+     Sforeign_symbol("(cs)s_chdir", (void *)s_chdir);
+diff --git a/racket/src/ChezScheme/c/scheme.c b/racket/src/ChezScheme/c/scheme.c
+index ed5564540b..0c40e3eaf0 100644
+--- a/racket/src/ChezScheme/c/scheme.c
++++ b/racket/src/ChezScheme/c/scheme.c
+@@ -458,6 +458,12 @@ static IBOOL next_path(char *path, const char *name, const char *ext, const char
+ static const char *path_last(const char *path);
+ static char *get_defaultheapdirs(void);
+ 
++#ifdef PATH_MAX
++# define BOOT_PATH_MAX PATH_MAX
++#else /* hack for Hurd: better to remove the restriction */
++# define BOOT_PATH_MAX 4096
++#endif
++
+ static const char *path_last(const char *p) {
+   const char *s;
+ #ifdef WIN32
+@@ -483,7 +489,7 @@ static const char *path_last(const char *p) {
+ 
+ static char *get_defaultheapdirs() {
+   char *result;
+-  wchar_t buf[PATH_MAX];
++  wchar_t buf[BOOT_PATH_MAX];
+   DWORD len = sizeof(buf);
+   if (ERROR_SUCCESS != RegGetValueW(HKEY_LOCAL_MACHINE, L"Software\\Chez Scheme\\csv" VERSION, L"HeapSearchPath", RRF_RT_REG_SZ, NULL, buf, &len))
+     return DEFAULT_HEAP_PATH;
+@@ -512,14 +518,14 @@ static char *get_defaultheapdirs() {
+  * leaving the full path with name affixed in path and *sp / *dsp pointing
+  * past the current entry.  it returns 1 on success and 0 if at the end of
+  * the search path.  path should be a pointer to an unoccupied buffer
+- * PATH_MAX characters long.  either or both of sp/dsp may be empty,
++ * BOOT_PATH_MAX characters long.  either or both of sp/dsp may be empty,
+  * but neither may be null, i.e., (char *)0. */
+ static IBOOL next_path(char *path, const char *name, const char *ext,
+                        const char **sp, const char **dsp) {
+   char *p;
+   const char *s, *t;
+ 
+-#define setp(c) if (p >= path + PATH_MAX) { fprintf(stderr, "search path entry too long\n"); S_abnormal_exit(); } else *p++ = (c)
++#define setp(c) if (p >= path + BOOT_PATH_MAX) { fprintf(stderr, "search path entry too long\n"); S_abnormal_exit(); } else *p++ = (c)
+   for (;;) {
+     s = *sp;
+     p = path;
+@@ -532,10 +538,10 @@ static IBOOL next_path(char *path, const char *name, const char *ext,
+           switch (*s) {
+ #ifdef WIN32
+             case 'x': {
+-              wchar_t exepath[PATH_MAX]; DWORD n;
++              wchar_t exepath[BOOT_PATH_MAX]; DWORD n;
+               s += 1;
+-              n = GetModuleFileNameW(NULL, exepath, PATH_MAX);
+-              if (n == 0 || (n == PATH_MAX && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
++              n = GetModuleFileNameW(NULL, exepath, BOOT_PATH_MAX);
++              if (n == 0 || (n == BOOT_PATH_MAX && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+                 fprintf(stderr, "warning: executable path is too long; ignoring %%x\n");
+               } else {
+                 char *tstart;
+@@ -608,7 +614,7 @@ typedef struct {
+   iptr len; /* 0 => unknown */
+   iptr offset;
+   IBOOL need_check, close_after;
+-  char path[PATH_MAX];
++  char path[BOOT_PATH_MAX];
+ } boot_desc;
+ 
+ #define MAX_BOOT_FILES 10
+@@ -695,14 +701,14 @@ static void finish_dependencies_header(int fd, const char *path, int c) {
+ static IBOOL find_boot(const char *name, const char *ext, IBOOL direct_pathp,
+                        int fd,
+                        IBOOL errorp) {
+-  char pathbuf[PATH_MAX], buf[PATH_MAX];
++  char pathbuf[BOOT_PATH_MAX], buf[BOOT_PATH_MAX];
+   uptr n = 0;
+   INT c;
+   const char *path;
+   char *expandedpath;
+ 
+   if ((fd != -1) || direct_pathp || S_fixedpathp(name)) {
+-    if (strlen(name) >= PATH_MAX) {
++    if (strlen(name) >= BOOT_PATH_MAX) {
+       fprintf(stderr, "boot-file path is too long %s\n", name);
+       S_abnormal_exit();
+     }
+@@ -776,7 +782,7 @@ static IBOOL find_boot(const char *name, const char *ext, IBOOL direct_pathp,
+     if (boot_count == 0) {
+       for (;;) {
+        /* try to load heap or boot file this boot file requires */
+-        if (get_string(fd, buf, PATH_MAX, &c) != 0) {
++        if (get_string(fd, buf, BOOT_PATH_MAX, &c) != 0) {
+           fprintf(stderr, "unexpected end of file on %s\n", path);
+           CLOSE(fd);
+           S_abnormal_exit();
+@@ -796,7 +802,7 @@ static IBOOL find_boot(const char *name, const char *ext, IBOOL direct_pathp,
+           c = get_u8(fd);
+           for (sep = " "; ; sep = "or ") {
+             if (c == ')') break;
+-            (void) get_string(fd, buf, PATH_MAX, &c);
++            (void) get_string(fd, buf, BOOT_PATH_MAX, &c);
+             fprintf(stderr, "%s%s.boot ", sep, buf);
+           }
+           fprintf(stderr, "required by %s\n", path);
+@@ -1090,7 +1096,7 @@ extern void Sregister_boot_file_fd_region(const char *name,
+                                           int close_after) {
+   check_boot_file_state("Sregister_boot_file_fd");
+ 
+-  if (strlen(name) >= PATH_MAX) {
++  if (strlen(name) >= BOOT_PATH_MAX) {
+     fprintf(stderr, "boot-file path is too long %s\n", name);
+     S_abnormal_exit();
+   }
+@@ -1141,14 +1147,14 @@ extern void Sbuild_heap(const char *kernel, void (*custom_init)(void)) {
+     }
+ 
+     name = path_last(kernel);
+-    if (strlen(name) >= PATH_MAX) {
++    if (strlen(name) >= BOOT_PATH_MAX) {
+       fprintf(stderr, "executable name too long: %s\n", name);
+       S_abnormal_exit();
+     }
+ 
+ #ifdef WIN32
+     { /* strip off trailing .exe, if any */
+-      static char buf[PATH_MAX];
++      static char buf[BOOT_PATH_MAX];
+       iptr n;
+ 
+       n = strlen(name) - 4;
+diff --git a/racket/src/ChezScheme/c/version.h b/racket/src/ChezScheme/c/version.h
+index a79d12621b..61751a9fad 100644
+--- a/racket/src/ChezScheme/c/version.h
++++ b/racket/src/ChezScheme/c/version.h
+@@ -80,7 +80,7 @@ FORCEINLINE void store_unaligned_uptr(uptr *addr, uptr val) {
+ /*****************************************/
+ /* Operating systems                     */
+ 
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__GNU__) /* Hurd */
+ #define NOBLOCK O_NONBLOCK
+ #define LOAD_SHARED_OBJECT
+ #define USE_MMAP
+@@ -91,7 +91,10 @@ FORCEINLINE void store_unaligned_uptr(uptr *addr, uptr val) {
+ #define GETPAGESIZE() getpagesize()
+ typedef char *memcpy_t;
+ #define MAKE_NAN(x) { x = 0.0; x = x / x; }
+-#define GETWD(x) getcwd((x),PATH_MAX)
++#ifndef __GNU__ /* Hurd: no PATH_MAX */
++/* n.b. don't test PATH_MAX directly: we have not yet included <limits.h>  */
++# define GETWD(x) getcwd((x),PATH_MAX)
++#endif
+ typedef int tputsputcchar;
+ #ifndef __ANDROID__
+ # define LOCKF
+diff --git a/racket/src/ChezScheme/configure b/racket/src/ChezScheme/configure
+index f64b639c3a..efdb6029cb 100755
+--- a/racket/src/ChezScheme/configure
++++ b/racket/src/ChezScheme/configure
+@@ -102,6 +102,11 @@ case "${CONFIG_UNAME}" in
+     installprefix=/usr
+     installmansuffix=share/man
+     ;;
++  GNU)
++    unixsuffix=gnu # the Hurd
++    installprefix=/usr
++    installmansuffix=share/man
++    ;;
+   QNX)
+     if uname -a | egrep 'x86' > /dev/null 2>&1 ; then
+       m32=i3qnx
+@@ -591,7 +596,7 @@ fi
+ 
+ # Infer flags needed for threads:
+ case "${flagsm}" in
+-  *le|*fb|*ob|*nb)
++  *le|*gnu|*fb|*ob|*nb)
+       threadFlags="-D_REENTRANT -pthread"
+       threadLibs="-lpthread"
+       ;;
+@@ -627,7 +632,7 @@ if [ "$cflagsset" = "no" ] ; then
+     a6*)
+         CFLAGS="-m64 ${optFlags}"
+         ;;
+-    i3le)
++    i3le) # intentionally not including i3gnu, which may not support sse2
+         CFLAGS="-m32 -msse2 -mfpmath=sse ${optFlags}"
+         ;;
+     i3nt)
+@@ -688,7 +693,7 @@ fi
+ # Add automatic linking flags, unless suppressed by --disable-auto-flags
+ if [ "$addflags" = "yes" ] ; then
+   case "${flagsm}" in
+-    *le)
++    *le|*gnu)
+         LDFLAGS="${LDFLAGS} -rdynamic"
+         ;;
+     *fb|*nb)
+@@ -702,7 +707,7 @@ if [ "$addflags" = "yes" ] ; then
+   esac
+ 
+   case "${flagsm}" in
+-    *le)
++    *le|*gnu)
+         LIBS="${LIBS} -lm -ldl ${ncursesLib} -lrt"
+         ;;
+     *fb|*ob)
+@@ -749,7 +754,7 @@ exeSuffix=
+ 
+ # compile flags for c/Mf-unix and mats/Mf-unix
+ case "${flagsmuni}" in
+-    *le)
++    *le|*gnu)
+         mdcflags="-fPIC -shared"
+         ;;
+     *fb|*ob)
+@@ -781,7 +786,7 @@ case "${flagsmuni}" in
+     i3le)
+         mdldflags="-melf_i386"
+         ;;
+-    *le)
++    *le|*gnu)
+         ;;
+     i3nb)
+         mdldflags="-m elf_i386"
+diff --git a/racket/src/ChezScheme/s/cmacros.ss b/racket/src/ChezScheme/s/cmacros.ss
+index ff2b09217b..2e79a4d8de 100644
+--- a/racket/src/ChezScheme/s/cmacros.ss
++++ b/racket/src/ChezScheme/s/cmacros.ss
+@@ -385,6 +385,7 @@
+   i3fb      ti3fb
+   i3ob      ti3ob
+   i3osx     ti3osx
++  i3gnu     ti3gnu
+   a6le      ta6le
+   a6osx     ta6osx
+   a6ob      ta6ob
+diff --git a/racket/src/cs/c/configure b/racket/src/cs/c/configure
+index 454d79e11a..dab545c0b4 100755
+--- a/racket/src/cs/c/configure
++++ b/racket/src/cs/c/configure
+@@ -4449,8 +4449,15 @@ case "$host_os" in
+     ;;
+   irix*)
+     ;;
+-  linux*)
+-    MACH_OS=le
++  linux*|gnu*)
++    case "$host_os" in
++      *linux*)
++        MACH_OS=le
++        ;;
++      *)
++        MACH_OS=gnu # Hurd
++        ;;
++    esac
+     case "$host_os" in
+       *linux-android*)
+         ;;
+@@ -4730,6 +4737,9 @@ if test "${build_os}_${build_cpu}" != "${host_os}_${host_cpu}" ; then
+     linux*)
+       BUILD_OS=le
+       ;;
++    gnu*) # Hurd: must come after linux*
++      BUILD_OS=gnu
++      ;;
+     *mingw*)
+       BUILD_OS=nt
+       ;;
+diff --git a/racket/src/cs/c/configure.ac b/racket/src/cs/c/configure.ac
+index 5bce979c92..43e7307b1b 100644
+--- a/racket/src/cs/c/configure.ac
++++ b/racket/src/cs/c/configure.ac
+@@ -272,8 +272,15 @@ case "$host_os" in
+     ;;
+   irix*)
+     ;;
+-  linux*)
+-    MACH_OS=le
++  linux*|gnu*)
++    case "$host_os" in
++      linux*)
++        MACH_OS=le
++        ;;
++      *)
++        MACH_OS=gnu # Hurd
++        ;;
++    esac
+     case "$host_os" in
+       *linux-android*)
+         ;;
+@@ -466,6 +473,9 @@ if test "${build_os}_${build_cpu}" != "${host_os}_${host_cpu}" ; then
+     linux*)
+       BUILD_OS=le
+       ;;
++    gnu*) # Hurd - must come after linux*
++      BUILD_OS=gnu
++      ;;
+     *mingw*)
+       BUILD_OS=nt
+       ;;
+diff --git a/racket/src/cs/rumble/system.ss b/racket/src/cs/rumble/system.ss
+index 2319cbe7a5..773eb79cf3 100644
+--- a/racket/src/cs/rumble/system.ss
++++ b/racket/src/cs/rumble/system.ss
+@@ -48,6 +48,8 @@
+            arm32le tarm32le arm64le tarm64le
+            ppc32le tppc32le)
+      'linux]
++    [(i3gnu ti3gnu)
++     'gnu-hurd]
+     [(a6fb ta6fb i3fb ti3fb
+            arm32fb tarm32fb arm64fb tarm64fb
+            ppc32fb tppc32fb)
+@@ -85,6 +87,7 @@
+             i3nb ti3nb
+             i3fb ti3fb
+             i3s2 ti3s2
++            i3gnu ti3gnu
+             i3qnx)
+      'i386]
+     [(arm32le tarm32le
+-- 
+2.32.0
+
+
+From 8653294b771c741d320aba31e692b4f0ed0c702f Mon Sep 17 00:00:00 2001
+From: Philip McGrath <philip@philipmcgrath.com>
+Date: Thu, 4 Aug 2022 20:18:09 -0400
+Subject: [PATCH 2/3] BC: Fix build on GNU/Hurd
+
+(cherry picked from commit 5c05496afd6159c2f9cd52e7f23389fdc6b55f43)
+---
+ racket/src/bc/configure    |  2 +-
+ racket/src/bc/configure.ac |  2 +-
+ racket/src/bc/sconfig.h    | 14 +++++++++-----
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/racket/src/bc/configure b/racket/src/bc/configure
+index 4ddb607b37..4ee346014d 100755
+--- a/racket/src/bc/configure
++++ b/racket/src/bc/configure
+@@ -5018,7 +5018,7 @@ case "$host_os" in
+       X_PRE_LIBS=""
+     fi
+     ;;
+-  linux*)
++  linux*,gnu*)
+     LIBS="$LIBS -ldl -lm -lrt -rdynamic"
+     DYN_CFLAGS="-fPIC"
+     curses_portable_link="/usr/lib/${host_cpu}-${host_os}/libncurses.a /usr/lib/${host_cpu}-${host_os}/libtermcap.a"
+diff --git a/racket/src/bc/configure.ac b/racket/src/bc/configure.ac
+index deef8f3077..866851236e 100644
+--- a/racket/src/bc/configure.ac
++++ b/racket/src/bc/configure.ac
+@@ -557,7 +557,7 @@ case "$host_os" in
+       X_PRE_LIBS=""
+     fi
+     ;;
+-  linux*)
++  linux*,gnu*)
+     LIBS="$LIBS -ldl -lm -lrt -rdynamic"
+     DYN_CFLAGS="-fPIC"
+     curses_portable_link="/usr/lib/${host_cpu}-${host_os}/libncurses.a /usr/lib/${host_cpu}-${host_os}/libtermcap.a"
+diff --git a/racket/src/bc/sconfig.h b/racket/src/bc/sconfig.h
+index 01ecb48158..8468942fcd 100644
+--- a/racket/src/bc/sconfig.h
++++ b/racket/src/bc/sconfig.h
+@@ -79,12 +79,14 @@
+ 
+ #endif
+ 
+-  /************** Linux with gcc ****************/
++  /************** Linux (or Hurd) with gcc ****************/
+ 
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__GNU__)
+ 
+ # ifdef __ANDROID__
+ #  define SCHEME_OS "android"
++# elif defined(__GNU__)
++#  define SCHEME_OS "gnu-hurd"
+ # else
+ #  define SCHEME_OS "linux"
+ # endif
+@@ -146,13 +148,15 @@
+ # define USE_IEEE_FP_PREDS
+ # define USE_EXPLICT_FP_FORM_CHECK
+ 
+-# define LINUX_FIND_STACK_BASE
++# define LINUX_FIND_STACK_BASE /* also ok for Hurd */
+ 
+ # define FLAGS_ALREADY_SET
+ 
+ #if defined(__i386__)
+-# define MZ_USE_JIT_I386
+-# define MZ_JIT_USE_MPROTECT
++# ifndef __GNU__ /* Hurd */
++#  define MZ_USE_JIT_I386
++#  define MZ_JIT_USE_MPROTECT
++# endif
+ # ifndef MZ_NO_UNWIND_SUPPORT
+ #  define MZ_USE_DWARF_LIBUNWIND
+ # endif
+-- 
+2.32.0
+
+
+From 1b0cd08557f58506c96f0ddd855bd9051a45a2f1 Mon Sep 17 00:00:00 2001
+From: Philip McGrath <philip@philipmcgrath.com>
+Date: Sat, 6 Aug 2022 22:48:40 -0400
+Subject: [PATCH 3/3] BC: repair configure script
+
+Hopefully this will fix the DrDr failures caused by 5c05496.
+
+Related to https://github.com/racket/racket/pull/4384
+
+(cherry picked from commit c3dd01055ed7589a18136904510fe4db557d6e77)
+---
+ racket/src/bc/configure    | 2 +-
+ racket/src/bc/configure.ac | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/racket/src/bc/configure b/racket/src/bc/configure
+index 4ee346014d..b1c5175b84 100755
+--- a/racket/src/bc/configure
++++ b/racket/src/bc/configure
+@@ -5018,7 +5018,7 @@ case "$host_os" in
+       X_PRE_LIBS=""
+     fi
+     ;;
+-  linux*,gnu*)
++  linux*|gnu*)
+     LIBS="$LIBS -ldl -lm -lrt -rdynamic"
+     DYN_CFLAGS="-fPIC"
+     curses_portable_link="/usr/lib/${host_cpu}-${host_os}/libncurses.a /usr/lib/${host_cpu}-${host_os}/libtermcap.a"
+diff --git a/racket/src/bc/configure.ac b/racket/src/bc/configure.ac
+index 866851236e..ecc3b0b579 100644
+--- a/racket/src/bc/configure.ac
++++ b/racket/src/bc/configure.ac
+@@ -557,7 +557,7 @@ case "$host_os" in
+       X_PRE_LIBS=""
+     fi
+     ;;
+-  linux*,gnu*)
++  linux*|gnu*)
+     LIBS="$LIBS -ldl -lm -lrt -rdynamic"
+     DYN_CFLAGS="-fPIC"
+     curses_portable_link="/usr/lib/${host_cpu}-${host_os}/libncurses.a /usr/lib/${host_cpu}-${host_os}/libtermcap.a"
+-- 
+2.32.0
+
diff --git a/gnu/packages/patches/racket-chez-scheme-bin-sh.patch b/gnu/packages/patches/racket-chez-scheme-bin-sh.patch
index df2eb671b3..69aca3b483 100644
--- a/gnu/packages/patches/racket-chez-scheme-bin-sh.patch
+++ b/gnu/packages/patches/racket-chez-scheme-bin-sh.patch
@@ -1,4 +1,4 @@ 
-From 5f3fc12bf123f30485800960b0493f5dd538d107 Mon Sep 17 00:00:00 2001
+From 988eea0a875d570d8ec155cb0925b4586d36e8d7 Mon Sep 17 00:00:00 2001
 From: Philip McGrath <philip@philipmcgrath.com>
 Date: Thu, 19 May 2022 13:41:56 -0400
 Subject: [PATCH] Chez Scheme: patch s_process for "/bin/sh" on Guix
@@ -22,10 +22,10 @@  on `system` from the C library.
  1 file changed, 19 insertions(+), 1 deletion(-)
 
 diff --git a/racket/src/ChezScheme/c/prim5.c b/racket/src/ChezScheme/c/prim5.c
-index f5e3e345be..9db2989138 100644
+index 82bbf8d687..307c8673a1 100644
 --- a/racket/src/ChezScheme/c/prim5.c
 +++ b/racket/src/ChezScheme/c/prim5.c
-@@ -856,6 +856,22 @@ static ptr s_process(s, stderrp) char *s; IBOOL stderrp; {
+@@ -861,6 +861,22 @@ static ptr s_process(char *s, IBOOL stderrp) {
  
      INT tofds[2], fromfds[2], errfds[2];
      struct sigaction act, oint_act;
@@ -48,10 +48,10 @@  index f5e3e345be..9db2989138 100644
  
      if (pipe(tofds)) S_error("process","cannot open pipes");
      if (pipe(fromfds)) {
-@@ -881,7 +897,9 @@ static ptr s_process(s, stderrp) char *s; IBOOL stderrp; {
-         CLOSE(1); if (dup(fromfds[1]) != 1) _exit(1);
-         CLOSE(2); if (dup(stderrp ? errfds[1] : 1) != 2) _exit(1);
-         {INT i; for (i = 3; i < NOFILE; i++) (void)CLOSE(i);}
+@@ -897,7 +913,9 @@ static ptr s_process(char *s, IBOOL stderrp) {
+           }
+         }
+ #endif /* __GNU__ Hurd */
 -        execl("/bin/sh", "/bin/sh", "-c", s, NULL);
 +        /* BEGIN PATCH for Guix */
 +        execl(guix_sh, guix_sh, "-c", s, NULL);
@@ -60,7 +60,7 @@  index f5e3e345be..9db2989138 100644
          /*NOTREACHED*/
      } else {
 
-base-commit: 9d228d16fb99c274c964e5bef93e97333888769f
+base-commit: 87eee6e2adb8c6bc11e60619c706fa6295096085
 -- 
 2.32.0
 
diff --git a/gnu/packages/racket.scm b/gnu/packages/racket.scm
index 0c8b3b6bb8..31f3394fa3 100644
--- a/gnu/packages/racket.scm
+++ b/gnu/packages/racket.scm
@@ -54,7 +54,7 @@  (define-module (gnu packages racket)
   #:use-module (gnu packages xorg)
   #:use-module ((guix licenses) #:prefix license:))
 
-;; Commentary:
+;; COMMENTARY:
 ;;
 ;; Anatomy of Racket:
 ;; ------------------
@@ -73,14 +73,16 @@  (define-module (gnu packages racket)
 ;;             ├── bc/
 ;;             ├── cs/
 ;;             ├── ChezScheme/
+;;             ├── zuo/
 ;;             └── ...
 ;;
 ;; The 'racket/src/' directory contains the source of the runtime system, core
 ;; compiler, and primitives for the major Racket implementations: this layer
-;; is called the ``Racket VM''. It is basically a normal autotools
-;; project. (Even when Racket VM implementations use components implemented in
-;; Racket, they are compiled in special modes to produce VM primitives.)
-;; (There are or have been experimental Racket VM implementations elsewhere,
+;; is called the ``Racket VM''.  It is basically a normal Autoconf project,
+;; except that the makefiles just run Zuo to do the real work. (Even when
+;; Racket VM implementations use components implemented in Racket, they are
+;; compiled in special modes to produce VM primitives.) (There are or have
+;; been experimental Racket VM implementations elsewhere,
 ;; e.g. <https://github.com/pycket/pycket>.)
 ;;
 ;; The 'racket/collects/' directory contains ``built in'' Racket libraries
@@ -101,10 +103,10 @@  (define-module (gnu packages racket)
 ;;
 ;; The top-level 'Makefile' is more like a directory of scripts: it has
 ;; convienience targets for developing Racket, and it cooperates with the
-;; 'distro-build' package to assemble custom Racket distributions. It is not
-;; part of Racket source distributions: the root of a source distribution is
-;; basically 'racket/src' with some extra package sources and configuration
-;; added.
+;; 'distro-build' package to assemble custom Racket distributions. (Again,
+;; the makefile just delegates to Zuo.) It is not part of Racket source
+;; distributions: the root of a source distribution is basically 'racket/src'
+;; with some extra package sources and configuration added.
 ;;
 ;; A ''minimal Racket'' installation includes two packages: 'base', which is a
 ;; sort of bridge between the current ``built-in'' collections and the package
@@ -130,12 +132,12 @@  (define-module (gnu packages racket)
 ;; output. The function 'racket-vm-for-system' returns the recomended Racket
 ;; VM package for a given system.
 ;;
-;; The file 'racket.scm' builds on these packages to define 'racket-minimal'
-;; and 'racket' packages. These use Racket's support for ``layered
-;; installations'', which allow an immutable base layer to be extended with
-;; additional packages. They use the layer configuration directly provide
-;; ready-to-install FHS-like trees, rather than relying on the built in
-;; ``Unix-style install'' mechanism.
+;; We then define the packages 'racket-minimal' and
+;; 'racket'. These use Racket's support for ``layered installations'', which
+;; allow an immutable base layer to be extended with additional packages.
+;; They use the layer configuration directly provide ready-to-install FHS-like
+;; trees, rather than relying on the built in ``Unix-style install''
+;; mechanism.
 ;;
 ;; Bootstrapping Racket:
 ;; ---------------------
@@ -178,16 +180,18 @@  (define-module (gnu packages racket)
 ;; 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.
+;; as of Racket 7.0. See also <https://racket.discourse.group/t/951/4>.
 ;;
 ;; 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:
+;; Zuo is notably *not* a problem for bootstrapping. The implementation is a
+;; single hand-written C file designed to build with just `cc -o zuo zuo.c`,
+;; even with very old or limited compilers. (We use the Autoconf support for
+;; convienience.)
+;;
+;; CODE:
 
 (define* (racket-vm-for-system #:optional
                                (system (or (%current-target-system)
@@ -200,7 +204,7 @@  (define* (racket-vm-for-system #:optional
       racket-vm-cs
       racket-vm-bc))
 
-(define %racket-version "8.5") ; Remember to update chez-scheme-for-racket!
+(define %racket-version "8.6") ; Remember to update chez-scheme-for-racket!
 (define %zuo-version "1.0") ; defined in racket/src/zuo/zuo.c
 (define %racket-commit
   (string-append "v" %racket-version))
@@ -211,10 +215,15 @@  (define %racket-origin
           (url "https://github.com/racket/racket")
           (commit %racket-commit)))
     (sha256
-     (base32 "0f9zyhdvbh4xsndrqjzl85j5ziz0rmqi676g9s1lw3h3skq2636h"))
+     (base32 "1yi36nr7zrdwrnvpmliirxxjz4pyfyhkar6yvk3rapvmg4q2vmnk"))
     (file-name (git-file-name "racket" %racket-version))
-    (patches (search-patches "racket-chez-scheme-bin-sh.patch"
-                             "racket-rktio-bin-sh.patch"))
+    (patches (search-patches "racket-backport-8.6-cross-install.patch"
+                             "racket-backport-8.6-docindex-write.patch"
+                             "racket-backport-8.6-hurd.patch"
+                             "racket-backport-8.6-zuo.patch"
+                             "racket-chez-scheme-bin-sh.patch"
+                             "racket-rktio-bin-sh.patch"
+                             "racket-zuo-bin-sh.patch"))
     (modules '((guix build utils)))
     (snippet
      #~(begin
@@ -241,21 +250,10 @@  (define-public zuo
       (name "zuo")
       (version (string-append %zuo-version
                               "-racket"
-                              "8.6"
+                              %racket-version
                               (if revision "-guix" "")
                               (or revision "")))
-      (source
-       (origin
-         (inherit %racket-origin)
-         (uri (git-reference
-               (url "https://github.com/racket/racket")
-               (commit "v8.6")))
-         (sha256
-          (base32 "1yi36nr7zrdwrnvpmliirxxjz4pyfyhkar6yvk3rapvmg4q2vmnk"))
-         (patches (append (origin-patches %racket-origin)
-                          (search-patches "racket-backport-8.6-zuo.patch"
-                                          "racket-zuo-bin-sh.patch")))
-         (file-name (git-file-name "racket" "8.6"))))
+      (source %racket-origin)
       (outputs '("out" "debug"))
       (build-system gnu-build-system)
       (inputs (list bash-minimal))
@@ -334,7 +332,8 @@  (define-public racket-vm-cgc
      (inputs (list ncurses ;; <- common to all variants (for #%terminal)
                    bash-minimal ;; <- common to all variants (for `system`)
                    libffi)) ;; <- only for BC variants
-     (native-inputs (list libtool)) ;; <- only for BC variants
+     (native-inputs (list zuo ;; <- for all variants
+                          libtool)) ;; <- only for BC variants
      (outputs '("out" "debug"))
      (build-system gnu-build-system)
      (arguments
@@ -342,6 +341,10 @@  (define-public racket-vm-cgc
        #:configure-flags
        #~(cons "--enable-cgcdefault"
                #$(racket-vm-common-configure-flags))
+       #:make-flags
+       #~(list (string-append "ZUO="
+                              #+(this-package-native-input "zuo")
+                              "/bin/zuo"))
        ;; Tests are in packages like racket-test-core and
        ;; main-distribution-test that aren't part of the main
        ;; distribution.
@@ -701,25 +704,25 @@  (define-public racket
        "contract-profile" (base32 "1xm2z8g0dpv5d9h2sg680vx1a8ix9gbsdpxxb8qv1w7akp73paj3")
        '(("contract-profile" ".")))
       (simple-racket-origin
-       "data" (base32 "10iabgrk9alaggvksnyb0hdq7f1p30pq6pq2bcakvhzpxwiv1f55")
+       "data" (base32 "08sj4m0g0cp7gwb0nq90m770f0c21b7ydif7nljc8rxmcdprfisc")
        '("data" "data-doc" "data-enumerate-lib" "data-lib"))
       (simple-racket-origin
        "datalog" (base32 "0nf6cy4djpyhfvgpa6yn72apbz9s83gp0qg95pzjd0az4v6qwq1s")
        '(("datalog" ".")))
       (simple-racket-origin
-       "db" (base32 "1n02ja0yj3mjjhmz0yv04yfhyvrsznbljn8bjviyfxnm4xf9rcc5")
+       "db" (base32 "0jzsbfcdm3xj0g8xxw3ky2swrhiqqsq2aqa3r08m641dc981dmjq")
        '("db" "db-doc" "db-lib"))
       (simple-racket-origin
-       "deinprogramm" (base32 "0g8flr1qg3bcyhdinqhs4w7dyisaqyailbxrjgd2a7zlqmdyicfr")
+       "deinprogramm" (base32 "16ncs3ms3mmdavbk0mkhm2qi62vyyif9cch3sn1y64pij489x34v")
        '("deinprogramm" "deinprogramm-signature"))
       (simple-racket-origin
        "distributed-places" (base32 "1dajpkj9balqcpv6cdk9hwjz592h1vq8rrx5vncariiac4vbdpa0")
        '("distributed-places" "distributed-places-doc" "distributed-places-lib"))
       (simple-racket-origin
-       "draw" (base32 "1fpk85rs2crd63bxnmwj2pysisd62pxcqaip01si67dv1ri8ff92")
+       "draw" (base32 "00rq5y4ba6z1d6jh76kl8rwpxrlqqp81a875zyhk3k81i42635sm")
        '("draw" "draw-doc" "draw-lib"))
       (simple-racket-origin
-       "drracket" (base32 "0dipnz92c63zxys9z1kl5215rm7arc35g9r8bs8ivp96p75mljnz")
+       "drracket" (base32 "05d7wssi0ry13alb5hl3llpsg30dd0jhyfv5nb1nmg189fn42q62")
        '("drracket"
          "drracket-plugin-lib"
          "drracket-tool"
@@ -736,7 +739,7 @@  (define-public racket
        "eopl" (base32 "1fmiixj6rxsgzwvgva8lvrvv0gl49v2405mp3s0i7ipis5c4n27s")
        '(("eopl" ".")))
       (simple-racket-origin
-       "errortrace" (base32 "14m7rhaxngj36070iw15am434hm438pfgmwjfsiqhsglz4pcxhip")
+       "errortrace" (base32 "0r5630bb2d6hk0fbi95fmyfja54nnwdfcj2zjba124pp6xkjyavx")
        '("errortrace" "errortrace-doc" "errortrace-lib"))
       (simple-racket-origin
        "expeditor" (base32 "0mjfwb4wzwsg5xj3k6cmik0va432n56rp5h7rxx1c2yy3prh1j7q")
@@ -753,13 +756,13 @@  (define-public racket
        "games" (base32 "0kpn3izlx1ccd0pj0dnvmnrhny51b85xy418a7psj70lz8j8415d")
        '(("games" ".")))
       (simple-racket-origin
-       "gui" (base32 "0r3ck4gxdhnzr1a1fi0f1i7gwfip7akq10qgcxza66pp57hnl0wx")
+       "gui" (base32 "18pcnx3wi8f32i2frm8bn9pi08n4y3c5jgqs4gy21w6f84dv401w")
        '("gui" "gui-doc" "gui-lib" "tex-table"))
       (simple-racket-origin
        "gui-pkg-manager" (base32 "1ji9448d723nklqvycwdswj0ni28sabrncag14f9mx47did5myb5")
        '("gui-pkg-manager-lib"))
       (simple-racket-origin
-       "htdp" (base32 "19xqixrqbwdxph17w9jga19008j88harb5wgml4hpqj3x0apx9g3")
+       "htdp" (base32 "173xy6ks55npvwn6cykjs41s9qfb70hc2gfjiqvw91hdsbjykwir")
        '("htdp" "htdp-doc" "htdp-lib"))
       (simple-racket-origin
        "html" (base32 "18n1jnjgzfknc8nv8dppi85nb8q08gqdwkg6hfjk08x0p00anx2x")
@@ -783,7 +786,7 @@  (define-public racket
        "make" (base32 "10852fj30bz5r46c3d99s37fkgy5yh44gb01j29sf3kxnhi0g2sa")
        '(("make" ".")))
       (simple-racket-origin
-       "math" (base32 "02sqbnvxvmvslk33b44fx4v93zafcvhva0cx8z21jqbl5wp217ac")
+       "math" (base32 "00ld38in5jfshs1q4zf07w84cyv4yjr40kmw30pyd5wqgs2zq9ai")
        '("math" "math-doc" "math-lib"))
       (simple-racket-origin
        "mysterx" (base32 "11p9jzrafw0hizhl0cs4sxx7rv281185q8hryic2rpk0kzjdyr48")
@@ -818,16 +821,16 @@  (define-public racket
           (git-file-name "stamourv-optimization-coach" %racket-version)))
        '(("optimization-coach" ".")))
       (simple-racket-origin
-       "option-contract" (base32 "026b7n5l0c3024nymshz8zp1yhn493rdzgpflzfd52hj7awafqhk")
+       "option-contract" (base32 "07cncg9pi15cm19k7rzv54vx83wq7y42i2m6bgzaqja1h8vnj2ww")
        '("option-contract" "option-contract-doc" "option-contract-lib"))
       (simple-racket-origin
-       "parser-tools" (base32 "08pvz4zramirzm3j64hbhjm0mmh5zfy37iv4s3vmq0rj49cr8fl3")
+       "parser-tools" (base32 "04ycihliikh0c47ivp09gayxiql9d9wpl216czic19cj6f7rmcnj")
        '("parser-tools" "parser-tools-doc" "parser-tools-lib"))
       (simple-racket-origin
        "pconvert" (base32 "00czi0p399mmyrvxyrs5kniizpkqfxyz2ncxqi2jy79a7wk79pb1")
        '("pconvert-lib"))
       (simple-racket-origin
-       "pict" (base32 "0v7a3l77swsbh80mnb9rakdwgw7s66ji0mall7qcqfwyg1b4zmlv")
+       "pict" (base32 "1n0v7kynkiin1v8igs9m8k8vfwjn5cswanhq2imp1pxzjvdyq6sx")
        '("pict" "pict-doc" "pict-lib"))
       (simple-racket-origin
        "pict-snip" (base32 "081nwiy4a0n4f7xws16hqbhf0j3kz5alizndi3nnyr3chm4kng6x")
@@ -881,7 +884,7 @@  (define-public racket
        "racklog" (base32 "0fbq0fpfb3l6h7h772dvkmlzlk2dnq5f8296xx1qxhhwypibqzr9")
        '(("racklog" ".")))
       (simple-racket-origin
-       "rackunit" (base32 "0vfwcddzrgrdv5awjka7m0jzqhqvfc5wlkih83a670y96496a83n")
+       "rackunit" (base32 "1gpz9sgnm8hrc0cb3rii0wzbcwp9mgy5k1amnxidy7gyzl7prn81")
        '("rackunit"
          "rackunit-doc"
          "rackunit-gui"
@@ -894,10 +897,10 @@  (define-public racket
        "readline" (base32 "13kbcn2wchv82d709mw3r8n37bk8iwq0y4kpvm9dbzx0w2pxkfwn")
        '("readline" "readline-doc" "readline-lib"))
       (simple-racket-origin
-       "realm" (base32 "0hxcgla08iack54j8v40fj51811chpy66ym2zq76zb52c7kzn0hi")
+       "realm" (base32 "0rlvwyd6rpyl0zda4a5p8dp346fvqzc8555dgfnrhliymkxb6x4g")
        '(("realm" ".")))
       (simple-racket-origin
-       "redex" (base32 "18rn8ddsqh1s7hdlb2cb9wxln63bz0wysjssaf9v92r712xnnv8i")
+       "redex" (base32 "06dhyqmin0qdm6b6sdvgzpy3pa4svlw42ld9k2h1dxcr852czil7")
        '("redex"
          "redex-benchmark"
          "redex-doc"
@@ -912,7 +915,7 @@  (define-public racket
        "scheme-lib" (base32 "0pcf0y8rp4qyjhaz5ww5sr5diq0wpcdfrrnask7zapyklzx1jx8x")
        '(("scheme-lib" ".")))
       (simple-racket-origin
-       "scribble" (base32 "0fbb7xgz95y90247hfc1a19v7ry8m6blvv4y8irdgzhjvik70zb3")
+       "scribble" (base32 "0a11kvcnzp04mp4xxq68rkl09jv00hv81k2nmwkmwpfx9b2acvd3")
        '("scribble"
          "scribble-doc"
          "scribble-html-lib"
@@ -944,7 +947,7 @@  (define-public racket
        "snip" (base32 "01r9wc5xr3q3n4yyif6j0a37rgdzmpslxn05k13ksik73b3wj6hj")
        '("snip" "snip-lib"))
       (simple-racket-origin
-       "typed-racket" (base32 "0z6bagp6qiw0i3slhvq035y5hqgq664xw3bdlvdayad0bgbg0mdc")
+       "typed-racket" (base32 "03wsz647fi58brbg33fw1xavp100gzfvngdy8bk7bdc0jfg8a18l")
        '("source-syntax"
          "typed-racket"
          "typed-racket-compatibility"
@@ -955,13 +958,13 @@  (define-public racket
        "srfi" (base32 "0aqbcdv2dfc2xnk0h6zfi56p7bpwqji8s88qds3d03hhh9k28gvn")
        '("srfi" "srfi-doc" "srfi-lib" "srfi-lite-lib"))
       (simple-racket-origin
-       "string-constants" (base32 "0b1ji31pv6bjb0a2bh9sqp5abvf91gn2rai8r4c4nkar1fzfwfac")
+       "string-constants" (base32 "1kg3vxq2hcd0vl76brgpzdwbrb65a4nrrkc6hj4az5lfbbdvqz47")
        '("string-constants" "string-constants-doc" "string-constants-lib"))
       (simple-racket-origin
-       "swindle" (base32 "164gdsphjzdl2vv7zxz7dfk9jwax8njpmim6sidm8qz8a8589y67")
+       "swindle" (base32 "03n9ymjhrw45h7hxkw4nq8nidnvs9mfzb4228s2cjfaqbgqxvsyb")
        '(("swindle" ".")))
       (simple-racket-origin
-       "syntax-color" (base32 "17lb2403ymz6sflw4vs3gsh2y7kgsf0gn8sncsxjhi16rpj3a9vm")
+       "syntax-color" (base32 "02dcd4yvdnw35m3srvfd43csxffxw3j4rk6zi379b8dsvbbrjyq1")
        '("syntax-color" "syntax-color-doc" "syntax-color-lib"))
       (simple-racket-origin
        "trace" (base32 "070ihla5j796hdarn5wxdwn4xj0xnkm50shgh49jy994mribvhia")
@@ -970,7 +973,7 @@  (define-public racket
        "unix-socket" (base32 "02dfwas5ynbpyz74w9kwb4wgb37y5wys7svrlmir8k0n9ph9vq0y")
        '("unix-socket" "unix-socket-doc" "unix-socket-lib"))
       (simple-racket-origin
-       "web-server" (base32 "1g4x79ym3mgxv4f3z3z84j12355pf44pjlzlb7f0h6r0i7p0cbjd")
+       "web-server" (base32 "104lnzjykkd6f3gxpv7p14l94if6zac33nmb4sj5jxmd6r3fwcpf")
        '("web-server" "web-server-doc" "web-server-lib"))
       (simple-racket-origin
        "wxme" (base32 "1qp5gr9gqsakiq3alw6m4yyv5vw4i3hp4y4nhq8vl2nkjmirvn0b")