cs: adjust build to use Racket bootstrap of Chez Scheme

This commit is contained in:
Matthew Flatt 2019-04-19 20:54:17 -06:00
parent f26b793e9a
commit e2de99f0b9
14 changed files with 185 additions and 43 deletions

View File

@ -1,6 +1,6 @@
RACKET=racket
SCHEME_DIR=../../build/ChezScheme
SCHEME_SRC=../../build/ChezScheme
boot:
env SCHEME_DIR="$(SCHEME_DIR)" $(RACKET) make-boot.rkt
env SCHEME_SRC="$(SCHEME_SRC)" $(RACKET) make-boot.rkt

View File

@ -5,9 +5,9 @@ existing Racket build, but without using an existing Chez Scheme
build.)
The "make-boot.rkt" programs builds Chez Scheme ".boot" and ".h" files
from source. The output is written to "compiled", but copy the files
to "<machine>/boot/<machine>" in a Chez Scheme source directory before
`configure` to `make` to boostrap the build.
from source. The output is written to "<machine>/boot/<machine>" in a
Chez Scheme source directory. Build boot files that way before
`configure` and `make` to boostrap the build.
The Chez Scheme simulation hasn't been made especially fast, so expect
the bootstrap process to take 5-10 times as long as using an existing

View File

@ -2,15 +2,16 @@
(require ffi/unsafe/global)
(provide scheme-dir
target-machine)
target-machine
optimize-level-init)
(define ht (get-place-table))
(define scheme-dir (or (hash-ref ht 'make-boot-scheme-dir #f)
(simplify-path
(path->complete-path
(or (getenv "SCHEME_DIR")
(error "set `SCHEME_DIR` environment variable"))))))
(or (getenv "SCHEME_SRC")
(error "set `SCHEME_SRC` environment variable"))))))
(hash-set! ht 'make-boot-scheme-dir scheme-dir)
(define target-machine (or (hash-ref ht 'make-boot-targate-machine #f)
@ -26,3 +27,5 @@
(error "set `MACH` environment variable")])))
(hash-set! ht 'make-boot-targate-machine target-machine)
(define optimize-level-init 3)

View File

@ -44,7 +44,7 @@
(provide id ...)
(define id (hash-ref ht 'id)) ...))
(hash-set! ht 'ptr-bytes (* 8 (hash-ref ht 'ptr-bits)))
(hash-set! ht 'ptr-bytes (/ (hash-ref ht 'ptr-bits) 8))
(define-constant
ptr-bytes
@ -58,4 +58,5 @@
prelex-sticky-mask
prelex-is-mask)
(provide record-ptr-offset)
(define record-ptr-offset 1)

View File

@ -2,7 +2,8 @@
(require racket/runtime-path
racket/match
racket/file
(only-in "r6rs-lang.rkt")
(only-in "r6rs-lang.rkt"
optimize-level)
(only-in "scheme-lang.rkt"
current-expand)
(submod "scheme-lang.rkt" callback)
@ -12,24 +13,47 @@
"parse-makefile.rkt"
"config.rkt")
;; Writes ".boot" and ".h" files to a "compiled" subdirectory of the
;; current directory.
;; Set `SCHEME_DIR` and `MACH` to specify the ChezScheme source
;; Set `SCHEME_SRC` and `MACH` to specify the ChezScheme source
;; directory and the target machine.
;; Writes ".boot" and ".h" files to a "boot" subdirectory of
;; `SCHEME_SRC`.
(define-runtime-path here-dir ".")
(define out-subdir (build-path scheme-dir "boot" target-machine))
(define nano-dir (build-path scheme-dir "nanopass"))
(define (status msg)
(printf "~a\n" msg)
(flush-output))
(define sources-date
(for/fold ([d 0]) ([dir (in-list (list here-dir
nano-dir
(build-path scheme-dir "s")))])
(status (format "Use ~a" dir))
(for/fold ([d d]) ([f (in-list (directory-list dir))]
#:when (regexp-match? #rx"[.](?:rkt|ss|sls)$" f))
(max d (file-or-directory-modify-seconds (build-path dir f))))))
(status (format "Check ~a" out-subdir))
(when (for/and ([f (in-list (list "scheme.h"
"equates.h"
"petite.boot"
"scheme.boot"))])
(define d (file-or-directory-modify-seconds (build-path out-subdir f) #f (lambda () #f)))
(and d (d . >= . sources-date)))
(status "Up-to-date")
(exit))
;; ----------------------------------------
(define-runtime-module-path r6rs-lang-mod "r6rs-lang.rkt")
(define-runtime-module-path scheme-lang-mod "scheme-lang.rkt")
(define-values (petite-sources scheme-sources)
(get-sources-from-makefile scheme-dir))
(define (status msg)
(printf "~a\n" msg)
(flush-output))
(define ns (make-base-empty-namespace))
(namespace-attach-module (current-namespace) r6rs-lang-mod ns)
(namespace-attach-module (current-namespace) scheme-lang-mod ns)
@ -110,7 +134,6 @@
(set-current-expand-set-callback!
(lambda ()
(start-fully-unwrapping-syntax!)
(status "Load expander")
(define $uncprep (orig-eval '$uncprep))
(current-eval
(lambda (stx)
@ -260,11 +283,14 @@
(lambda (ty)
(filter-foreign-type ty))))
(make-directory* out-subdir)
(status "Load mkheader")
(load-ss (build-path scheme-dir "s/mkheader.ss"))
(status "Generate headers")
(eval `(mkscheme.h "compiled/scheme.h" ,target-machine))
(eval `(mkequates.h "compiled/equates.h"))
(eval `(mkscheme.h ,(path->string (build-path out-subdir "scheme.h")) ,target-machine))
(eval `(mkequates.h ,(path->string (build-path out-subdir "equates.h"))))
(plumber-flush-all (current-plumber))
(for ([s (in-list '("ftype.ss"
"fasl.ss"
@ -281,14 +307,12 @@
(status (format "Load ~a" s))
(load-ss (build-path scheme-dir "s" s)))
(make-directory* "compiled")
(let ([failed? #f])
(for ([src (append petite-sources scheme-sources)])
(let ([dest (path->string (path->complete-path (build-path "compiled" (path-replace-suffix src #".so"))))])
(let ([dest (path->string (path->complete-path (build-path out-subdir (path-replace-suffix src #".so"))))])
(parameterize ([current-directory (build-path scheme-dir "s")])
;; (status (format "Compile ~a" src)) - Chez Scheme prints its own message
(with-handlers ([exn:fail? (lambda (exn)
(with-handlers (#;[exn:fail? (lambda (exn)
(eprintf "ERROR: ~s\n" (exn-message exn))
(set! failed? #t))])
((orig-eval 'compile-file) src dest)))))
@ -296,10 +320,12 @@
(raise-user-error 'make-boot "compilation failure(s)")))
(let ([src->so (lambda (src)
(path->string (build-path "compiled" (path-replace-suffix src #".so"))))])
(path->string (build-path out-subdir (path-replace-suffix src #".so"))))])
(status "Writing petite.boot")
(eval `($make-boot-file "compiled/petite.boot" ',(string->symbol target-machine) '()
(eval `($make-boot-file ,(path->string (build-path out-subdir "petite.boot"))
',(string->symbol target-machine) '()
,@(map src->so petite-sources)))
(status "Writing scheme.boot")
(eval `($make-boot-file "compiled/scheme.boot" ',(string->symbol target-machine) '("petite")
(eval `($make-boot-file ,(path->string (build-path out-subdir "scheme.boot"))
',(string->symbol target-machine) '("petite")
,@(map src->so scheme-sources)))))

View File

@ -19,7 +19,7 @@
body)])))))
(free-identifier=? #'id #'make-in-context-transformer)
(begin
(printf "Nanopass patch applied\n")
(printf "Apply nanopass patch\n")
#'(...
(define id
(lambda args

View File

@ -6,6 +6,7 @@
(define (get-sources-from-makefile scheme-dir)
(call-with-input-file*
(build-path scheme-dir "s" "Mf-base")
#:mode 'text
(lambda (i)
(define (extract-files m)
(string-split (regexp-replace* #rx"\\\\" (bytes->string/utf-8 (cadr m)) "")))

View File

@ -12,6 +12,7 @@
"format.rkt"
"syntax-mode.rkt"
"constant.rkt"
"config.rkt"
(only-in "record.rkt"
do-$make-record-type
register-rtd-name!
@ -769,9 +770,8 @@
(define (s:fixnum? x)
(and (fixnum? x)
(let ([w (fixnum-width)])
(<= low-fixnum x high-fixnum))))
(<= low-fixnum x high-fixnum)))
(define (make-compile-time-value v) v)
(define optimize-level (make-parameter 2))
(define optimize-level (make-parameter optimize-level-init))

View File

@ -5,6 +5,7 @@
racket/list
"immediate.rkt"
"symbol.rkt"
"gensym.rkt"
"constant.rkt")
(provide do-$make-record-type
@ -57,8 +58,15 @@
(define (do-$make-record-type in-base-rtd in-super in-name fields sealed? opaque? more
#:uid [uid #f])
(define name (if (string? in-name) (string->symbol in-name) in-name))
#:uid [in-uid #f])
(define name (cond
[(string? in-name) (string->symbol in-name)]
[(gensym? in-name) (string->symbol (gensym->pretty-string in-name))]
[else in-name]))
(define uid (or in-uid
(cond
[(gensym? in-name) in-name]
[else #f])))
(define super
(cond
[(base-rtd? in-super) struct:base-rtd-subtype]
@ -113,7 +121,7 @@
(define (fld-type fld) (vector-ref fld 3))
(define (fld-byte fld) (vector-ref fld 4))
(define (set-fld-byte! fld v) (vector-set! fld 4 v))
(define fld-byte-value 0) ; gets replaced
(define fld-byte-value 0) ; doesn't matter; gets replaced in field vectors
(define (register-rtd-fields! struct:name fields)
(define-values (r-name init-cnt auto-cnt ref set immutables super skipped?)
@ -476,10 +484,10 @@
(void))
(define (fix-offsets flds)
(let loop ([flds flds] [offset (add1 fld-byte-value)])
(let loop ([flds flds] [offset (+ record-ptr-offset ptr-bytes)])
(unless (null? flds)
(set-fld-byte! (car flds) offset)
(loop (cdr flds) (+ offset fld-byte-value))))
(loop (cdr flds) (+ offset ptr-bytes))))
flds)
(define ($object-ref type v offset)
@ -493,7 +501,7 @@
(unless (or (eq? type 'scheme-object)
(eq? type 'ptr))
(error '$object-ref "unrecognized type: ~e" type))
(define i (quotient (- offset (add1 fld-byte-value)) fld-byte-value))
(define i (quotient (- offset (+ record-ptr-offset ptr-bytes)) ptr-bytes))
(cond
[(struct-type? v)
(cond

View File

@ -17,6 +17,7 @@
"scheme-struct.rkt"
"symbol.rkt"
"record.rkt"
"constant.rkt"
(only-in "r6rs-lang.rkt"
make-record-constructor-descriptor
set-car!
@ -123,7 +124,7 @@
[arithmetic-shift ash]
[arithmetic-shift bitwise-arithmetic-shift-left]
[arithmetic-shift bitwise-arithmetic-shift]
[fxrshift fxsrl]
[fxrshift fxsra]
[bitwise-not lognot]
[bitwise-ior logor]
[bitwise-xor logxor]
@ -168,6 +169,7 @@
[logbit1 fxlogbit1]
[logbit0 fxlogbit0]
[logtest fxlogtest])
fxsrl
fxbit-field
bitwise-bit-count
bitwise-arithmetic-shift-right
@ -554,6 +556,13 @@
(define (logtest a b)
(not (eqv? 0 (bitwise-and a b))))
(define (fxsrl v amt)
(if (and (v . fx< . 0)
(amt . fx> . 0))
(bitwise-and (fxrshift v amt)
(- (fxlshift 1 (- fixnum-bits amt)) 1))
(fxrshift v amt)))
(define (fxbit-field fx1 fx2 fx3)
(fxand (fxrshift fx1 fx2) (fx- (fxlshift 1 (- fx3 fx2)) 1)))

View File

@ -137,17 +137,20 @@ SCHEME_CONFIG_VARS = CC="$(CC)" CFLAGS="$(BASE_CFLAGS)" LD="$(LD)" LDFLAGS="$(LD
scheme-make:
cd $(SCHEME_SRC) && git submodule -q init && git submodule -q update
env SCHEME_SRC="$(SCHEME_SRC)" MACH="$(MACH)" $(BOOTSTRAP_RACKET) $(srcdir)/../bootstrap/make-boot.rkt
cd $(SCHEME_SRC) && ./configure @SCHEME_CONFIG_ARGS@ $(SCHEME_CONFIG_VARS)
mkdir -p $(SCHEME_SRC)/$(MACH)/boot/$(MACH)
$(MAKE) $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/equates.h
$(MAKE) $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/scheme.h
$(MAKE) $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/petite.boot
$(MAKE) $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/scheme.boot
cd $(SCHEME_SRC) && $(MAKE)
# Replace "equates.h", etc., if they seem to be out of date.
# Otherwise, `make` on Chez Scheme can fail.
# If "equates.h", etc., are newly built since previous build, move them into place
$(SCHEME_SRC)/$(MACH)/boot/$(MACH)/equates.h: $(SCHEME_SRC)/boot/$(MACH)/equates.h
cp $(SCHEME_SRC)/boot/$(MACH)/equates.h $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/equates.h
$(SCHEME_SRC)/$(MACH)/boot/$(MACH)/scheme.h: $(SCHEME_SRC)/boot/$(MACH)/scheme.h
cp $(SCHEME_SRC)/boot/$(MACH)/scheme.h $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/scheme.h
$(SCHEME_SRC)/$(MACH)/boot/$(MACH)/petite.boot: $(SCHEME_SRC)/boot/$(MACH)/petite.boot
cp $(SCHEME_SRC)/boot/$(MACH)/petite.boot $(SCHEME_SRC)/$(MACH)/boot/$(MACH)/petite.boot
$(SCHEME_SRC)/$(MACH)/boot/$(MACH)/scheme.boot: $(SCHEME_SRC)/boot/$(MACH)/scheme.boot

View File

@ -42,6 +42,7 @@
(copy-one-dir "s")
(copy-one-dir "mats")
(copy-one-dir "nanopass")
(copy-one-dir "unicode")
(copy-one-dir "zlib")
(copy-one-dir "lz4")
(copy-one-dir (build-path "boot" machine-name))

View File

@ -0,0 +1,70 @@
#lang racket/base
(require racket/file
racket/system
"../../cs/bootstrap/parse-makefile.rkt")
(provide recompile)
(define optimize-level 3)
(define (recompile scheme-dir machine #:system* [system* system*])
(when (or (same-content? (build-path scheme-dir "boot" machine "petite.boot")
(build-path scheme-dir machine "boot" machine "petite.boot"))
(same-content? (build-path scheme-dir "boot" machine "scheme.boot")
(build-path scheme-dir machine "boot" machine "scheme.boot")))
(define-values (petite-srcs scheme-srcs) (get-sources-from-makefile scheme-dir))
(define abs-scheme-dir (path->complete-path scheme-dir))
(parameterize ([current-directory (build-path scheme-dir machine "nanopass")])
(define o (open-output-bytes))
(write-nanopass-config o)
(write '(compile-library "nanopass.ss" "nanopass.so") o)
(parameterize ([current-input-port (open-input-bytes (get-output-bytes o))])
(system* (build-path abs-scheme-dir machine "bin" machine "scheme.exe")
"-q"
"--compile-imported-libraries")))
(parameterize ([current-directory (build-path scheme-dir machine "s")])
(copy-file (format "~a.def" machine) "machine.def" #t)
(define o (open-output-bytes))
(define (src->so src) (regexp-replace #rx"[.]ss$" src ".so"))
(write-system-config o)
(for ([f (in-list '("cmacros.ss" "priminfo.ss"))])
(write `(load ,f) o))
(for ([f (in-list (append petite-srcs scheme-srcs))])
(write `(compile-file ,f) o))
(write `($make-boot-file ,(format "../boot/~a/petite.boot" machine)
',(string->symbol machine) '()
,@(map src->so petite-srcs))
o)
(write `($make-boot-file ,(format "../boot/~a/scheme.boot" machine)
',(string->symbol machine) '("petite")
,@(map src->so scheme-srcs))
o)
;;(printf "~a\n" (get-output-string o))
(parameterize ([current-input-port (open-input-bytes (get-output-bytes o))])
(system* (build-path abs-scheme-dir machine "bin" machine "scheme.exe")
"-q"
"--libdirs" "../nanopass")))))
(define (same-content? f1 f2)
(and (equal? (file-size f1)
(file-size f2))
(equal? (file->bytes f1)
(file->bytes f2))))
(define (write-config o)
(write '(reset-handler abort) o)
(write '(base-exception-handler (lambda (c) (fresh-line) (display-condition c) (newline) (reset))) o)
(write '(keyboard-interrupt-handler (lambda () (display "interrupted---aborting\n") (reset))) o)
(write `(optimize-level ,optimize-level) o)
(write '(debug-level 0) o)
(write '(generate-inspector-information #f) o))
(define (write-nanopass-config o)
(write-config o))
(define (write-system-config o)
(write-config o)
(write '(subset-mode (quote system)) o))

View File

@ -5,7 +5,8 @@
racket/runtime-path
compiler/find-exe
racket/system
"cs/prep.rkt")
"cs/prep.rkt"
"cs/recompile.rkt")
(define-runtime-path here ".")
@ -67,6 +68,7 @@
;; ----------------------------------------
;; Download Chez Scheme source
(let ([submodules '("nanopass" "stex" "zlib" "lz4")]
[readmes '("ReadMe.md" "ReadMe" "README" "README.md")])
(define (clone from to [git-clone-args '()])
@ -105,12 +107,30 @@
(system*! "git" "submodule" "init")
(system*! "git" "submodule" "update")))]))
;; Bootstrap Chez Scheme boot files
(let/ec esc
(parameterize ([current-environment-variables
(environment-variables-copy (current-environment-variables))]
[exit-handler (let ([orig-exit (exit-handler)])
(lambda (v)
(if (zero? v)
(esc)
(orig-exit v))))])
(putenv "SCHEME_SRC" (path->string scheme-dir))
(putenv "MACH" machine)
(dynamic-require (build-path here 'up "cs" "bootstrap" "make-boot.rkt") #f)))
;; Prepare to use Chez Scheme makefile
(prep-chez-scheme scheme-dir machine)
;; Finish building Chez Scheme
(parameterize ([current-directory (build-path scheme-dir machine "c")])
(system*! "nmake"
(format "Makefile.~a" machine)))
;; Replace Chez-on-Racket-built bootfiles with Chez-built bootfiles
(recompile scheme-dir machine #:system* system*!)
;; ----------------------------------------
;; Run Racket in directories that reach here with "../worksp".