2 Compiling Modified Modules to Bytecode
The default mode for mzc is to accept filenames for Scheme modules to be compiled to bytecode format. Modules are re-compiled only if the source Scheme file is newer than the bytecode file, or if any imported module is recompiled.
2.1 Bytecode Files
A file "‹name›.‹ext›" is compiled to bytecode that is saved as "compiled/‹name›_‹ext›.zo" relative to the file. As a result, the bytecode file is normally used automatically when "‹name›.‹ext›" is required as a module, since the underlying load/use-compiled operation detects such a bytecode file.
For example, in a directory that contains the following files:
"a.scm":
#lang scheme (require "b.scm" "c.scm") (+ b c) "b.scm":
#lang scheme (provide b) (define b 1) "c.scm":
#lang scheme (provide c) (define c 1)
then
mzc a.scm
triggers the creation of "compiled/a_ss.zo", "compiled/b_ss.zo", and "compiled/c_ss.zo". A subsequent
mzscheme a.scm
loads bytecode from the generated ".zo" files, paying attention to the ".scm" sources only to confirm that each ".zo" file has a later timestamp.
In contrast,
mzc b.scm c.scm
would create only "compiled/b_scm.zo" and "compiled/c_scm.zo", since neither "b.scm" nor "c.scm" imports "a.scm".
2.2 Dependency Files
In addition to a bytecode file, mzc creates a file "compiled/‹name›_‹ext›.dep" that records dependencies of the compiled module on other module files. Using this dependency information, a re-compilation request via mzc can consult both the source file’s timestamp and the timestamps for the sources and bytecode of imported modules. Furthermore, imported modules are themselves compiled as necessary, including updating the bytecode and dependency files for the imported modules, transitively.
Continuing the mzc a.scm example from the previous section, the mzc creates "compiled/a_scm.dep", "compiled/b_scm.dep", and "compiled/c_scm.dep" at the same time as the ".zo" files. The "compiled/a_scm.dep" file records the dependency of "a.scm" on "b.scm", "c.scm" and the scheme library. If the "b.scm" file is modified (so that its timestamp changes), then running
mzc a.scm
again rebuilds "compiled/a_ss.zo" and "compiled/b_ss.zo".
For module files that are within library collections, setup-plt uses the same ".zo" and ".dep" conventions and files as mzc, so the two tools can be used together.
2.3 Scheme Compilation Manager API
the file is expected to contain a module (i.e., the second argument to the handler is a symbol);
the value of each of (current-eval), (current-load), and (namespace-module-registry (current-namespace)) is the same as when make-compilation-manager-load/use-compiled-handler was called;
the value of use-compiled-file-paths contains the first path that was present when make-compilation-manager-load/use-compiled-handler was called;
the value of current-load/use-compiled is the result of this procedure; and
one of the following holds:
the source file is newer than the ".zo" file in the first sub-directory listed in use-compiled-file-paths (at the time that make-compilation-manager-load/use-compiled-handler was called)
no ".dep" file exists next to the ".zo" file;
the version recorded in the ".dep" file does not match the result of (version);
one of the files listed in the ".dep" file has a ".zo" timestamp newer than the one recorded in the ".dep" file.
After the handler procedure compiles a ".zo" file, it creates a corresponding ".dep" file that lists the current version, plus the ".zo" timestamp for every file that is required by the module in the compiled file. Additional dependencies can be installed during compilation via compiler/cm-accomplice.
The handler caches timestamps when it checks ".dep" files, and the cache is maintained across calls to the same handler. The cache is not consulted to compare the immediate source file to its ".zo" file, which means that the caching behavior is consistent with the caching of the default module name resolver (see current-module-name-resolver).
If use-compiled-file-paths contains an empty list when make-compilation-manager-load/use-compiled-handler is called, then exn:fail:contract exception is raised.
Do not install the result of make-compilation-manager-load/use-compiled-handler when the current namespace contains already-loaded versions of modules that may need to be recompiled – unless the already-loaded modules are never referenced by not-yet-loaded modules. References to already-loaded modules may produce compiled files with inconsistent timestamps and/or ".dep" files with incorrect information.
(managed-compile-zo file [read-src-syntax]) → void? | ||||||||||||
file : path-string? | ||||||||||||
|
If file is compiled from source, then read-src-syntax is used in the same way as read-syntax to read the source module. The normal read-syntax is used for any required files, however.
(trust-existing-zos) → boolean? |
(trust-existing-zos trust?) → void? |
trust? : any/c |
(make-caching-managed-compile-zo read-src-syntax) |
→ (path-string? . -> . void?) |
read-src-syntax : (any/c input-port? . -> . syntax?) |
(manager-compile-notify-handler) → (path? . -> . any) |
(manager-compile-notify-handler notify) → void? |
notify : (path? . -> . any) |
(manager-trace-handler) → (string? . -> . any) |
(manager-trace-handler notify) → void? |
notify : (string? . -> . any) |
(manager-skip-file-handler) → (-> path? (or/c number? #f)) |
(manager-skip-file-handler proc) → void? |
proc : (-> path? (or/c number? #f)) |
2.4 Compilation Manager Hook for Syntax Transformers
(require compiler/cm-accomplice) |
(register-external-file file) → void? |
file : (and path? complete-path?) |
A compilation manager implemented by compiler/cm looks for such messages to register an external dependency. The compilation manager records (in a ".dep" file) the path as contributing to the implementation of the module currently being compiled. Afterward, if the registered file is modified, the compilation manager will know to recompile the module.
The include macro, for example, calls this procedure with the path of an included file as it expands an include form.