Racket distro packagers: please try building from a snapshot

This request is for anyone who packages the Racket implementation for installation by an OS package manager (as opposed to people who manage Racket packages in the sense of raco pkg).

The upcoming v8.6 release will include an overhaul of the Racket build scripts. The intent is that configure and make work just as before, and we've tested on many platforms and configurations, but there's a good chance that there are still some problems. It would be better to discover lingering problems before the release.

So, if you can, please try building a snapshot as if it were a release, and let us know about any problems that you run into. Snapshot source distributions can be found here:

https://snapshot.racket-lang.org/

Thanks!
Matthew

10 Likes

I'm getting the following error when using my usual ebuild on gentoo. The reason is because we traditionally build cgc-core first, and that option is now gone due to the transition to zuo. Is there an equivalent way to get the same results as the old make cgc-core?

Source configured.
Compiling source in /var/tmp/portage/dev-scheme/racket-8.6_pre1/work/racket-8.5.0.8/src ...
/var/tmp/portage/dev-scheme/racket-8.6_pre1/work/racket-8.5.0.8/src/bc /var/tmp/portage/dev-scheme/racket-8.6_pre1/work/racket-8.5.0.8/src
make -j73 -l8 cgc-core
make: *** No rule to make target 'cgc-core'. Stop.

5 Likes

Thanks for trying out the snapshot!

Currently, there's not a makefile in the bc build directory. While configure and make are meant to work as before in the main src directory, I hadn't added bridge makefiles in src/bc or src/cs/c, because I didn't expect make to be used there.

Probably it's best to add makefiles and preserve the old behavior of being able to run configure and make within bc and cs/c. I'll make that change, and hopefully you can try again with the next snapshot.

2 Likes

For the record:

It's unclear who usually updates either, but there are some names common between the history of the two.


I was going to try building the snapshot via Homebrew to see what happened, but I don't have the time and expertise at the moment, so this is my "next best contribution."

2 Likes

One other place is in gc2 where we run make all. This is for pax-marking on hardened systems.

I don't know exactly what cgc-core is exactly, but for Guix we do totally separate builds from racket-vm-cgc -> racket-vm-bc -> chez-scheme-for-racket -> racket-vm-cs, where vm signifies minimal Racket but without the base and racket-lib packages installed. All that can be done with just configure and make in the src directory. I've got Zuo-ified build definitions at gnu/packages/racket.scm · 271fc33 · Philip McGrath / guix-patches · GitLab and gnu/packages/chez.scm · 271fc33 · Philip McGrath / guix-patches · GitLab, if they help. (I'll also check again with a more recent commit.)

It would be good to figure out the Homebrew issue from Minimal-racket is very slow before installing compiler-lib - #20 by LiberalArtist. It looked to me like it wasn't finding compiled files in the lib directory from a Unix-style install without --enable-sharezo.

1 Like

That one is not so easy to support. Could that step be replaced with make racket3m in the bc directory (assuming I make that work) instead of make all in the bc/gc2 directory?

Possibly. I think as long was we can build the racket3m binary before running make cgc or make bc from the src folder then that will work?

edit: A bit more thinking says that, yes that should work.

I've pushed the change, calling the target just-racket3m instead of racket3m (to avoid the name of the generated file).

The build scripts have a notion of a POST_LINKER step, which is automatically defined as paxctl +m for NetBSD. Would that approach work better for pax marking in gentoo builds? If so, I could add --enable-postlinker=.... so it can be set via configure.

Yes. I think that --enable-postlinker= set via configure would be ideal and simplify a number of things for hardened builds in general.

A new snapshot is available at Racket: Snapshot: 20220607-9c0b2f5 with --enable-postlink= supported (dropped er).

For Void Linux, native compilation seems to work fine without additional changes over 8.5.

Cross-compilation is broken in a few ways. Note that we use --enable-racket=/usr/bin/racket with a Racket built for the host before building cross-compiled packages.

First, zuo is compiled for the target platform due to

HOSTCC=$(CC) $(CFLAGS) -O2

in the Makefile (but $CC is the cross-compiler).

Next, building Chez for the target works fine, but in make install I get

...
/usr/bin/racket -O info'@'compiler/cm -l- setup --chain setup-go.rkt cs/c/compiled ignored cs/c/ignored.d cs/c/add-terminator.rkt cs/c/scheme-v.boot /destdir/aarch64-linux-musl/racket-8.6/usr/lib64/racket/scheme.boot
/usr/bin/racket -O info'@'compiler/cm -l- setup --chain setup-go.rkt cs/c/compiled ignored cs/c/ignored.d cs/c/add-terminator.rkt cs/c/racket-v.boot /destdir/aarch64-linux-musl/racket-8.6/usr/lib64/racket/racket.boot
/builddir/racket-8.5.0.8/src/ChezScheme/ta6le/bin/ta6le/scheme -B /builddir/racket-8.5.0.8/src/ChezScheme/ta6le/boot/ta6le/petite.boot -B /builddir/racket-8.5.0.8/src/ChezScheme/ta6le/boot/ta6le/scheme.boot --script mk-cross-serve.ss . cross-serve.ss ../expander/env.ss
compiling cross-serve.ss with output to /builddir/racket-8.5.0.8/src/cs/c/cross-serve.so
-O info'@'compiler/cm -l- setup --chain setup-go.rkt cs/c/compiled ignored cs/c/ignored.d ../collects/setup/unixstyle-install.rkt make-install-copytree .. /destdir/aarch64-linux-musl/racket-8.6/usr/bin /destdir/aarch64-linux-musl/racket-8.6/usr/share/racket/collects /destdir/aarch64-linux-musl/racket-8.6/usr/share/racket/pkgs /destdir/aarch64-linux-musl/racket-8.6/usr/share/doc/racket /destdir/aarch64-linux-musl/racket-8.6/usr/lib64 /destdir/aarch64-linux-musl/racket-8.6/usr/include/racket /destdir/aarch64-linux-musl/racket-8.6/usr/lib64/racket /destdir/aarch64-linux-musl/racket-8.6/usr/share/racket /destdir/aarch64-linux-musl/racket-8.6/etc/racket /destdir/aarch64-linux-musl/racket-8.6/usr/share/applications /destdir/aarch64-linux-musl/racket-8.6/usr/share/man no
process: not a path string: (hash 'MAKE_COPYTREE "copytree" 'RANLIB "aarch64-linux-musl-ranlib" 'etcpltdir "/etc/${PACKAGE}" 'RKTLINKER "aarch64-linux-musl-gcc" 'racket "/usr/bin/racket" 'INSTALL_SETUP_FLAGS "--no-user" 'libpltdir_rel "" 'datarootdir "${prefix}/share" 'SETUP_MACHINE_FLAGS "" 'CROSS_MODE "cross" 'MACLIBRKT_LINK_MODE "fw" 'FRAMEWORK_REL_INSTALL "" 'exec_prefix "${prefix}" 'LINK_DYNAMIC "-rdynamic" 'PACKAGE "racket" 'POST_LINKER "" 'INSTALL_PKGSCOPE "user" 'DISABLE_WPO "f" 'OSX "f" 'ZUO "bin/zuo" 'MAKE_INSTALL_PKGSCOPE "preserve" 'COMPRESS_COMP "--compress" 'srcdir "." 'HOSTCC "cc -O2" 'DISABLE_ICONV "no" 'CONFIGURE_RACKET_SO_COMPILE "" 'SELF_ROOT_CONFIG_DIR "" 'CONFIG_PATH "${etcpltdir}" 'PLT_CS_SLSP_SUFFIX "" 'INSTALL_LIBZO "libzo" 'TARGET_MACH "tarm64le" 'COLLECTS_PATH "${collectsdir}" 'CROSS_COMPILE_TARGET_KIND "machine" 'ARFLAGS "rc" 'DISABLE_CURSES "yes" 'INSTALL_ORIG_TREE "no" 'MACH "ta6le" 'configdir "/etc/${PACKAGE}" 'AR "aarch64-linux-musl-ar" 'mandir "/usr/share/man" 'collectsdir "${exec_prefix}/share/${PACKAGE}/collects" 'SETUP_BOOT_MODE "--chain" 'includepltdir "${prefix}/include/${PACKAGE}" 'upsrcdir "../." 'SCHEME_LIBFFI "no" 'appsdir "${exec_prefix}/share/applications" 'DESTDIR "/destdir/aarch64-linux-musl/racket-8.6" 'sharepltdir "${datarootdir}/${PACKAGE}" 'FRAMEWORK_INSTALL_DIR "$(libpltdir)" 'LIBS "-ldl -lm  -lrt -lz -llz4" 'docdir "${datarootdir}/doc/${PACKAGE}" 'RKTIO_CONFIGURE_ARGS "'--prefix=/usr' '--sysconfdir=/etc' '--sbindir=/usr/bin' '--bindir=/usr/bin' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--localstatedir=/var' '--host=x86_64-unknown-linux-musl' '--build=x86_64-unknown-linux-musl' '--libdir=${exec_prefix}/lib64' '--host=aarch64-linux-musl' '--with-sysroot=/usr/aarch64-linux-musl' '--with-libtool-sysroot=/usr/aarch64-linux-musl' 'build_alias=x86_64-unknown-linux-musl' 'host_alias=aarch64-linux-musl' 'CC=aarch64-linux-musl-gcc' 'CFLAGS=-fstack-clash-protection -D_FORTIFY_SOURCE=2 -O2 -pipe -march=armv8-a   -I/usr/aarch64-linux-musl/usr/include -fdebug-prefix-map=/builddir/racket-8.5.0.8=.' 'LDFLAGS=-Wl,-z,relro -Wl,-z,now -Wl,--as-needed    -L/usr/aarch64-linux-musl/usr/lib' 'CPPFLAGS=  ' 'CPP=aarch64-linux-musl-cpp'  CC=\"aarch64-linux-musl-gcc\" CFLAGS=\"-fstack-clash-protection -D_FORTIFY_SOURCE=2 -O2 -pipe -march=armv8-a   -I/usr/aarch64-linux-musl/usr/include -fdebug-prefix-map=/builddir/racket-8.5.0.8=.\" LDFLAGS=\"-Wl,-z,relro -Wl,-z,now -Wl,--as-needed    -L/usr/aarch64-linux-musl/usr/lib -pthread\" LIBS=\"-ldl -lm  -lrt -lz -llz4\" AR=\"aarch64-linux-musl-ar\" ARFLAGS=\"rc\" RANLIB=\"aarch64-linux-musl-ranlib\" WINDRES=\"windres\" CPPFLAGS=\"    -pthread\" --enable-pthread --enable-iconv" 'libpltdir "${exec_prefix}/lib64/${PACKAGE}" 'CS_INSTALLED "" 'LDFLAGS "-Wl,-z,relro -Wl,-z,now -Wl,--as-needed    -L/usr/aarch64-linux-musl/usr/lib -pthread" 'pkgsdir "${datarootdir}/${PACKAGE}/pkgs" 'STRIP_LIB_DEBUG "aarch64-linux-musl-strip -S" 'BOOT_COMPRESS_COMP "" 'INSTALL_LIBS_ENABLE "install" 'libdir "${exec_prefix}/lib64" 'BOOTFILE_RACKET "" 'CFLAGS "-fstack-clash-protection -D_FORTIFY_SOURCE=2 -O2 -pipe -march=armv8-a   -I/usr/aarch64-linux-musl/usr/include -fdebug-prefix-map=/builddir/racket-8.5.0.8=." 'LZ4_LIB "-llz4" 'RACKET "/usr/bin/racket" 'STRIP_DEBUG "aarch64-linux-musl-strip" 'KERNEL_TARGET_MACH "tarm64le" 'prefix "/usr" 'CPPFLAGS "-pthread" 'SCHEME_DIR "/builddir/racket-8.5.0.8/src/ChezScheme" 'ICP_LIB "cp" 'PBCHUNK_MODE "plain" 'WINDRES "windres" 'CC "aarch64-linux-musl-gcc" 'Z_LIB "-lz" 'ICP "cp" 'bindir "/usr/bin" 'SCHEME "")

Note how it seems to use an empty string as compiler? The line starts with -O info. So mk-cross-serve.ss may need adjustments here to use /usr/bin/racket as well?

1 Like

I'm hitting an issue that I think is related to the one that @leahneukirchen is hitting, which is that I get the following when I run ./configure --enable-bc --enable-shared; pushd bc; make cgc-core.

mkdir -p bin
libtool --mode=compile --tag=CC gcc -O2 -DZUO_LIB_PATH='"'".././../zuo/lib"'"' -o bin/zuo ./../zuo/zuo.c
libtool:   error: cannot determine name of library object from 'bin/zuo'
make: *** [Makefile:184: bin/zuo] Error 1

I think the difference is due to the CC variable in bc/Makefile which is
CC = libtool --mode=compile --tag=CC gcc for --enable-shared and
CC = gcc without --enable-shared.

What is the right way in this context for Racket's build scripts to get a compiler whose output is for the host?

One possibility is that the Void script to derive a Racket build supplies HOSTCC=.

Another possibility is that there's already a good way to get a host compiler, and the Racket build scripts should use that.

Finally, a possibility is that builds aren't supposed to want a compiler for host-platform output, and Zuo needs to be built and available (in much the same way that a host Racket has been built) so that the Void script can supply ZUO=zuo (or something like that) when driving a Racket build.

This came up for Guix, too, but I worked around it by packaging Zuo separately and adding it as a build dependency, letting us supply ZUO=zuo.

I think the right thing is probably for Racket's configure to arrange to build Zuo so that Zuo's "host" is Racket's "build", in the Autoconf build/host/target sense. Sometimes such compiler for this scenario seems to be called CC_FOR_BUILD. I'm not sure what the best way to do this with Autoconf is—in particular, how much should be fixed at configure time vs. overridable at make time—but I did see ax_prog_cc_for_build (Autoconf Archive).

A packager may still need to add a suitable C toolchain to the build environment, depending on how sparse their default build environment is, but I think this would at least produce a descriptive error, rather than attempting to execute code for the wrong system.

I've changed HOSTCC to CC_FOR_BUILD, made configure recognize a CC_FOR_BUILD=... argument, and fixed some other problems with BC and --enable-shared (intended to fix the problem that @tgbugs hit).

I'd really rather not have to make the configure scripts figure out automatically when a CC_FOR_BUILD different from CC is needed, so I'm trying without that for now.

Update.

With the recent fixes I have made if far enough to encountered a new issue, which is that it seems that cs-install and bc-install are the new names for install-cs and install-bc, however it seems that there is no longer a cgc-install.

Another point of strangeness is that calling make bc doesn't seem to actually build racketbc, e.g. you have to call make 3m in order for make install-bc to not fail due to missing racket3m? Should make bc be calling make 3m internally (via zuo)?

The fixes for --enable-shared seem to be working when I test them in git. I'll check again when the snapshot finishes building.

I have been able to use --enable-postlink to simplify the build process, the bridging make files for cgc-core and just-racket3m are still useful in cases where we don't need to pax mark absolutely everything.

Thanks — I've pushed repairs for these.

1 Like

Not sure what happened, but on master if I run ./configure or ./configure --enable-cs and then make cs I now get the following error

mkdir -p bin
cc -O2 -DZUO_LIB_PATH='"'".././zuo/lib"'"' -o bin/zuo ./zuo/zuo.c
bin/zuo . cs
cd cs/c/rktio/ && ../../../rktio/configure CC=gcc CFLAGS=-g" "-O2" "-Wall LDFLAGS=" "-pthread LIBS=-ldl" "-lm"  "-lrt"  "-lncurses" "-ltinfo" "-lz" "-llz4 AR=ar ARFLAGS=rc RANLIB=ranlib WINDRES=windres CPPFLAGS="  "-pthread --enable-pthread --enable-iconv
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for ranlib... ranlib
checking for fmod in -lm... yes
checking for dlopen in -ldl... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for intptr_t... yes
checking for uintptr_t... yes
checking whether byte ordering is bigendian... no
checking for struct dirent.d_namelen... no
checking for struct dirent.d_namlen... no
checking for xlocale.h... no
checking for xlocale functions... yes
checking for getaddrinfo... yes
checking iconv.h usability... yes
checking iconv.h presence... yes
checking for iconv.h... yes
checking iconv is usable... yes
checking for nl_langinfo (CODESET)... yes
checking for mbsrtowcs... yes
checking for poll... yes
checking for epoll... yes
checking for inotify... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating rktio_config.h
gcc -pthread -DPORTABLE_BYTECODE -Ics/c/ChezScheme/pb/boot/pb -Ics/c/ChezScheme/pb/c -IChezScheme/c/ -g -O2 -Wall -pthread -o cs/c/ChezScheme/pb/c/statics.o -c ChezScheme/c/statics.c
In file included from ChezScheme/c/system.h:46,
                 from ChezScheme/c/statics.c:18:
ChezScheme/c/segment.h: In function ‘S_object_to_reference’:
ChezScheme/c/segment.h:94:31: error: ‘reference_disp’ undeclared (first use in this function)
   94 |     return ((ptr)((uptr)(p) + reference_disp));
      |                               ^~~~~~~~~~~~~~
ChezScheme/c/segment.h:94:31: note: each undeclared identifier is reported only once for each function it appears in
ChezScheme/c/segment.h: In function ‘S_reference_to_object’:
ChezScheme/c/segment.h:101:31: error: ‘reference_disp’ undeclared (first use in this function)
  101 |     return ((ptr)((uptr)(p) - reference_disp));
      |                               ^~~~~~~~~~~~~~
ChezScheme/c/segment.h: In function ‘S_maybe_reference_to_object’:
ChezScheme/c/segment.h:124:31: error: ‘reference_disp’ undeclared (first use in this function)
  124 |     return ((ptr)((uptr)(p) - reference_disp));
      |                               ^~~~~~~~~~~~~~
compile failed
 in build-one
 in loop
 in module->hash
make: *** [Makefile:23: cs] Error 1

This person is building a racket snap, and while they used main/master it seemed successful

Thread here