Compare commits

...

10 Commits

Author SHA1 Message Date
Jan Nieuwenhuizen 6b4a0ed8a2
core: Support string-set!
* src/string.c (string_set_x): New function.
* src/mes.c (mes_builtins): Add it.
* include/mes/builtins.h: Declare it.
* mes/module/mes/scm.mes (string-set!): Remove broken implementation.
2019-12-29 22:55:03 +01:00
Jan Nieuwenhuizen bafe4c81ef
Support generating Nyacc tables. WIP
* mes/module/nyacc/lang/c99/cppmach.mes: New file.
* mes/module/nyacc/lang/c99/mach.mes: New file.
* mes/module/nyacc/lang/lalr.mes: Resurrect.
* module/mes/pretty-print.scm: Rename from
mes/module/mes/pretty-print.scm.
2019-12-29 22:53:48 +01:00
Jan Nieuwenhuizen fdcdead857
doc: Release update.
* BOOTSTRAP: Release update.
* HACKING: Likewise.
* INSTALL: Likewise.
* NEWS: Likewise.
* PORTING: Likewise.
* README: Likewise.
* ROADMAP: Likewise.
* doc/mes.texi: Likewise.
2019-12-29 14:33:30 +01:00
Jan Nieuwenhuizen cca07aff2b
mescc: Mes C Library: Fix execlp, execvp for file names with slash.
Reported by mid-kid.

* lib/posix/execlp.c (execlp): Do not use search_path when file name
contains a slash (WAS: when file name starts with slash).
* lib/posix/execvp.c (execvp): Likewise.
2019-12-29 14:33:10 +01:00
Jan Nieuwenhuizen 575c177817
build: Support bootstrapping using build.sh.
* build-aux/build.sh.in: Oops, use $compiler = bootstrap concept does
not exist yet.  Gash cp does not support -p; drop it.
* configure.sh: Oops, set bootstrap to `true' instead of yes.
2019-12-19 09:11:14 +01:00
Jan Nieuwenhuizen 6a9154cd67
mescc: Mes C Library: lseek: Be careful clearing read buffer.
* lib/linux/lseek.c (_lseek): New function.
* lib/linux/lseek.c (lseek): Use it to check if we should reset read
buffer.
* lib/mes/__buffered_read.c (__read_buffer_max): New variable.
(__buffered_read_init): Add environment override: MES_READ_BUFFER.
(__buffered_read): Use it.
2019-12-19 07:14:35 +01:00
Jan Nieuwenhuizen 709176b247
build: Have configure respect GUILE_LOAD_PATH for mes to find Nyacc.
* configure: Substitute GUILE_LOAD_PATH from %load-path.
* configure.sh: Likewise.
* build-aux/config.make.in: Add GUILE_LOAD_PATH as subtitution variable.
* build-aux/config.sh.in: Likewise.
* mes/module/mes/guile.mes (%load-path): New variable.
2019-12-17 21:08:19 +01:00
Jan Nieuwenhuizen e7f151e126
build: Have configure prefer $CC over gcc; tcc over gcc, gcc over cc.
Reported by Vagrant Cascadian.

* configure (string->version): Prefer for most-dotted string.  Fixes
makeinfo version.
(check-program-version): Prefer displaying of command, if single word.
(main): Check for $CC --version, $CC -v.  Prefer $CC over gcc; tcc over
gcc, gcc over cc.
2019-12-17 21:08:18 +01:00
Jan Nieuwenhuizen b834c7877a
mescc: Opt for reproducible builds with Guile and MES.
* module/mescc/compile.scm (mes-or-reproducible?): New variable.
(ast->comment): Use it.
* module/mescc/preprocess.scm (mes-or-reproducible?): New variable.
(c99-input->full-ast): Use it.
2019-12-17 21:08:18 +01:00
Jan Nieuwenhuizen b041861c26
build: Resurrect compiling with TinyCC.
./configure CC=tcc --host=i686-unknown-linux-gnu --with-courage

* configure: Cater for tcc.
2019-12-17 21:08:18 +01:00
32 changed files with 583 additions and 204 deletions

View File

@ -8,24 +8,24 @@ Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
notice and this notice are preserved. notice and this notice are preserved.
* What? * What?
** Full source bootstrapping for GNU Guix ** Full source bootstrapping for the GNU System
A package in Guix is uniquely identified by the hash of its source code, A package in GNU Guix is uniquely identified by the hash of its source
its dependencies, and its build recipe. code, its dependencies, and its build recipe.
Every package can be built from source, except for the bootstrap Every package can be built from source, except for the bootstrap
binaries. binaries.
*** From the Guix manual *** From the GNU Guix manual
The distribution is fully “bootstrapped” and “self-contained”: each The distribution is fully “bootstrapped” and “self-contained”: each
package is built based solely on other packages in the distribution. package is built based solely on other packages in the distribution.
The root of this dependency graph is a small set of “bootstrap The root of this dependency graph is a small set of “bootstrap
binaries”, provided by the (gnu packages bootstrap) module. For more binaries”, provided by the (gnu packages bootstrap) module. For more
information on bootstrapping, *note Bootstrapping::. information on bootstrapping, *note Bootstrapping::.
**** Guix bootstrap tarballs **** Guix v1.0 bootstrap binary seed
$ du -schx $(readlink $(guix build bootstrap-tarballs)/*) $ du -schx $(readlink $(guix build bootstrap-tarballs)/*)
2.1M /gnu/store/9623n4bq6iq5c8cwwdq99qb7d0xj93ym-binutils-static-stripped-tarball-2.28.1/binutils-static-stripped-2.28.1-x86_64-linux.tar.xz 2.1M /gnu/store/9623n4bq6iq5c8cwwdq99qb7d0xj93ym-binutils-static-stripped-tarball-2.28.1/binutils-static-stripped-2.28.1-x86_64-linux.tar.xz
@ -44,6 +44,42 @@ $ du -schx *
5.2M share 5.2M share
252M total 252M total
**** Guix Reduced Binary Seed bootstrap binary seed
$ du -schx $(readlink $(guix build bootstrap-tarballs)/*)
5.7M /gnu/store/9f8gi8raqfx9j3l9d00qrrc0jg3r1kyj-guile-static-stripped-tarball-2.2.6/guile-static-stripped-2.2.6-x86_64-linux.tar.xz
80K /gnu/store/b6rjl52hibhmvyw4dg8678pwryhla0h2-linux-libre-headers-stripped-tarball-4.19.56/linux-libre-headers-stripped-4.19.56-x86_64-linux.tar.xz
12K /gnu/store/d7zlxsjcnqilmvqwx7scija9x9bjw8cw-mescc-tools-static-stripped-tarball-0.5.2-0.bb062b0/mescc-tools-static-stripped-0.5.2-0.bb062b0-x86_64-linux.tar.xz
428K /gnu/store/n7zc4kpi8ny6jlfaikkzxlwhc5fvr1vr-mes-minimal-stripped-tarball-0.19/mes-minimal-stripped-0.19-x86_64-linux.tar.xz
6.0M /gnu/store/nv4djwlrljfqmynqr2cqvfwz0ydx7kxb-static-binaries-tarball-0/static-binaries-0-x86_64-linux.tar.xz
13M total
$ for i in $(readlink $(guix build bootstrap-tarballs)/*);\
do sudo tar xf $i; done
Password:
$ du -schx *
93M bin
700K include
38M lib
14M share
145M total
**** Guix Scheme-only bootstrap binary seed
$ du -schx $(readlink $(~/src/guix/wip-bootstrap/pre-inst-env guix build bootstrap-tarballs)/*)
5.7M /gnu/store/1mq2pcd2h7g54xpi2jrgj6ibbi4lgi3c-guile-static-stripped-tarball-2.2.6/guile-static-stripped-2.2.6-x86_64-linux.tar.xz
80K /gnu/store/bl1r2bpk6fam8r2gjvr5mvr48i3dm2hn-linux-libre-headers-stripped-tarball-4.19.56/linux-libre-headers-stripped-4.19.56-x86_64-linux.tar.xz
12K /gnu/store/w0dlz486dhb8aiq8pxm5akllz628fqin-mescc-tools-static-stripped-tarball-0.5.2-0.bb062b0/mescc-tools-static-stripped-0.5.2-0.bb062b0-x86_64-linux.tar.xz
428K /gnu/store/15j6l18q44ymlrh1cfp4s4hc9835xic5-mes-minimal-stripped-tarball-0.19/mes-minimal-stripped-0.19-x86_64-linux.tar.xz
6.2M total
$ for i in $(readlink $(~/src/guix/wip-bootstrap/pre-inst-env guix build bootstrap-tarballs)/*);\
do sudo tar xf $i; done
$ du -schx *
4.9M bin
700K include
38M lib
14M share
57M total
* Why? * Why?
** Reproducibility is essential to Software Freedom ** Reproducibility is essential to Software Freedom
@ -92,20 +128,22 @@ be source.
*** mes.c: a Scheme interpreter in ~5,000LOC of simple C *** mes.c: a Scheme interpreter in ~5,000LOC of simple C
*** mescc: a C compiler written in Scheme (uses Nyacc C99 parser in Scheme) *** mescc: a C compiler written in Scheme (uses Nyacc C99 parser in Scheme)
*** mes.M2: this Scheme interpreter in preprocessed M2 *** mes.M2: this Scheme interpreter in bootstrappable M2
** TinyCC ** TinyCC
https://gitlab.com/janneke/tinycc https://gitlab.com/janneke/tinycc
* TODO * TODO
** merge scheme-only bootstrap into Guix.
** reduced binary seed bootstrap into NixOS, Debian.
** remove or upstream patches from tcc-boot ** remove or upstream patches from tcc-boot
** prepare src/mes.c for M2-Planet transpiler. ** prepare src/mes.c for M2-Planet transpiler.
** ARM, the Hurd ** ARM, the Hurd
** fix bootstrap-loops: (Nyacc?, mes.M2, psyntax.pp?) ** fix bootstrap-loops: (Nyacc?, mes.M2, psyntax.pp?)
** make GNU gcc (8.0?) bootstrappable again, remove [need for] tcc stage ** make GNU gcc (8.0?) bootstrappable again, remove [need for] tcc stage
* DONE * DONE
** upstream mes-boot to Guix. ** reduced binary seed bootstrap into Guix.
** replace Guix bootstrap for x86_64. ** replace Guix bootstrap for x86_64.
** replace Guix bootstrap for x86. ** replace Guix bootstrap for x86.
** add full source gcc-4.7 package build. ** add full source gcc-4.7 package build.
@ -121,5 +159,6 @@ be source.
** tcc compiled with gcc is known to compile gcc ** tcc compiled with gcc is known to compile gcc
* Contact * Contact
** bug-mes@gnu.org
** #bootstrappable, #guix on freenode ** #bootstrappable, #guix on freenode
** bootstrappable.org ** bootstrappable.org

70
HACKING
View File

@ -1,64 +1,31 @@
-*- org -*- -*- org -*-
#+TITLE: Hacking GNU Mes #+TITLE: Hacking GNU Mes
Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
* SETUP * SETUP
guix environment -l guix.scm #64 bit + 32bit guix environment -l guix.scm #64 bit + 32bit
CC=i686-unkown-linux-gnu-gcc ./configure
or or
./configure
guix environment --system=i686-linux -l guix.scm #32 bit only The 64bit bootstrap is not supported; MesCC needs work to be able to
compile a functional tinycc.
or
guix package --profile=~/.config/guix/mes --manifest=build-aux/manifest.scm
. ~/.config/guix/mes/etc/profile
* BUILD * BUILD
There are two major modes to build Mes: true bootstrap and
development.
** DEVELOPMENT BUILD GNU Guile can be used as a replacement for Mes. It's faster and has
To help development we assume ./configure sets these variables for make much better error handling.
CC -- gcc (or i686-unknown-linux-gnu-gcc sans libc) #+BEGIN_SRC bash
GUILE -- guile make MES=guile
HEX2 -- hex2 make check MES=guile
MES -- unset #+END_SRC
M1 -- M1
prefix -- ""
Mes is supposed to serve as a full equivalent for Guile, however Mes Configure to compile with Tiny CC
is still about 2 to 10 times slower than Guile. That's why we usually
don't use Mes during development, configure --with-cheating.
Gcc is used to verify the sanity of our C sources. #+BEGIN_SRC bash
./configure CC=tcc --host=i686-unknown-linux-gnu --with-courage
i686-unknown-linux-gnu-gcc is used to compare hex/assembly, to test #+END_SRC
the gcc variant of Mes C Libirary.
Target prefix: x86-mes-gcc.
gcc -nostdinc,-nostdlib is used to compare hex/assembly, to test the
64bit variant of Mes C Library. Target prefix: x86_64-mes-gcc.
Guile is used to develop MesCC, the C compiler in Scheme that during
bootstrapping will be executed by Mes.
** BOOTSTRAP BUILD
./configure.sh [--prefix=PREFIX]
./bootstrap.sh
./install.sh
In bootstrap mode, we don't have gcc (CC), we don't have a 32 bit gcc,
we have no guile (GUILE)...but we should have hex2, M1, and mes.M1.
That's a bootstrap problem which is currently ignored by using the
mes-seed package. mes.M1 will be produced by M2-Planet from mes.c.
* DEBUG * DEBUG
MES_DEBUG=<level> mes MES_DEBUG=<level> mes
@ -83,7 +50,7 @@ mes-seed package. mes.M1 will be produced by M2-Planet from mes.c.
* Bugs * Bugs
** mes: performance, Mes is now 2-10x slower than Guile. ** mes: performance, Mes is now 2-10x slower than Guile.
** mes/mescc lack support for the Hurd. ** mes/mescc lack support for fork/exec on the Hurd.
** mes: gcc-x86_64 compiled mes segfaults with small arena, or gc_up_arena. ** mes: gcc-x86_64 compiled mes segfaults with small arena, or gc_up_arena.
** mes: gcc-x86 compiled, tests/srfi-13.test number->string INT-MIN fails: ** mes: gcc-x86 compiled, tests/srfi-13.test number->string INT-MIN fails:
test: number->string INT-MIN: fail test: number->string INT-MIN: fail
@ -214,3 +181,10 @@ https://notabug.org/rain1/hex86/src/master/tests/hex0b3.hex86
https://jamey.thesharps.us/2016/07/15/testing-strategies-for-corrode/ https://jamey.thesharps.us/2016/07/15/testing-strategies-for-corrode/
("Randomized testing with Csmith and C-Reduce") [10:58] ("Randomized testing with Csmith and C-Reduce") [10:58]
** linux syscalls: https://fedora.juszkiewicz.com.pl/syscalls.html ** linux syscalls: https://fedora.juszkiewicz.com.pl/syscalls.html
* legalese
Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.

23
INSTALL
View File

@ -41,6 +41,19 @@ similar way.
make make
#+END_SRC #+END_SRC
If you get something like
#+BEGIN_SRC bash
mes.c:(.text+0x8da0): undefined reference to `__stack_chk_fail'
#+END_SRC
then your compiler inserts stack protection code. The Mes C Library
does not support that. Turn it off lik this
#+BEGIN_SRC bash
./configure CFLAGS=-fno-stack-protector
#+END_SRC
** Check it ** Check it
#+BEGIN_SRC bash #+BEGIN_SRC bash
@ -86,3 +99,13 @@ https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/commencement.scm
#+BEGIN_SRC bash #+BEGIN_SRC bash
sh install.sh sh install.sh
#+END_SRC #+END_SRC
* Regular build and bootstrap combine
To build mes.c using MesCC, configure using --with-bootstrap:
#+BEGIN_SRC bash
./configure --with-bootstrap
make
#+END_SRC
This creates bin/mes-gcc and bin/mes-mescc.

36
NEWS
View File

@ -10,6 +10,41 @@ Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
Please send Mes bug reports to bug-mes@gnu.org. Please send Mes bug reports to bug-mes@gnu.org.
* Changes in 0.22 since 0.21
** Core
*** Mes now builds reproducibly with MesCC, cross distribution
Using --with-bootstrap on x86, a bin/mes-mescc is compiled with
mes+mescc, that shall have sha256sum
9e0bcb1633c58e7bc415f6ea27cee7951d6b0658e13cdc147e992b31a14625fb bin/mes-mescc
This has been verified on GNU Guix, Debian GNU/Linux and NixOS.
*** Mes now builds reproducibly with Guile+MesCC vs Mes+MesCC.
*** Mes now builds reproducibly with Tiny CC-built MesCC.
*** configure now respects the user's CFLAGS, CPPFLAGS and LDFLAGS.
*** Mes now supports mescc-tools 0.5.2 next to 0.6.1.
This allows introducing the Scheme-only bootstrap without updating or
adding new bootstrap binary seeds into GNU Guix.
*** Mes now runs when configured --with-courage on the Hurd:
GNU debian 0.9 GNU-Mach 1.8+git20170609-486/Hurd-0.9 i686-AT386 GNU
Note that mescc does not run; fork and exec are not yet implemented.
*** Mes now configures --with-courage on x86-FreeBSD 12.1
The initial ELF scaffold tests: exit-42.S, 0exit-42.hex2,
body-exit-42.hex2, hello-mes.S, 0hello-mes.hex2, body-hello-mes.hex2
pass.
*** configure now has a --with-bootstrap option.
This adds the reproducible bootstrap build of bin/mes-mescc, using
mes+mescc.
*** configure prefers $CC over gcc; tcc over gcc, gcc over cc.
*** Mes now prints an error when attempting to read a file that does not exist.
*** Mes no longer depends on GIT.
** Noteworthy bug fixes
*** Several annoying build problems were fixed, for non-Guix systems.
*** A bug with buffered-read was fixed.
This means that bash-2.05 can now build glibc-2.2.5; notably it now
successfully executes make-syscall.sh.
*** A bug with execlp, execvp for file names containing a slash was fixed.
This should allow make-3.80 running scripts that have "#! ./move-if-change".
* Changes in 0.21 since 0.20 * Changes in 0.21 since 0.20
** Core ** Core
*** Mes can now be bootstrapped with Gash and Gash Core Utils. *** Mes can now be bootstrapped with Gash and Gash Core Utils.
@ -48,6 +83,7 @@ take-while.
*** 1 new function *** 1 new function
__mesabi_uldiv. __mesabi_uldiv.
** Noteworthy bug fixes ** Noteworthy bug fixes
*** map and for-each now support lists with unequal length.
*** interger division has been fixed. *** interger division has been fixed.
*** isatty now looks at terminfo. *** isatty now looks at terminfo.
*** signal now uses sigaction correctly for non-x86. *** signal now uses sigaction correctly for non-x86.

22
PORTING
View File

@ -54,6 +54,28 @@ bootstrap for x86_64 uses x86 mes and that is not expected to change.
The Hurd port can be found in wip-hurd on savannah. For development, we The Hurd port can be found in wip-hurd on savannah. For development, we
use a Debian GNU/Hurd vm. use a Debian GNU/Hurd vm.
* Porting GNU Mes to FreeBSD
The FreeBSD port can be found in wip-freebsd on savannah.
* Porting the Reduced Binary Seed bootstrap to NixOS
The NixOS port of the Reduced Binary Seed bootstrap lives on the
mes-bootstrap branch in https://github.com/xwvvvvwx/nixpkgs
* Porting the Reduced Binary Seed bootstrap to Debian GNU/Linux
To port the Reduced Binary Seed bootstrap to a traditional distribution
such as Debian, two things need to happen: the bootstrap must be ported
and the distribution build process needs to change to start from a only
binary seed.
The porting aspect is probably easiest: we start by packaging GNU Mes as
a regular package. Having Mes built as a regular package, we can then
build a bootstrap Mes. This bootstrap Mes can be used to build tinycc,
and so on.
Once we have shown that the Debian base system can be bootstrapped from
a Reduced Binary seed, thus significantly reducing the Trusted Computing
Base (TCB), strategic decisions about the build process can start.
* Legalese * Legalese
Copyright © 2019 Jan (janneke) Nieuwenhuizen <[[mailto:janneke@gnu.org][janneke@gnu.org]]> Copyright © 2019 Jan (janneke) Nieuwenhuizen <[[mailto:janneke@gnu.org][janneke@gnu.org]]>

12
README
View File

@ -4,11 +4,11 @@
#+SUBTITLE: Maxwell Equations of Software #+SUBTITLE: Maxwell Equations of Software
[[https://www.gnu.org/software/mes][GNU Mes]] is a Scheme interpreter and C compiler for bootstrapping the GNU [[https://www.gnu.org/software/mes][GNU Mes]] is a Scheme interpreter and C compiler for bootstrapping the GNU
system. Since version 0.20 it brings a [[https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/][Reduced Binary Seed bootstrap]] to System. Since version 0.20 it brings a [[https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/][Reduced Binary Seed bootstrap]] to
[[https://www.gnu.org/software/guix][GNU Guix]]. This bootstrap has halved the size of opaque, uninspectable [[https://www.gnu.org/software/guix][GNU Guix]]. This bootstrap has halved the size of opaque, uninspectable
binaries that were needed to bootstrap Guix 1.0. The final goal is to binary seeds that were needed to bootstrap Guix 1.0. The final goal is
help create a full source bootstrap as part of the [[http://bootstrappable.org][bootstrappable builds]] to help create a full source bootstrap as part of the [[http://bootstrappable.org][bootstrappable
effort for UNIX-like operating systems. builds]] effort for UNIX-like operating systems.
Mes consists of a mutual self-hosting Scheme interpreter written in Mes consists of a mutual self-hosting Scheme interpreter written in
~5,000 LOC of simple C, and a C compiler written in Scheme. This mes.c ~5,000 LOC of simple C, and a C compiler written in Scheme. This mes.c
@ -16,8 +16,8 @@ is [[https://github.com/oriansj/mes-m2][being simplified]] to be transpiled by [
The Scheme interpreter has a Garbage Collector, a library of loadable The Scheme interpreter has a Garbage Collector, a library of loadable
Scheme modules-- notably Dominique Boucher's [[https://github.com/schemeway/lalr-scm][LALR]], Pre-R6RS [[https://www.cs.indiana.edu/chezscheme/syntax-case/old-psyntax.html][portable Scheme modules-- notably Dominique Boucher's [[https://github.com/schemeway/lalr-scm][LALR]], Pre-R6RS [[https://www.cs.indiana.edu/chezscheme/syntax-case/old-psyntax.html][portable
syntax-case]] with R7RS ellipsis, Matt Wette's [[https://www.nongnu.org/nyacc][Nyacc]] --and test suite just syntax-case]] with R7RS ellipsis, Matt Wette's [[https://www.nongnu.org/nyacc][Nyacc]] --and test suite,
enough to support a REPL and a C99 compiler: MesCC. just enough to support a REPL and a C99 compiler: mescc.
Mes+MesCC can compile an only [[http://gitlab.com/janneke/tinycc][lightly patched TinyCC]] that is Mes+MesCC can compile an only [[http://gitlab.com/janneke/tinycc][lightly patched TinyCC]] that is
self-hosting. Using this tcc and the Mes C library we now have a self-hosting. Using this tcc and the Mes C library we now have a

31
ROADMAP
View File

@ -9,7 +9,7 @@ Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
The goals of the GNU Mes project are two-fold: The goals of the GNU Mes project are two-fold:
- to bootstrap the GNU system purely from source, without using any binary - to bootstrap the GNU System purely from source, without using any binary
seeds. seeds.
- to aid the Reproducible-Builds.org effort; demonstrate the impact and - to aid the Reproducible-Builds.org effort; demonstrate the impact and
@ -23,23 +23,32 @@ on Freenode!
* TODO * TODO
** release 0.x, unsorted ** release 0.x, unsorted
- Merge the Scheme-only bootstrap which uses Gash and Gash Core
Utilities to remove from bootstrap-binary seed : Awk, Bash, Core
Utilities, Grep, Gzip, Sed, Tar.
- Introduce the Reduced Binaries Seed bootstrap to NixOS (Debian, - Introduce the Reduced Binaries Seed bootstrap to NixOS (Debian,
Gentoo, ...?) Arch, Gentoo, ...?)
- Full Source Bootstrap: compile Mes.c using M2-Planet. Jeremiah - Full Source Bootstrap: compile mes.c using M2-Planet. Jeremiah
branched-out from mes; see https://github.com/oriansj/mes-m2, also see the branched-out from mes; see https://github.com/oriansj/mes-m2, also see the
branches: wip-m2-merge and wip-m2. branches: wip-full-source-bootstrap, wip-m2-merge and wip-m2.
- Scheme-only bootstrap bootstrap-binaries with Gash and Gash Core
Utilities: Awk, Bash, Core Utilities, Grep, Gzip, Make, Sed, Tar.
- Full Guile-compatible module support: define-module, define-public, - Full Guile-compatible module support: define-module, define-public,
export, use-modules, ... export, use-modules, ...
- ARMv7/AArch64 support: Mes C Library and MesCC. - ARMv7/AArch64 support: Mes C Library and MesCC.
- Simplify eval-apply and other core functionality (see mes-m2). - Simplify eval-apply and other core functionality (see mes-m2).
** after release 1.0 - Support native x86_64 bootstrap.
- Replace the initial gcc-2.95.3 with gcc-4.6.4. - Simplify MesCC ``MesCC should optimize ease of convincing us of its
correctness''
- tcc: remove or upstream patches from tcc-boot. - tcc: remove or upstream patches from tcc-boot.
- tcc: build 0.9.27 directly instead of via 0.9.26, see tinycc - tcc: build 0.9.27 directly instead of via 0.9.26, see tinycc
** after release 1.0
- Build Guix packages using Mes: run or simplify (guix build utils),
(guix build gnu-build-system).
- Build Guix packages without guix-daemon. See Ludovic's initrd build
work.
- Bootstrap support for the Hurd. Most needed now are fork and exec.
- Replace the initial gcc-2.95.3 with gcc-4.6.4.
- FreeBSD, *BSD?
wip-bootstrappable@0.9.27 branch wip-bootstrappable@0.9.27 branch
- Bootstrap a `bootstrap-Guile' before bootstrapping tcc?
- Skip tcc: Build gcc using MesCC. - Skip tcc: Build gcc using MesCC.
- better garbage collector. - better garbage collector.
- mes/mescc: proper docstrings, api reference documentation. - mes/mescc: proper docstrings, api reference documentation.
@ -51,9 +60,9 @@ on Freenode!
+ get full source syntax-case up (Andre van Tonder?) + get full source syntax-case up (Andre van Tonder?)
https://srfi.schemers.org/srfi-72/srfi-72.html, or https://srfi.schemers.org/srfi-72/srfi-72.html, or
+ ... drop it? + ... drop it?
- Support the Hurd. There is a wip-hurd branch; most needed now are fork
and exec.
* DONE * DONE
- 0.22 GNU Mes now builds reproducibly cross-platform, runs on the
Hurd and has better support for other distributions and kernels.
- 0.21 GNU Mes now supports a Scheme-only bootstrap and is packaged in - 0.21 GNU Mes now supports a Scheme-only bootstrap and is packaged in
Debian GNU/Linux. Debian GNU/Linux.
- 0.20 GNU Mes brings the Reduced Binary Source bootstrap to Guix. - 0.20 GNU Mes brings the Reduced Binary Source bootstrap to Guix.

View File

@ -97,7 +97,7 @@ fi
-I ${srcdest}include -I ${srcdest}include
-I ${srcdest}include/$mes_kernel/$mes_cpu -I ${srcdest}include/$mes_kernel/$mes_cpu
" "
if test "$compiler" != bootstrap; then if test $compiler = gcc; then
${SHELL} ${srcdest}build-aux/build-mes.sh ${SHELL} ${srcdest}build-aux/build-mes.sh
fi fi
) )
@ -108,13 +108,16 @@ fi
cd mescc-lib cd mescc-lib
sed -i s,mes_libc=system,mes_libc=mes, config.sh sed -i s,mes_libc=system,mes_libc=mes, config.sh
mkdir -p include/mes mkdir -p include/mes
cp -p ../include/mes/config.h include/mes/config.h cp ../include/mes/config.h include/mes/config.h
sed -i 's,#define SYSTEM_LIBC 1,#undef SYSTEM_LIBC,' include/mes/config.h sed -i 's,#define SYSTEM_LIBC 1,#undef SYSTEM_LIBC,' include/mes/config.h
if test -z "$srcdest"; then if test -z "$srcdest"; then
srcdest=../ srcdest=../
srcdir=../ srcdir=../
fi fi
AM_CPPFLAGS=" ln -sf ${srcdest}mes .
ln -sf ${srcdest}module .
ln -sf ${srcdest}src .
AM_CPPFLAGS="
-D HAVE_CONFIG_H=1 -D HAVE_CONFIG_H=1
-I ${srcdest}lib -I ${srcdest}lib
-I include -I include
@ -122,8 +125,8 @@ fi
-I ${srcdest}include/$mes_kernel/$mes_cpu -I ${srcdest}include/$mes_kernel/$mes_cpu
" "
compiler=mescc compiler=mescc
AR="${srcdest}pre-inst-env mesar" AR=${MESAR-"${srcdest}pre-inst-env mesar"}
CC="${srcdest}pre-inst-env mescc -m $mes_bits" CC=${MESCC-"${srcdest}pre-inst-env mescc -m $mes_bits"}
# No user overrides for MesCC, they are probably intended for GCC # No user overrides for MesCC, they are probably intended for GCC
CFLAGS= CFLAGS=
CPPFLAGS= CPPFLAGS=

View File

@ -28,6 +28,7 @@ GIT:=@GIT@
GUILD:=@GUILD@ GUILD:=@GUILD@
GUILE:=@GUILE@ GUILE:=@GUILE@
GUILE_EFFECTIVE_VERSION:=@GUILE_EFFECTIVE_VERSION@ GUILE_EFFECTIVE_VERSION:=@GUILE_EFFECTIVE_VERSION@
GUILE_LOAD_PATH:=@GUILE_LOAD_PATH@
GUIX:=@GUIX@ GUIX:=@GUIX@
HELP2MAN:=@HELP2MAN@ HELP2MAN:=@HELP2MAN@
HEX2:=@HEX2@ HEX2:=@HEX2@

View File

@ -29,6 +29,7 @@ GIT="@GIT@"
GUILD="@GUILD@" GUILD="@GUILD@"
GUILE="@GUILE@" GUILE="@GUILE@"
GUILE_EFFECTIVE_VERSION="@GUILE_EFFECTIVE_VERSION@" GUILE_EFFECTIVE_VERSION="@GUILE_EFFECTIVE_VERSION@"
GUILE_LOAD_PATH="@GUILE_LOAD_PATH@"
GUIX="@GUIX@" GUIX="@GUIX@"
HELP2MAN="@HELP2MAN@" HELP2MAN="@HELP2MAN@"
HEX2="@HEX2@" HEX2="@HEX2@"

79
build-aux/gen-cppmach.scm Normal file
View File

@ -0,0 +1,79 @@
#! /bin/sh
# -*-scheme-*-
exec ${GUILE-guile} --no-auto-compile -L $(dirname $0) -C $(dirname $0) -e '(mes-snarf)' -s "$0" "$@"
!#
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;; Usage:
;; GUILE_LOAD_PATH=~/src/nyacc/module MES_ARENA=2000000 MES_MAX_ARENA=$MES_ARENA ./pre-inst-env mes build-aux/gen-cppmach.scm
(cond-expand
(mes
(mes-use-module (mes misc))
(warn 'boo)
(mes-use-module (mes pretty-print))
(mes-use-module (nyacc lang c99 cppmach)))
(guile
(use-modules (mes pretty-print))
(module-define! (resolve-module '(nyacc lalr)) 'pretty-print pretty-print)
(use-modules (nyacc lang c99 cppmach))))
(define (reverse-string-append lst)
(apply string-append (reverse lst)))
(define (call-with-output-file file-name proc)
(let ((port (open-output-file file-name)))
(if (= port -1)
(error 'cannot-open file-name)
(proc port))))
(define (string-every-pred-start-end pred s start end)
(cond ((= start end) #t)
((> start end) (throw 'value-out-of-range "string-every" s start end))
(else (and (string-every-pred-start-end pred s (1+ start) end)
(pred (string-ref s start))))))
(define (string-every pred s . rest)
(let ((start (if (null? rest) 0
(car rest)))
(end (if (or (null? rest) (null? (cdr rest))) (string-length s)
(cadr rest)))
(pred (if (char? pred) (lambda (c) (eq? c pred)) pred)))
(string-every-pred-start-end pred s start end)))
(define (vector-fold proc init vec1 . rest)
(if (null? rest)
(let ((len (vector-length vec1)))
(let loop ((i 0) (result init))
(if (= i len) result
(loop (1+ i) (proc i result (vector-ref vec1 i))))))
(error "VECTOR-FOLD-2-NOT-SUPPORTED")))
(define F_OK 0)
(define (rename-file old new)
(system* "mv" old new)) ;; FIXME: rename is in libc+gnu.
(define (move-if-changed src-file dst-file . rest)
(rename-file src-file dst-file))
(gen-cpp-files ".")

88
configure vendored
View File

@ -3,23 +3,23 @@
MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)' -s "$0" ${1+"$@"} MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)' -s "$0" ${1+"$@"}
!# !#
;;; GNU Mes --- Maxwell Equations of Software ;;; GNU MES --- Maxwell Equations of Software
;;; Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> ;;; Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; ;;;
;;; configure: This file is part of GNU Mes. ;;; configure: This file is part of GNU MES.
;;; ;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it ;;; GNU MES is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by ;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at ;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version. ;;; your option) any later version.
;;; ;;;
;;; GNU Mes is distributed in the hope that it will be useful, but ;;; GNU MES is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details. ;;; GNU General Public License for more details.
;;; ;;;
;;; You should have received a copy of the GNU General Public License ;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>. ;;; along with GNU MES. If not, see <http://www.gnu.org/licenses/>.
(define-module (configure) (define-module (configure)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
@ -155,7 +155,7 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(data dependency-data) (data dependency-data)
(version-found dependency-version-found)) (version-found dependency-version-found))
(define* (make-dep name #:key (version '(0)) optional? (version-option "--version") (commands (list name)) file-name data) (define* (make-dep name #:key (version '()) optional? (version-option "--version") (commands (list name)) file-name data)
(let* ((env-var (getenv (name->shell-name name))) (let* ((env-var (getenv (name->shell-name name)))
(commands (if env-var (cons env-var commands) commands))) (commands (if env-var (cons env-var commands) commands)))
(make-dependency name version optional? version-option commands file-name data #f))) (make-dependency name version optional? version-option commands file-name data #f)))
@ -186,7 +186,12 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(let ((split (string-tokenize string (let ((split (string-tokenize string
(char-set-adjoin char-set:digit #\.)))) (char-set-adjoin char-set:digit #\.))))
(and (pair? split) (and (pair? split)
(let* ((version (sort split (lambda (a b) (> (string-length a) (string-length b))))) (let* ((version (sort split (lambda (a b)
(let ((len-a (length (string-split a #\.)))
(len-b (length (string-split b #\.))))
(cond ((> len-a len-b) #t)
((< len-a len-b) #f)
(else (> (string-length a) (string-length b))))))))
(version (car version)) (version (car version))
(version (string-tokenize version (version (string-tokenize version
(char-set-complement (char-set #\.))))) (char-set-complement (char-set #\.)))))
@ -198,16 +203,17 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(version-option (dependency-version-option dependency)) (version-option (dependency-version-option dependency))
(commands (dependency-commands dependency))) (commands (dependency-commands dependency)))
(let loop ((commands commands)) (let loop ((commands commands))
(if (null? commands) dependency (if (or (null? commands)
(not (car commands))) dependency
(let ((command (car commands))) (let ((command (car commands)))
(stdout "checking for ~a~a... " name (stdout "checking for ~a~a... " (if (string-index command #\space) name command)
(if (null? expected) "" (if (null? expected) ""
(format #f " [~a]" (version->string expected)))) (format #f " [~a]" (version->string expected))))
(let* ((output (gulp-pipe (string-append command " " (if version-option version-option "")))) (let* ((output (gulp-pipe (string-append command " " (if version-option version-option ""))))
(actual (string->version output)) (actual (string->version output))
(pass? (and actual (tuple< expected actual))) (pass? (and actual (tuple< expected actual)))
(dependency (set-field dependency (dependency-version-found) actual))) (dependency (set-field dependency (dependency-version-found) actual)))
(stdout "~a ~a\n" (if pass? (if (pair? actual) "" " yes") (stdout "~a ~a\n" (if pass? (if (pair? actual) "" "yes")
(if actual " no, found" "no")) (if actual " no, found" "no"))
(or (version->string actual) "")) (or (version->string actual) ""))
(if pass? (let ((file-name (or (PATH-search-path command) (if pass? (let ((file-name (or (PATH-search-path command)
@ -273,7 +279,7 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(define (check-compile-string-c cc string) (define (check-compile-string-c cc string)
(with-output-to-file ".config.c" (with-output-to-file ".config.c"
(cut display string)) (cut display string))
(let ((test (lambda _ (apply system* `(,cc "--std=gnu99" "-c" "-o" ".config.o" ,@(cflags-list) ".config.c"))))) (let ((test (lambda _ (apply system* `(,cc "-std=gnu99" "-c" "-o" ".config.o" ,@(cflags-list) ".config.c")))))
(zero? (if %verbose? (test) (zero? (if %verbose? (test)
(with-error-to-file "/dev/null" (with-error-to-file "/dev/null"
test))))) test)))))
@ -281,7 +287,7 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(define (check-link-string-c cc string) (define (check-link-string-c cc string)
(with-output-to-file ".config.c" (with-output-to-file ".config.c"
(cut display string)) (cut display string))
(let ((test (lambda _ (apply system* `(,cc "--std=gnu99" "-o" ".config" ,@(cflags-list) ,@(ldflags-list) ".config.c"))))) (let ((test (lambda _ (apply system* `(,cc "-std=gnu99" "-o" ".config" ,@(cflags-list) ,@(ldflags-list) ".config.c")))))
(zero? (if %verbose? (test) (zero? (if %verbose? (test)
(with-error-to-file "/dev/null" (with-error-to-file "/dev/null"
test))))) test)))))
@ -382,6 +388,7 @@ Some influential environment variables:
LDFLAGS C linker flags LDFLAGS C linker flags
GUILE guile command GUILE guile command
GUILD guild command GUILD guild command
GUILE_LOAD_PATH guile load path; where to find Nyacc
MES_FOR_BUILD build system MES [can be mes or guile] MES_FOR_BUILD build system MES [can be mes or guile]
" PACKAGE VERSION (getenv "prefix"))) " PACKAGE VERSION (getenv "prefix")))
@ -404,6 +411,8 @@ Some influential environment variables:
(includedir (option-ref options 'includedir "${prefix}/include")) (includedir (option-ref options 'includedir "${prefix}/include"))
(libdir (option-ref options 'libdir "${prefix}/lib")) (libdir (option-ref options 'libdir "${prefix}/lib"))
(pkgdatadir (string-append datadir "/mes")) (pkgdatadir (string-append datadir "/mes"))
(guile-load-path (if (and (pair? %load-path) (equal? (car %load-path) ".")) (cdr %load-path)
%load-path))
(guile-effective-version (effective-version)) (guile-effective-version (effective-version))
(guile-site-dir (if (equal? prefix ".") (canonicalize-path ".") (guile-site-dir (if (equal? prefix ".") (canonicalize-path ".")
(string-append prefix "/share/guile/site/" guile-effective-version))) (string-append prefix "/share/guile/site/" guile-effective-version)))
@ -436,12 +445,10 @@ Some influential environment variables:
(when %verbose? (when %verbose?
(stderr "configure args=~s\n" args)) (stderr "configure args=~s\n" args))
(for-each (lambda (v) (apply setenv (string-split v #\=))) vars) (for-each (lambda (v) (apply setenv (string-split v #\=))) vars)
(let* ((tinycc-prefix (or (getenv "TINYCC_PREFIX") (let* ((cross? (not (equal? host-type build-type)))
(string-append srcdest "../tinycc-prefix"))) (gcc (if cross? (string-append host-type "-" "gcc") "gcc"))
(cross? (not (equal? host-type build-type))) (tcc (if cross? (string-append host-type "-" "tcc") "tcc"))
(gcc (or (getenv "CC") (if cross? (string-append host-type "-" "gcc") "gcc"))) (mescc (if cross? (string-append host-type "-" "mescc") "mescc"))
(tcc (or (getenv "TCC") "tcc"))
(mescc (or (getenv "MESCC") "mescc"))
(deps (fold (lambda (program results) (deps (fold (lambda (program results)
(cons (check-program-version program) results)) (cons (check-program-version program) results))
'() '()
@ -453,12 +460,18 @@ Some influential environment variables:
(make-dep "mes" #:version '(0 20) #:optional? #t) (make-dep "mes" #:version '(0 20) #:optional? #t)
(make-dep "guix" #:version '(0 13) #:optional? #t) (make-dep "guix" #:version '(0 13) #:optional? #t)
(make-dep "ar" #:version '(2 10) #:optional? #t) (make-dep "ar" #:version '(2 10) #:optional? #t)
(make-dep "sh" #:version '(0) #:optional? #t) (make-dep "sh" #:optional? #t)
(make-dep "bash" #:version '(2 0) #:optional? #t) (make-dep "bash" #:version '(2 0) #:optional? #t)
(make-dep "guild" #:version '(2 0) #:commands '("guild" "guile-tools" "true")) (make-dep "guild" #:version '(2 0) #:commands '("guild" "guile-tools" "true"))
(make-dep "cc" #:commands (list gcc "cc" tcc mescc) #:optional? #t) (make-dep "CC" #:commands `(,(getenv "CC")) #:optional? #t)
(make-dep "CC-v" #:commands `(,(getenv "CC")) #:optional? #t #:version-option "-v")
(make-dep "cc" #:commands '("cc") #:optional? #t)
(make-dep "gcc" #:commands `(,gcc "gcc") #:optional? #t)
(make-dep "mescc" #:commands `(,mescc "mescc") #:optional? #t)
(make-dep "tcc" #:commands `(,tcc "tcc") #:optional? #t #:version-option "-v")
(make-dep "cc-v" #:commands '("cc") #:optional? #t #:version-option "-v")
(make-dep "make" #:optional? #t #:commands '("gmake" "make")) (make-dep "make" #:optional? #t #:commands '("gmake" "make"))
(make-dep "makeinfo" #:optional? #t) (make-dep "makeinfo" #:version '(6) #:optional? #t)
(make-dep "dot" #:version-option "-V" #:optional? #t) (make-dep "dot" #:version-option "-V" #:optional? #t)
(make-dep "help2man" #:version '(1 47) #:optional? #t) (make-dep "help2man" #:version '(1 47) #:optional? #t)
(make-dep "perl" #:version '(5) #:optional? #t)))) (make-dep "perl" #:version '(5) #:optional? #t))))
@ -467,15 +480,18 @@ Some influential environment variables:
deps) deps)
deps)) deps))
(guile (or guile "guile")) (guile (or guile "guile"))
(cc (file-name "cc" deps)) (cc (or (file-name "CC" deps)
(file-name "CC-v" deps)
(file-name "tcc" deps)
(file-name "gcc" deps)
(file-name "cc" deps)
(file-name "cc-v" deps)
(file-name "mescc" deps)))
(deps (if cc (deps (if cc
(cons* (check-header-c cc (make-dep "limits.h")) (cons* (check-header-c cc (make-dep "limits.h"))
(check-header-c cc (make-dep "stdio.h" #:optional? #t)) (check-header-c cc (make-dep "stdio.h" #:optional? #t))
deps) deps)
deps)) deps))
(deps (cons (check-file (make-dep "tinycc-prefix" #:optional? #t
#:file-name tinycc-prefix))
deps))
(missing (filter (conjoin (negate dependency-file-name) (missing (filter (conjoin (negate dependency-file-name)
(negate dependency-optional?)) deps)) (negate dependency-optional?)) deps))
(deps (if cc (deps (if cc
@ -493,21 +509,22 @@ Some influential environment variables:
")) "))
deps) deps)
deps)) deps))
(mesc? (file-name "cc is Mes C" deps)) (mesc? (file-name "cc is MES C" deps))
(deps (if cc (deps (if cc
(cons (check-compile-c cc (make-dep "cc is Tiny CC" #:data "#if !defined (__TINYCC__) (cons (check-compile-c cc (make-dep "cc is Tiny C" #:data "#if !defined (__TINYC__)
#error no tinycc #error no tinycc
#endif #endif
")) "))
deps) deps)
deps)) deps))
(tcc? (file-name "cc is Tiny CC" deps)) (tcc? (file-name "cc is Tiny C" deps))
(deps (if cc (deps (if cc
(cons (check-link-c cc (make-dep "if cc can create executables" #:data "int main () {return 0;}")) (cons (check-link-c cc (make-dep "whether cc can create executables" #:data "int main () {return 0;}"))
deps) deps)
deps)) deps))
(system-libc? (and with-system-libc? (file-name "if cc can create executables" deps))) (system-libc? (and with-system-libc? (file-name "if cc can create executables" deps)))
(host-type (or (and cc (gulp-pipe* cc "-dumpmachine")) host-type)) (host-type (or (and cc (let ((dump (gulp-pipe* cc "-dumpmachine")))
(and (not (string-null? dump)) dump))) host-type))
(host-type-list (string-split host-type #\-)) (host-type-list (string-split host-type #\-))
(mes-cpu (car host-type-list)) (mes-cpu (car host-type-list))
(mes-cpu (cond ((member mes-cpu '("i386" "i486" "i586" "i686")) "x86") (mes-cpu (cond ((member mes-cpu '("i386" "i486" "i586" "i686")) "x86")
@ -521,7 +538,7 @@ Some influential environment variables:
(cut member <> '("pc" "portbld" "unknown"))) (cut member <> '("pc" "portbld" "unknown")))
(cdr host-type-list)))) (cdr host-type-list))))
(mes-kernel (if (string-prefix? "freebsd" mes-kernel) "freebsd" mes-kernel)) (mes-kernel (if (string-prefix? "freebsd" mes-kernel) "freebsd" mes-kernel))
(compiler (if gcc? "gcc" "mescc")) (mes-compiler (cond (gcc? "gcc") (tcc? "gcc") (else "mescc")))
(mes-system (string-join (list mes-cpu mes-kernel "mes") "-")) (mes-system (string-join (list mes-cpu mes-kernel "mes") "-"))
(bash (or (and (file-exists? "/bin/bash") "/bin/bash") (bash (or (and (file-exists? "/bin/bash") "/bin/bash")
(file-name "bash" deps) (file-name "bash" deps)
@ -572,7 +589,7 @@ See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
("@bootstrap@" . ,(if with-bootstrap? "true" "false")) ("@bootstrap@" . ,(if with-bootstrap? "true" "false"))
("@courageous@" . ,(if with-courage? "true" "false")) ("@courageous@" . ,(if with-courage? "true" "false"))
("@compiler@" . ,compiler) ("@compiler@" . ,mes-compiler)
("@mes_bits@" . ,mes-bits) ("@mes_bits@" . ,mes-bits)
("@mes_kernel@" . ,mes-kernel) ("@mes_kernel@" . ,mes-kernel)
("@mes_cpu@" . ,mes-cpu) ("@mes_cpu@" . ,mes-cpu)
@ -600,17 +617,18 @@ See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
("@mandir@" . ,mandir) ("@mandir@" . ,mandir)
("@sysconfdir@" . ,sysconfdir) ("@sysconfdir@" . ,sysconfdir)
("@GUILE_EFFECTIVE_VERSION@" . ,(effective-version))
("@colors@" . ,(if disable-colors? "no" "yes")) ("@colors@" . ,(if disable-colors? "no" "yes"))
("@V@" . ,(if disable-silent-rules? "1" "0")) ("@V@" . ,(if disable-silent-rules? "1" "0"))
("@AR@" . ,(or (file-name "ar" deps) "")) ("@AR@" . ,(or (file-name "ar" deps) ""))
("@BASH@" . ,bash) ("@BASH@" . ,bash)
("@CC@" . ,(or (file-name "cc" deps) "")) ("@CC@" . ,cc)
("@DIFF@" . ,(or (file-name "diff" deps) (string-append abs-top-builddir "/pre-inst-env diff.scm"))) ("@DIFF@" . ,(or (file-name "diff" deps) (string-append abs-top-builddir "/pre-inst-env diff.scm")))
("@DOT@" . ,(or (file-name "dot" deps) "")) ("@DOT@" . ,(or (file-name "dot" deps) ""))
("@GIT@" . ,(or (file-name "git" deps) "")) ("@GIT@" . ,(or (file-name "git" deps) ""))
("@GUILE@" . ,guile) ("@GUILE@" . ,guile)
("@GUILE_EFFECTIVE_VERSION@" . ,(effective-version))
("@GUILE_LOAD_PATH@" . ,(string-join guile-load-path ":"))
("@GUIX@" . ,(or (file-name "guix" deps) "")) ("@GUIX@" . ,(or (file-name "guix" deps) ""))
("@HELP2MAN@" . ,(or (file-name "help2man" deps) "")) ("@HELP2MAN@" . ,(or (file-name "help2man" deps) ""))
("@MAKEINFO@" . ,(or (file-name "makeinfo" deps) "")) ("@MAKEINFO@" . ,(or (file-name "makeinfo" deps) ""))
@ -682,7 +700,7 @@ See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
(let ((make (and=> (file-name "make" deps) basename))) (let ((make (and=> (file-name "make" deps) basename)))
(display (string-append " (display (string-append "
GNU Mes is configured for GNU Mes is configured for
compiler: " compiler " compiler: " mes-compiler "
cpu: " mes-cpu " cpu: " mes-cpu "
bits: " mes-bits " bits: " mes-bits "
libc: " mes-libc " libc: " mes-libc "

View File

@ -122,7 +122,7 @@ subst () {
-e s,"@PACKAGE_NAME@,$PACKAGE_NAME,"\ -e s,"@PACKAGE_NAME@,$PACKAGE_NAME,"\
-e s,"@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,"\ -e s,"@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,"\
-e s,"@VERSION@,$VERSION,"\ -e s,"@VERSION@,$VERSION,"\
-e s,"@bootstrap@,yes,"\ -e s,"@bootstrap@,true,"\
-e s,"@build@,$build,"\ -e s,"@build@,$build,"\
-e s,"@host@,$host,"\ -e s,"@host@,$host,"\
-e s,"@compiler@,$compiler,"\ -e s,"@compiler@,$compiler,"\
@ -151,6 +151,7 @@ subst () {
-e s,"@pkgdatadir@,$pkgdatadir,"\ -e s,"@pkgdatadir@,$pkgdatadir,"\
-e s,"@sysconfdir@,$sysconfdir,"\ -e s,"@sysconfdir@,$sysconfdir,"\
-e s,"@GUILE_EFFECTIVE_VERSION@,$GUILE_EFFECTIVE_VERSION,"\ -e s,"@GUILE_EFFECTIVE_VERSION@,$GUILE_EFFECTIVE_VERSION,"\
-e s,"@GUILE_LOAD_PATH@,$GUILE_LOAD_PATH,"\
-e s,"@V@,$V,"\ -e s,"@V@,$V,"\
-e s,"@AR@,$AR,"\ -e s,"@AR@,$AR,"\
-e s,"@BASH@,$BASH,"\ -e s,"@BASH@,$BASH,"\

View File

@ -37,18 +37,18 @@ Packages are available in Guix master.
GNU Mes[0] brings a Reduced Binary Seed bootstrap[1] to GNU Guix[2]. GNU Mes[0] brings a Reduced Binary Seed bootstrap[1] to GNU Guix[2].
This bootstrap has halved the size of opaque, uninspectable binaries This bootstrap has halved the size of opaque, uninspectable binaries
that were needed to bootstrap Guix. The final goal is to help create that were needed to bootstrap Guix 1.0. The final goal is to help
a full source bootstrap as part of the bootstrappable builds[3] effort create a full source bootstrap as part of the bootstrappable builds[3]
for any interested UNIX-like operating system. effort for any interested UNIX-like operating system.
It consists of a mutual self-hosting Scheme interpreter written in Mes consists of a mutual self-hosting Scheme interpreter written in
~5,000 LOC of simple C and a Nyacc-based C compiler written in Scheme. ~5,000 LOC of simple C, and a C compiler written in Scheme. This
This mes.c is being simplified[4] to be transpiled by M2-Planet[5]. mes.c is being simplified[4] to be transpiled by M2-Planet[5].
The Scheme interpreter has a Garbage Collector, a library of loadable The Scheme interpreter has a Garbage Collector, a library of loadable
Scheme modules-- notably Dominique Boucher's LALR[6], Pre-R6RS Scheme modules-- notably Dominique Boucher's LALR[6], Pre-R6RS
[portable syntax-case[7] with R7RS ellipsis, Matt Wette's Nyacc[8] [portable syntax-case[7] with R7RS ellipsis, Matt Wette's Nyacc[8]
--and test suite just enough to support a REPL and a C99 compiler: --and test suite, just enough to support a REPL and a C99 compiler:
MesCC. MesCC.
Mes+MesCC can compile an only lightly patched TinyCC[9] that is Mes+MesCC can compile an only lightly patched TinyCC[9] that is

View File

@ -29,7 +29,7 @@ Documentation License''.
* mes: (mes)Invoking mes. Running Mes, a minimalist Guile lookalike. * mes: (mes)Invoking mes. Running Mes, a minimalist Guile lookalike.
* mescc: (mes)Invoking MesCC. Running the MesCC bootstrap compiler. * mescc: (mes)Invoking mescc. Running the MesCC bootstrap compiler.
@end direntry @end direntry
@titlepage @titlepage
@ -48,7 +48,7 @@ Edition @value{EDITION} @*
@contents @contents
@c ********************************************************************* @c *********************************************************************
@node Top @node Top, Introduction, (dir), (dir)
@top GNU Mes @top GNU Mes
This document describes GNU Mes version @value{VERSION}, a bootstrappable This document describes GNU Mes version @value{VERSION}, a bootstrappable
@ -73,6 +73,7 @@ Software Freedom
* Reproducible Builds:: Reproducibility and free software. * Reproducible Builds:: Reproducibility and free software.
* Bootstrappable Builds:: The freedom to build a software without binary seed. * Bootstrappable Builds:: The freedom to build a software without binary seed.
* Full Source Bootstrap:: Software dependencies worthy of GNU. * Full Source Bootstrap:: Software dependencies worthy of GNU.
* LISP as Maxwell's Equations of Software:: Auditable elegance.
Installation Installation
@ -83,15 +84,15 @@ Installation
Bootstrapping Bootstrapping
* The Mes Bootstrap Process:: How Mes will make you yogurt from pure milk. * The Mes Bootstrap Process:: How Mes will make you yogurt from pure milk.
* Invoking Mes:: Running Mes, a minimalist Guile lookalike. * Invoking mes:: Running Mes, a minimalist Guile lookalike.
* Invoking MesCC:: Running the MesCC bootstrap compiler. * Invoking mescc:: Running the MesCC bootstrap compiler.
* Invoking mesar:: * Invoking mesar::
Invoking Mes Invoking mes
* Environment Variables:: If the bits won't change, change their habitat. * Environment Variables:: If the bits won't change, change their habitat.
Invoking MesCC Invoking mescc
* MesCC Environment Variables:: There's no NIX like POSIX. * MesCC Environment Variables:: There's no NIX like POSIX.
@ -108,7 +109,7 @@ Contributing
@end menu @end menu
@c ********************************************************************* @c *********************************************************************
@node Introduction @node Introduction, Installation, Top, Top
@chapter Introduction @chapter Introduction
@quotation @quotation
@ -187,9 +188,10 @@ Freedom 1.
* Reproducible Builds:: Reproducibility and free software. * Reproducible Builds:: Reproducibility and free software.
* Bootstrappable Builds:: The freedom to build a software without binary seed. * Bootstrappable Builds:: The freedom to build a software without binary seed.
* Full Source Bootstrap:: Software dependencies worthy of GNU. * Full Source Bootstrap:: Software dependencies worthy of GNU.
* LISP as Maxwell's Equations of Software:: Auditable elegance.
@end menu @end menu
@node Reproducible Builds @node Reproducible Builds, Bootstrappable Builds, Introduction, Introduction
@section Reproducible Builds @section Reproducible Builds
The current Reproducible Builds effort incubated in the Debian The current Reproducible Builds effort incubated in the Debian
@ -238,7 +240,7 @@ packages could be rebuild bit-identical from source.
@author Martin Uecker @author Martin Uecker
@end quotation @end quotation
@node Bootstrappable Builds @node Bootstrappable Builds, Full Source Bootstrap, Reproducible Builds, Introduction
@section Bootstrappable Builds @section Bootstrappable Builds
Software distributions that take reproducible builds seriously are Software distributions that take reproducible builds seriously are
@ -250,14 +252,14 @@ opaque ascii or binary @emph{seeds} that are injected during build
time. Yes, a package may build reproduciblly from all inspectable time. Yes, a package may build reproduciblly from all inspectable
sourcess...but what functionality is programmed in the opaque seed? sourcess...but what functionality is programmed in the opaque seed?
@subsection Bootstrap Binaries @subsection Bootstrap Binary Seed
Possibly one of the most harmless, but certainly by far the biggest Possibly one of the most harmless, but certainly by far the biggest
binary seed that all software distributions inject are the so called binary seed that all software distributions inject are the so called
@emph{bootstrap binaries}. Bootstrap binaries are the initial binary @emph{bootstrap binary seed}. Bootstrap binaries are the initial binary
seeds that are used to start building the distribution. seeds that are used to start building the distribution.
The GNU Guix operating system, version 1.0 had a relatively small The GNU Guix operating system, version 1.0 had a relatively small
closure of bootstrap binaries: GNU binutils, GNU gcc, GNU Libc, GNU closure of bootstrap binary seed: GNU binutils, GNU gcc, GNU Libc, GNU
Guile, and ``Static binaries'' (think: bash, bzip2, coreutils, gawk, Guile, and ``Static binaries'' (think: bash, bzip2, coreutils, gawk,
grep, gzip, patch, sed, tar, xz). grep, gzip, patch, sed, tar, xz).
@ -287,17 +289,17 @@ $ du -schx *
@end example @end example
During the Guix 1.1 development series we managed to create the first During the Guix 1.1 development series we managed to create the first
reduction by 50% of the Guix @emph{bootstrap binaries}@footnote{See reduction by 50% of the Guix @emph{bootstrap binary seed}@footnote{See
@url{https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/}}. @url{https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/}}.
This was a very important step because the ~250MB @emph{seed} of binary This was a very important step because the ~250MB @emph{seed} of binary
code was practically non-auditable, which makes it hard to establish code was practically non-auditable, which makes it hard to establish
what source code produced them. what source code produced them.
@node Full Source Bootstrap @node Full Source Bootstrap, , Bootstrappable Builds, Introduction
@section Full Source Bootstrap @section Full Source Bootstrap
There is an obvious solution: we cannot allow any binary seeds in our There is an obvious solution: we cannot allow any binary seeds in our
software stack. Not even in the bootstrap binaries. Maybe that is a software stack. Not even in the bootstrap binary seed. Maybe that is a
bit too strong: we want to have the absolute minimum of binary seeds and bit too strong: we want to have the absolute minimum of binary seeds and
all binary seeds need to be inspectable and must be reviewed. How big all binary seeds need to be inspectable and must be reviewed. How big
would the absolute minimal set be? would the absolute minimal set be?
@ -321,8 +323,8 @@ of the @var{hex} function
@end example @end example
All computer programs look like this: an opaque list of computer codes. All computer programs look like this: an opaque list of computer codes.
The initial programs that we take for granted---the bootstrap The initial programs that we take for granted---the bootstrap binary
binaries---are about 250MB of such numbers: think 250,000 pages full of seed---are about 250MB of such numbers: think 250,000 pages full of
numbers. numbers.
Most computers work pretty well so apparently there is not a pressing Most computers work pretty well so apparently there is not a pressing
@ -407,7 +409,8 @@ nothing to all of the programs that our computer runs. Something that
seemed to be an impossible dream is suddenly starting to look like seemed to be an impossible dream is suddenly starting to look like
``just a couple years of work''. ``just a couple years of work''.
@subsection LISP as Maxwell's Equations of Software @node LISP as Maxwell's Equations of Software
@section LISP as Maxwell's Equations of Software
As fate would have it, I stumbled upon this As fate would have it, I stumbled upon this
@url{https://queue.acm.org/detail.cfm?id=1039523, interview with Alan @url{https://queue.acm.org/detail.cfm?id=1039523, interview with Alan
@ -426,7 +429,7 @@ over.
@end quotation @end quotation
Our starting point is @file{hex0}, a 500 byte hex assembler and we need Our starting point is @file{hex0}, a 500 byte hex assembler and we need
to somehow close the gap to building the bootstrap binaries, esp. GNU to somehow close the gap to building the bootstrap binary seed, esp. GNU
Gcc and the GNU C Library. What better way to do that than by Gcc and the GNU C Library. What better way to do that than by
leveraging the powers of LISP? leveraging the powers of LISP?
@ -435,8 +438,49 @@ will be indirectly bootstrapped from @file{hex0} and that wields the
magical powers of LISP to close the bootstrap gap, asserting we can magical powers of LISP to close the bootstrap gap, asserting we can
enjoy software Freedom 1. enjoy software Freedom 1.
@subsection Auditable Elegance
@code{eval} and @code{apply} are mutual recursing functions that---using
a few helper functions---describe the core of the universe of computing.
@lisp
(define (apply fn x a)
(cond
((atom fn)
(cond
((eq fn CAR) (caar x))
((eq fn CDR) (cdar x))
((eq fn CONS) (cons (car x) (cadr x)))
((eq fn ATOM) (atom (car x)))
((eq fn EQ) (eq (car x) (cadr x)))
(#t (apply (eval fn a) x a))))
((eq (car fn) LAMBDA)
(eval (caddr fn) (pairlis (cadr fn) x a)))
((eq (car fn) LABEL)
(apply (caddr fn) x
(cons (cons (cadr fn) (caddr fn)) a)))))
@end lisp
@lisp
(define (eval e a)
(cond
((atom e) (cdr (assoc e a)))
((atom (car e))
(cond ((eq (car e) QUOTE) (cadr e))
((eq (car e) COND) (evcon (cdr e) a))
(#t (apply (car e) (evlis (cdr e) a) a))))
(#t (apply (car e) (evlis (cdr e) a) a))))
@end lisp
It will be a big day when our computers are fully bootstrapped from
source. It would be nice if that source code were readable, auditable
and elegant. To be honest, the elegance displayed above that we
achieved at the very start of the Mes project is currently hard to find.
It is our sincerest hope to bring back this level of quality and
elegance..
@c ********************************************************************* @c *********************************************************************
@node Installation @node Installation, Bootstrapping, Introduction, Top
@chapter Installation @chapter Installation
@cindex installing Mes @cindex installing Mes
@ -452,7 +496,7 @@ to use it.
* Running the Test Suites:: Testing Mes. * Running the Test Suites:: Testing Mes.
@end menu @end menu
@node Regular Requirements @node Regular Requirements, Bootstrap Requirements, Installation, Installation
@section Regular Requirements @section Regular Requirements
This section lists requirements when building Mes from source. The This section lists requirements when building Mes from source. The
@ -476,7 +520,7 @@ Mes is compatible with GNU Guile, so it is possible to share the same
Scheme code between both. Currently Mes only supports the minimal Scheme code between both. Currently Mes only supports the minimal
subset of R5RS and Guile extensions to run MesCC. subset of R5RS and Guile extensions to run MesCC.
@node Bootstrap Requirements @node Bootstrap Requirements, Running the Test Suites, Regular Requirements, Installation
@section Bootstrap Requirements @section Bootstrap Requirements
This section lists requirements when building Mes as a bootstrap This section lists requirements when building Mes as a bootstrap
@ -501,7 +545,7 @@ Bootstrapping Mes depends on the following packages:
@item @url{https://savannah.gnu.org/projects/nyacc/, NYACC}, 0.93.0 or later, including 0.99.0. @item @url{https://savannah.gnu.org/projects/nyacc/, NYACC}, 0.93.0 or later, including 0.99.0.
@end itemize @end itemize
@node Running the Test Suites @node Running the Test Suites, , Bootstrap Requirements, Installation
@section Running the Test Suites @section Running the Test Suites
@cindex test suites @cindex test suites
@ -544,7 +588,7 @@ CC=gcc CC32=i686-unknown-linux-gnu-gcc MES=guile \
build-aux/test.sh scaffold/tests/00-exit-0 build-aux/test.sh scaffold/tests/00-exit-0
@end example @end example
@node Bootstrapping @node Bootstrapping, Contributing, Installation, Top
@chapter Bootstrapping @chapter Bootstrapping
@quotation @quotation
@ -584,12 +628,12 @@ responsibility.
@menu @menu
* The Mes Bootstrap Process:: How Mes will make you yogurt from pure milk. * The Mes Bootstrap Process:: How Mes will make you yogurt from pure milk.
* Invoking Mes:: Running Mes, a minimalist Guile lookalike. * Invoking mes:: Running Mes, a minimalist Guile lookalike.
* Invoking MesCC:: Running the MesCC bootstrap compiler. * Invoking mescc:: Running the MesCC bootstrap compiler.
* Invoking mesar:: * Invoking mesar::
@end menu @end menu
@node The Mes Bootstrap Process @node The Mes Bootstrap Process, Invoking mes, Bootstrapping, Bootstrapping
@section The Mes Bootstrap Process @section The Mes Bootstrap Process
The Reduced Binary Seed bootstrap currently adopted by Guix@footnote{See The Reduced Binary Seed bootstrap currently adopted by Guix@footnote{See
@ -667,8 +711,8 @@ Although we think these are less essential and thus less interesting
than the GNU toolchain triplet that we focussed on initially, our next than the GNU toolchain triplet that we focussed on initially, our next
priority is to eleminate these one by one. priority is to eleminate these one by one.
@node Invoking Mes @node Invoking mes, Invoking mescc, The Mes Bootstrap Process, Bootstrapping
@section Invoking Mes @section Invoking mes
@cindex repl @cindex repl
The @command{mes} command is the Scheme interpreter whose prime The @command{mes} command is the Scheme interpreter whose prime
@ -687,13 +731,13 @@ The @var{option}s can be among the following:
@item -s @var{script} @var{arg}@dots{} @item -s @var{script} @var{arg}@dots{}
@cindex script mode @cindex script mode
By default, Mes will read a file named on the command line as a script. By default, mes will read a file named on the command line as a script.
Any command-line arguments @var{arg}@dots{} following @var{script} Any command-line arguments @var{arg}@dots{} following @var{script}
become the script's arguments; the @code{command-line} function returns become the script's arguments; the @code{command-line} function returns
a list of strings of the form @code{(@var{script} @var{arg}@dots{})}. a list of strings of the form @code{(@var{script} @var{arg}@dots{})}.
Scripts are read and evaluated as Scheme source code just as the Scripts are read and evaluated as Scheme source code just as the
@code{load} function would. After loading @var{script}, Mes exits. @code{load} function would. After loading @var{script}, mes exits.
@item -c @var{expr} @var{arg}@dots{} @item -c @var{expr} @var{arg}@dots{}
@cindex evaluate expression, command-line argument @cindex evaluate expression, command-line argument
@ -701,7 +745,7 @@ Evaluate @var{expr} as Scheme code, and then exit. Any command-line
arguments @var{arg}@dots{}) following @var{expr} become command-line arguments @var{arg}@dots{}) following @var{expr} become command-line
arguments; the @code{command-line} function returns a list of strings of arguments; the @code{command-line} function returns a list of strings of
the form @code{(@var{guile} @var{arg}@dots{})}, where @var{mes} is the the form @code{(@var{guile} @var{arg}@dots{})}, where @var{mes} is the
path of the Mes executable. path of the mes executable.
@item -- @var{arg}@dots{} @item -- @var{arg}@dots{}
Run interactively, prompting the user for expressions and evaluating Run interactively, prompting the user for expressions and evaluating
@ -709,7 +753,7 @@ them. Any command-line arguments @var{arg}@dots{} following the
@option{--} become command-line arguments for the interactive session; @option{--} become command-line arguments for the interactive session;
the @code{command-line} function returns a list of strings of the form the @code{command-line} function returns a list of strings of the form
@code{(@var{guile} @var{arg}@dots{})}, where @var{mes} is the path of the @code{(@var{guile} @var{arg}@dots{})}, where @var{mes} is the path of the
Mes executable. mes executable.
@item -L,--load-path=@var{directory} @item -L,--load-path=@var{directory}
Add @var{directory} to the front of Mes module load path. The given Add @var{directory} to the front of Mes module load path. The given
@ -732,10 +776,10 @@ and the command-line arguments---the list provided by the
@code{command-line} function. @code{command-line} function.
@item -h@r{, }--help @item -h@r{, }--help
Display help on invoking Mes, and then exit. Display help on invoking mes, and then exit.
@item -v@r{, }--version @item -v@r{, }--version
Display the current version of Mes, and then exit. Display the current version of mes%, and then exit.
@end table @end table
@ -743,7 +787,7 @@ Display the current version of Mes, and then exit.
* Environment Variables:: If the bits won't change, change their habitat. * Environment Variables:: If the bits won't change, change their habitat.
@end menu @end menu
@node Environment Variables @node Environment Variables, , Invoking mes, Invoking mes
@subsection Environment Variables @subsection Environment Variables
@cindex environment variables @cindex environment variables
@cindex shell @cindex shell
@ -752,13 +796,13 @@ Display the current version of Mes, and then exit.
@c Hmm, I expected this paragraph in the Guix manual? @c Hmm, I expected this paragraph in the Guix manual?
Here are the environment variables (see @pxref{Environment Variables,,, Here are the environment variables (see @pxref{Environment Variables,,,
guile, Guile Reference}) that affect the run-time behavior of guile, Guile Reference}) that affect the run-time behavior of
Mes: mes:
@table @env @table @env
@item MES_BOOT @item MES_BOOT
@vindex MES_BOOT @vindex MES_BOOT
Set @env{MES_BOOT} to change the initial Scheme program that Mes runs. Set @env{MES_BOOT} to change the initial Scheme program that mes runs.
@item MES_ARENA @item MES_ARENA
@vindex MES_ARENA @vindex MES_ARENA
@ -821,8 +865,8 @@ Mes uses @var{@strong{GUILE}_LOAD_PATH} for compatibility with Guile.
@end table @end table
@node Invoking MesCC @node Invoking mescc, Invoking mesar, Invoking mes, Bootstrapping
@section Invoking MesCC @section Invoking mescc
@example @example
mescc @var{option}@dots{} @file{FILE}@dots{} mescc @var{option}@dots{} @file{FILE}@dots{}
@ -902,14 +946,14 @@ specify LANGUAGE of the following input files
* MesCC Environment Variables:: There's no NIX like POSIX. * MesCC Environment Variables:: There's no NIX like POSIX.
@end menu @end menu
@node MesCC Environment Variables @node MesCC Environment Variables, , Invoking mescc, Invoking mescc
@subsection MesCC Environment Variables @subsection MesCC Environment Variables
@table @env @table @env
@item MES @item MES
@vindex MES @vindex MES
Setting @env{MES} to a mes-compatible Scheme will run MesCC using that Setting @env{MES} to a mes-compatible Scheme will run mescc using that
@example @example
MES=guile mescc -c scaffold/main.c MES=guile mescc -c scaffold/main.c
@end example @end example
@ -931,7 +975,7 @@ during the parsing phase.
@end table @end table
@node Invoking mesar @node Invoking mesar, , Invoking mescc, Bootstrapping
@section Invoking mesar @section Invoking mesar
@example @example
@ -961,7 +1005,7 @@ display version and exit
@end table @end table
@c ********************************************************************* @c *********************************************************************
@node Contributing @node Contributing, Acknowledgments, Bootstrapping, Top
@chapter Contributing @chapter Contributing
@menu @menu
@ -973,7 +1017,7 @@ display version and exit
* Submitting Patches:: Share your work. * Submitting Patches:: Share your work.
@end menu @end menu
@node Building from Git @node Building from Git, Running Mes From the Source Tree, Contributing, Contributing
@section Building from Git @section Building from Git
If you want to hack GNU Mes itself, it is recommended to use the latest If you want to hack GNU Mes itself, it is recommended to use the latest
@ -997,7 +1041,7 @@ Finally, you have to invoke @code{make check} to run tests
installation instructions (@pxref{Installation}) or send a message to installation instructions (@pxref{Installation}) or send a message to
the @email{bug-mes@@gnu.org} mailing list. the @email{bug-mes@@gnu.org} mailing list.
@node Running Mes From the Source Tree @node Running Mes From the Source Tree, Porting GNU Mes, Building from Git, Contributing
@section Running Mes From the Source Tree @section Running Mes From the Source Tree
First, you need to have an environment with all the dependencies First, you need to have an environment with all the dependencies
@ -1005,7 +1049,7 @@ available (@pxref{Building from Git}), and then simply prefix each
command by @command{./pre-inst-env} (the @file{pre-inst-env} script command by @command{./pre-inst-env} (the @file{pre-inst-env} script
lives in the top build tree of Mes). lives in the top build tree of Mes).
@node Porting GNU Mes @node Porting GNU Mes, The Perfect Setup, Running Mes From the Source Tree, Contributing
@section Porting GNU Mes @section Porting GNU Mes
Mes was written for x86-linux. A 64 bit (x86_64) is almost done, only a Mes was written for x86-linux. A 64 bit (x86_64) is almost done, only a
@ -1017,13 +1061,13 @@ An ARM (armv4/armv7l) linux port is underway. A port to GNU/Hurd
Initial scaffold, built by @file{build-aux/build-scaffold.sh}: Initial scaffold, built by @file{build-aux/build-scaffold.sh}:
@example @example
@file{lib/x86-mes-gcc/exit-42.S} @file{lib/linux/x86-mes-gcc/exit-42.S}
@file{lib/x86-mes/elf32-0exit-42.hex2} @file{lib/linux/x86-mes/elf32-0exit-42.hex2}
@file{lib/x86-mes/elf32-body-exit-42.hex2} @file{lib/linux/x86-mes/elf32-body-exit-42.hex2}
@file{lib/x86-mes-gcc/hello-mes.S} @file{lib/linux/x86-mes-gcc/hello-mes.S}
@file{lib/x86-mes/elf32-0hello-mes.hex2} @file{lib/linux/x86-mes/elf32-0hello-mes.hex2}
@file{lib/x86-mes/elf32-body-hello-mes.hex2} @file{lib/linux/x86-mes/elf32-body-hello-mes.hex2}
@end example @end example
Porting MesCC: Porting MesCC:
@ -1038,7 +1082,7 @@ Porting MesCC:
@file{mes/module/mescc/i386/info.mes} @file{mes/module/mescc/i386/info.mes}
@end example @end example
@node The Perfect Setup @node The Perfect Setup, Coding Style, Porting GNU Mes, Contributing
@section The Perfect Setup @section The Perfect Setup
The Perfect Setup to hack on Mes is basically the perfect setup used The Perfect Setup to hack on Mes is basically the perfect setup used
@ -1053,7 +1097,7 @@ on-line documentation (docstrings), context-sensitive completion,
@kbd{M-.} to jump to an object definition, a REPL to try out your code, @kbd{M-.} to jump to an object definition, a REPL to try out your code,
and more (@pxref{Introduction,,, geiser, Geiser User Manual}). and more (@pxref{Introduction,,, geiser, Geiser User Manual}).
@node Coding Style @node Coding Style, Submitting Patches, The Perfect Setup, Contributing
@section Coding Style @section Coding Style
In general our code follows the GNU Coding Standards (@pxref{Top,,, In general our code follows the GNU Coding Standards (@pxref{Top,,,
@ -1089,7 +1133,7 @@ Additionally, in Mes we prefer to format @code{if} statements like this
else)) else))
@end example @end example
@node Submitting Patches @node Submitting Patches, , Coding Style, Contributing
@section Submitting Patches @section Submitting Patches
Development is done using the Git distributed version control system. Development is done using the Git distributed version control system.
@ -1139,7 +1183,7 @@ Join us on @code{#bootstrappable} on the Freenode IRC network or on
Please send bug reports with full details to @email{bug-mes@@gnu.org}. Please send bug reports with full details to @email{bug-mes@@gnu.org}.
@c ********************************************************************* @c *********************************************************************
@node Acknowledgments @node Acknowledgments, Resources, Contributing, Top
@chapter Acknowledgments @chapter Acknowledgments
We would like to thank the following people for their help: Jeremiah We would like to thank the following people for their help: Jeremiah
@ -1151,7 +1195,7 @@ LISP-1.5 and Alan Kay for their inspiring comment on
@url{https://queue.acm.org/detail.cfm?id=1039523, Page 13}. @url{https://queue.acm.org/detail.cfm?id=1039523, Page 13}.
@c ********************************************************************* @c *********************************************************************
@node Resources @node Resources, GNU Free Documentation License, Acknowledgments, Top
@chapter Resources @chapter Resources
@itemize @itemize
@ -1185,17 +1229,17 @@ at the freenode IRC network.
@end itemize @end itemize
@c ********************************************************************* @c *********************************************************************
@node GNU Free Documentation License @node GNU Free Documentation License, Concept Index, Resources, Top
@appendix GNU Free Documentation License @appendix GNU Free Documentation License
@cindex license, GNU Free Documentation License @cindex license, GNU Free Documentation License
@include fdl-1.3.texi @include fdl-1.3.texi
@c ********************************************************************* @c *********************************************************************
@node Concept Index @node Concept Index, Programming Index, GNU Free Documentation License, Top
@unnumbered Concept Index @unnumbered Concept Index
@printindex cp @printindex cp
@node Programming Index @node Programming Index, , Concept Index, Top
@unnumbered Programming Index @unnumbered Programming Index
@syncodeindex tp fn @syncodeindex tp fn
@syncodeindex vr fn @syncodeindex vr fn

View File

@ -399,6 +399,7 @@ SCM read_string (SCM port);
SCM string_append (SCM x); SCM string_append (SCM x);
SCM string_length (SCM string); SCM string_length (SCM string);
SCM string_ref (SCM str, SCM k); SCM string_ref (SCM str, SCM k);
SCM string_set_x (SCM str, SCM k, SCM v);
// src/struct.mes // src/struct.mes
SCM make_struct (SCM type, SCM fields, SCM printer); SCM make_struct (SCM type, SCM fields, SCM printer);
SCM struct_length (SCM x); SCM struct_length (SCM x);

View File

@ -24,9 +24,21 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#if !__MESC__ /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
off_t
_lseek (int filedes, off_t offset, int whence)
{
return _sys_call3 (SYS_lseek, (int) filedes, (long) offset, (int) whence);
}
#endif
off_t off_t
lseek (int filedes, off_t offset, int whence) lseek (int filedes, off_t offset, int whence)
{ {
#if !__MESC__ /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
if (_lseek (filedes, 0, SEEK_CUR) == -1)
return -1;
#endif
size_t skip = __buffered_read_clear (filedes); size_t skip = __buffered_read_clear (filedes);
if (whence == SEEK_CUR) if (whence == SEEK_CUR)
offset -= skip; offset -= skip;

View File

@ -22,7 +22,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if !__MESC__
#define __READ_BUFFER_MAX 128
int __read_buffer_max;
#else /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
#define __READ_BUFFER_MAX 100 #define __READ_BUFFER_MAX 100
#define __read_buffer_max 100
#endif
struct __read_buffer struct __read_buffer
{ {
@ -36,7 +42,21 @@ void
__buffered_read_init (int filedes) __buffered_read_init (int filedes)
{ {
if (!__read_cache) if (!__read_cache)
__read_cache = (struct __read_buffer *) malloc (sizeof (struct __read_buffer) * __FILEDES_MAX); {
__read_cache = (struct __read_buffer *) malloc (sizeof (struct __read_buffer) * __FILEDES_MAX);
#if !__MESC__
__read_buffer_max = __READ_BUFFER_MAX;
char *p = getenv ("MES_READ_BUFFER");
if (p)
{
__read_buffer_max = atoi (p);
if (__read_buffer_max < 0)
__read_buffer_max = 0;
if (__read_buffer_max > __READ_BUFFER_MAX)
__read_buffer_max = __READ_BUFFER_MAX;
}
#endif
}
} }
size_t size_t
@ -55,23 +75,33 @@ __buffered_read (int filedes, void *buffer, size_t size)
__buffered_read_init (filedes); __buffered_read_init (filedes);
struct __read_buffer *cache = &__read_cache[filedes]; struct __read_buffer *cache = &__read_cache[filedes];
char *p = buffer; char *p = buffer;
if (!cache->size && size > __READ_BUFFER_MAX) if (!cache->size && size > __read_buffer_max)
return _read (filedes, buffer, size); return _read (filedes, buffer, size);
while (cache->size > 0 && todo) while (cache->size > 0 && todo)
{ {
todo--; todo--;
*p++ = cache->string[__READ_BUFFER_MAX - cache->size--]; *p++ = cache->string[__read_buffer_max - cache->size--];
} }
if (todo) if (todo)
{ {
ssize_t bytes = _read (filedes, cache->string, __READ_BUFFER_MAX); #if !__MESC__
if (todo > __read_buffer_max)
return size - todo + _read (filedes, p, todo);
if (__mes_debug () > 4)
{
eputs ("__buffered_read: ");
eputs (itoa (__read_buffer_max));
eputs ("\n");
}
#endif
ssize_t bytes = _read (filedes, cache->string, __read_buffer_max);
if (bytes < 0) if (bytes < 0)
return -1; return -1;
if (bytes) if (bytes)
{ {
cache->size = bytes; cache->size = bytes;
if (bytes < __READ_BUFFER_MAX) if (bytes < __read_buffer_max)
memmove (cache->string + __READ_BUFFER_MAX - bytes, cache->string, bytes); memmove (cache->string + __read_buffer_max - bytes, cache->string, bytes);
return size - todo + __buffered_read (filedes, p, todo); return size - todo + __buffered_read (filedes, p, todo);
} }
} }

View File

@ -21,6 +21,7 @@
#include <mes/lib.h> #include <mes/lib.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h>
int int
execlp (char const *file_name, char const *arg, ...) execlp (char const *file_name, char const *arg, ...)
@ -28,7 +29,7 @@ execlp (char const *file_name, char const *arg, ...)
va_list ap; va_list ap;
int r; int r;
va_start (ap, arg); va_start (ap, arg);
if (file_name[0] != '/') if (!strchr (file_name, '/'))
file_name = search_path (file_name); file_name = search_path (file_name);
if (__mes_debug () > 2) if (__mes_debug () > 2)
{ {

View File

@ -20,12 +20,13 @@
#include <mes/lib.h> #include <mes/lib.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
int int
execvp (char const *file_name, char *const argv[]) execvp (char const *file_name, char *const argv[])
{ {
if (file_name[0] != '/') if (!strchr (file_name, '/'))
file_name = search_path (file_name); file_name = search_path (file_name);
if (!file_name) if (!file_name)
{ {

View File

@ -42,5 +42,5 @@ open (char const *file_name, int flags, ...)
return r; return r;
} }
else else
return _open2(file_name, flags); return _open2 (file_name, flags);
} }

View File

@ -45,7 +45,7 @@ fopen (char const *file_name, char const *opentype)
int flags = O_RDWR; int flags = O_RDWR;
if (opentype[0] == 'a') if (opentype[0] == 'a')
flags |= O_APPEND; flags |= O_APPEND;
fd = open (file_name, flags, mode); fd = _open3 (file_name, flags, mode);
} }
else if (opentype[0] == 'w' || opentype[0] == 'a' || !strcmp (opentype, "r+")) else if (opentype[0] == 'w' || opentype[0] == 'a' || !strcmp (opentype, "r+"))
{ {
@ -72,5 +72,3 @@ fopen (char const *file_name, char const *opentype)
fd = 0; fd = 0;
return (FILE *) (long) fd; return (FILE *) (long) fd;
} }
#undef open

View File

@ -32,6 +32,8 @@
(mes-use-module (mes display)) (mes-use-module (mes display))
(mes-use-module (mes simple-format)) (mes-use-module (mes simple-format))
(define %load-path (or (and=> (getenv "GUILE_LOAD_PATH") (lambda (x) (string-split x #\:))) '()))
(define (drain-input port) (read-string)) (define (drain-input port) (read-string))
(define (read-line . rest) (define (read-line . rest)

View File

@ -205,9 +205,6 @@
(define (make-string n . fill) (define (make-string n . fill)
(list->string (apply make-list n fill))) (list->string (apply make-list n fill)))
(define (string-set! s k v)
(list->string (list-set! (string->list s) k v)))
(define (substring s start . rest) (define (substring s start . rest)
(let* ((end (and (pair? rest) (car rest))) (let* ((end (and (pair? rest) (car rest)))
(lst (list-tail (string->list s) start))) (lst (list-tail (string->list s) start)))

View File

@ -22,8 +22,9 @@
;;; Code: ;;; Code:
(mes-use-module (mes pretty-print))
(mes-use-module (mes psyntax)) (mes-use-module (mes psyntax))
(mes-use-module (srfi srfi-1)) (mes-use-module (srfi srfi-1))
(mes-use-module (srfi srfi-9-psyntax)) (mes-use-module (srfi srfi-9))
(mes-use-module (srfi srfi-43)) (mes-use-module (srfi srfi-43))
(include-from-path "nyacc/lalr.scm") (include-from-path "nyacc/lalr.scm")

View File

@ -0,0 +1,33 @@
;;; -*-scheme-*-
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(mes-use-module (mes guile))
(mes-use-module (rnrs arithmetic bitwise))
(mes-use-module (srfi srfi-43))
(mes-use-module (nyacc lalr))
(mes-use-module (nyacc parse))
(mes-use-module (nyacc lex))
(mes-use-module (nyacc lang util))
(include-from-path "nyacc/lang/c99/cppmach.scm")

View File

@ -0,0 +1,34 @@
;;; -*-scheme-*-
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(mes-use-module (mes guile))
(mes-use-module (srfi srfi-43))
(mes-use-module (nyacc lang c99 cpp))
(mes-use-module (nyacc lang util))
(mes-use-module (nyacc lalr))
(mes-use-module (nyacc parse))
(mes-use-module (nyacc lex))
(mes-use-module (nyacc util))
(include-from-path "nyacc/lang/c99/mach.scm")

View File

@ -20,9 +20,9 @@
;;; Taken from GNU Guile ;;; Taken from GNU Guile
(define-module (ice-9 pretty-print) (define-module (mes pretty-print)
:use-module (ice-9 optargs) #:use-module (ice-9 optargs)
:export (pretty-print)) #:export (pretty-print))
;; From SLIB. ;; From SLIB.

View File

@ -42,6 +42,7 @@
c99-input->object)) c99-input->object))
(define mes? (pair? (current-module))) (define mes? (pair? (current-module)))
(define mes-or-reproducible? #t)
(define (cc-amd? info) #f) ; use AMD calling convention? (define (cc-amd? info) #f) ; use AMD calling convention?
;; (define %reduced-register-count #f) ; use all registers? ;; (define %reduced-register-count #f) ; use all registers?
(define %reduced-register-count 2) ; use reduced instruction set (define %reduced-register-count 2) ; use reduced instruction set
@ -581,7 +582,7 @@
(wrap-as `((#:comment ,o)))) (wrap-as `((#:comment ,o))))
(define (ast->comment o) (define (ast->comment o)
(if mes? '() (if mes-or-reproducible? '()
(let* ((source (with-output-to-string (lambda () (pretty-print-c99 o)))) (let* ((source (with-output-to-string (lambda () (pretty-print-c99 o))))
;; Nyacc fixups ;; Nyacc fixups
(source (string-substitute source "\\" "\\\\")) (source (string-substitute source "\\" "\\\\"))
@ -1514,7 +1515,7 @@
info)) info))
((or ,a ,b) ((or ,a ,b)
(let* ((here (number->string (length (if mes? (.text info) (let* ((here (number->string (length (if mes-or-reproducible? (.text info)
(filter (negate comment?) (.text info)))))) (filter (negate comment?) (.text info))))))
(skip-b-label (string-append label "_skip_b_" here)) (skip-b-label (string-append label "_skip_b_" here))
(b-label (string-append label "_b_" here)) (b-label (string-append label "_b_" here))

View File

@ -31,6 +31,8 @@
#:use-module (mes guile) #:use-module (mes guile)
#:export (c99-input->ast)) #:export (c99-input->ast))
(define mes-or-reproducible? #t)
(when (getenv "MESC_DEBUG") (when (getenv "MESC_DEBUG")
(format (current-error-port) "*nyacc-version*=~a\n" *nyacc-version*)) (format (current-error-port) "*nyacc-version*=~a\n" *nyacc-version*))
@ -97,7 +99,7 @@
"SYSTEM_LIBC=0" "SYSTEM_LIBC=0"
"__STDC__=1" "__STDC__=1"
"__MESC__=1" "__MESC__=1"
,(if mes? "__MESC_MES__=1" "__MESC_MES__=0") ,(if mes-or-reproducible? "__MESC_MES__=1" "__MESC_MES__=0")
,@defines))) ,@defines)))
(when (and verbose? (> verbose? 1)) (when (and verbose? (> verbose? 1))
(stderr "includes: ~s\n" includes) (stderr "includes: ~s\n" includes)

View File

@ -1729,6 +1729,7 @@ mes_builtins (SCM a) ///((internal))
a = init_builtin (builtin_type, "string-append", -1, (function1_t) & string_append, a); a = init_builtin (builtin_type, "string-append", -1, (function1_t) & string_append, a);
a = init_builtin (builtin_type, "string-length", 1, (function1_t) & string_length, a); a = init_builtin (builtin_type, "string-length", 1, (function1_t) & string_length, a);
a = init_builtin (builtin_type, "string-ref", 2, (function1_t) & string_ref, a); a = init_builtin (builtin_type, "string-ref", 2, (function1_t) & string_ref, a);
a = init_builtin (builtin_type, "string-set!", 3, (function1_t) & string_set_x, a);
// src/struct.mes // src/struct.mes
a = init_builtin (builtin_type, "make-struct", 3, (function1_t) & make_struct, a); a = init_builtin (builtin_type, "make-struct", 3, (function1_t) & make_struct, a);
a = init_builtin (builtin_type, "struct-length", 1, (function1_t) & struct_length, a); a = init_builtin (builtin_type, "struct-length", 1, (function1_t) & struct_length, a);

View File

@ -252,3 +252,18 @@ string_ref (SCM str, SCM k)
char const *p = CSTRING (str); char const *p = CSTRING (str);
return MAKE_CHAR (p[i]); return MAKE_CHAR (p[i]);
} }
SCM
string_set_x (SCM str, SCM k, SCM v)
{
assert (TYPE (str) == TSTRING);
assert (TYPE (k) == TNUMBER);
assert (TYPE (v) == TCHAR);
size_t size = LENGTH (str);
size_t i = VALUE (k);
if (i > size)
error (cell_symbol_system_error, cons (MAKE_STRING0 ("value out of range"), k));
char *p = CSTRING (str);
p[i] = VALUE (v);
return cell_unspecified;
}