3 raco exe: Creating Stand-Alone Executables
Use a smaller base language to achieve a faster startup time such as #lang racket/base instead of #lang racket rather than relying on raco exe.
Compiled code produced by raco make relies on Racket executables to provide run-time support to the compiled code. However, raco exe can package code together with its run-time support to form an executable, and raco distribute can package the executable into a distribution that works on other machines. Running an executable produced by raco exe will not improve performance over raco make.
The raco exe command embeds a module, from source or byte code, into a copy of the racket executable. (On Unix, the embedding executable is actually a copy of a wrapper executable.) The created executable invokes the embedded module on startup. The --gui flag causes the program to be embedded in a copy of the gracket executable. If the embedded module refers to other modules via require, then the other modules are also included in the embedding executable.
For example, the command
raco exe --gui hello.rkt
produces either "hello.exe" (Windows), "hello.app" (Mac OS X), or "hello" (Unix), which runs the same as running the "hello.rkt" module in gracket.
Library modules or other files that are referenced
dynamically—
Modules that are implemented directly by extensions—
The raco exe command works only with module-based programs. The compiler/embed library provides a more general interface to the embedding mechanism.
A stand-alone executable is “stand-alone” in the sense that you can run it without starting racket, gracket, or DrRacket. However, the executable depends on Racket shared libraries, and possibly other run-time files declared via define-runtime-path. The executable can be packaged with support libraries to create a distribution using raco distribute, as described in raco distribute: Sharing Stand-Alone Executables.
The --ico (Windows) or --icns (Mac OS X) flag sets the icon for the generated executable. For generally, ++aux attaches information to the executable based on the auxilliary file’s suffix; see extract-aux-from-path for a list of recognized suffixes and meanings.
The -l or --launcher flag creates a launcher instead of a stand-alone executable. See Installation-Specific Launchers for more information on launchers. The --lib has no effect in that case.
3.1 API for Creating Executables
Embedding walks the module dependency graph to find all modules needed by some initial set of top-level modules, compiling them if needed, and combining them into a “module bundle.” In addition to the module code, the bundle extends the module name resolver, so that modules can be required with their original names, and they will be retrieved from the bundle instead of the filesystem.
The create-embedding-executable function combines the bundle with an executable (Racket or GRacket). The write-module-bundle function prints the bundle to the current output port, instead; this stream can be loaded directly by a running program, as long as the read-accept-compiled parameter is true.
procedure
(create-embedding-executable dest #:modules mod-list [ #:configure-via-first-module? config-via-first? #:literal-files literal-files #:literal-expression literal-sexp #:literal-expressions literal-sexps #:cmdline cmdline #:gracket? gracket? #:mred? mred? #:variant variant #:aux aux #:collects-path collects-path #:collects-dest collects-dest #:launcher? launcher? #:verbose? verbose? #:expand-namespace expand-namespace #:compiler compile-proc #:src-filter src-filter #:on-extension ext-proc #:get-extra-imports extras-proc]) → void? dest : path-string?
mod-list :
(listof (or/c (list/c (or/c symbol? (one-of/c #t #f)) (or/c module-path? path?)) (list/c (or/c symbol? (one-of/c #t #f)) (or/c module-path? path?) (listof symbol?)))) config-via-first? : any/c = #f literal-files : (listof path-string?) = null literal-sexp : any/c = #f
literal-sexps : list? =
(if literal-sexp (list literal-sexp) null) cmdline : (listof string?) = null gracket? : any/c = #f mred? : any/c = #f variant : (or/c 'cgc '3m) = (system-type 'gc) aux : (listof (cons/c symbol? any/c)) = null
collects-path :
(or/c #f path-string? (listof path-string?)) = #f collects-dest : (or/c #f path-string?) = #f launcher? : any/c = #f verbose? : any/c = #f expand-namespace : namespace? = (current-namespace)
compile-proc : (any/c . -> . compiled-expression?) =
(lambda (e) (parameterize ([current-namespace expand-namespace]) (compile e))) src-filter : (path? . -> . any) = (lambda (p) #t) ext-proc : (or/c #f (path-string? boolean? . -> . any)) = #f
extras-proc :
(path? compiled-module-expression? . -> . (listof module-path?)) = (lambda (p m) null)
The embedding executable is written to dest, which is overwritten if it exists already (as a file or directory).
The embedded code consists of module declarations followed by additional (arbitrary) code. When a module is embedded, every module that it imports is also embedded. Library modules are embedded so that they are accessible via their lib paths in the initial namespace except as specified in mod-list, other modules (accessed via local paths and absolute paths) are embedded with a generated prefix, so that they are not directly accessible.
The #:modules argument mod-list designates modules to be embedded, as described below. The #:literal-files and #:literal-expressions arguments specify literal code to be copied into the executable: the content of each file in literal-files is copied in order (with no intervening space), followed by each element of literal-sexps. The literal-files files or literal-sexps list can contain compiled bytecode, and it’s possible that the content of the literal-files files only parse when concatenated; the files and expression are not compiled or inspected in any way during the embedding process. Beware that the initial namespace contains no bindings; use compiled expressions to bootstrap the namespace. If literal-sexp is #f, no literal expression is included in the executable. The #:literal-expression (singular) argument is for backward compatibility.
If the #:configure-via-first-module? argument is specified as true, then the language of the first module in mod-list is used to configure the run-time environment before the expressions added by #:literal-files and #:literal-expressions are evaluated. See also Language Run-Time Configuration.
The #:cmdline argument cmdline contains command-line strings that are prefixed onto any actual command-line arguments that are provided to the embedding executable. A command-line argument that evaluates an expression or loads a file will be executed after the embedded code is loaded.
Each element of the #:modules argument mod-list is a two- or three-item list, where the first item is a prefix for the module name, and the second item is a module path datum (that’s in the format understood by the default module name resolver), and the third is a list of submodule names to be included if they are available. The prefix can be a symbol, #f to indicate no prefix, or #t to indicate an auto-generated prefix. For example,
'((#f "m.rkt"))
embeds the module m from the file "m.rkt", without prefixing the name of the module; the literal-sexpr argument to go with the above might be '(require m). When submodules are available and included, the submodule is given a name by symbol-appending the write form of submodule path to the enclosing module’s name.
Modules are normally compiled before they are embedded into the target executable; see also #:compiler and #:src-filter below. When a module declares run-time paths via define-runtime-path, the generated executable records the path (for use both by immediate execution and for creating a distribution that contains the executable).
If collects-dest is a path instead of #f, then instead of embedding collection-based modules into the executable, the modules (in compiled form, only) are copied into collections in the collects-dest directory.
The optional #:aux argument is an association list for platform-specific options (i.e., it is a list of pairs where the first element of the pair is a key symbol and the second element is the value for that key). See also build-aux-from-path. The currently supported keys are as follows:
'icns (Mac OS X) : An icon file path (suffix ".icns") to use for the executable’s desktop icon.
'ico (Windows) : An icon file path (suffix ".ico") to use for the executable’s desktop icon; the executable will have 16x16, 32x32, and 48x48 icons at 4-bit, 8-bit, and 32-bit (RGBA) depths; the icons are copied and generated from any 16x16, 32x32, and 48x48 icons in the ".ico" file.
'creator (Mac OS X) : Provides a 4-character string to use as the application signature.
'file-types (Mac OS X) : Provides a list of association lists, one for each type of file handled by the application; each association is a two-element list, where the first (key) element is a string recognized by Finder, and the second element is a plist value (see xml/plist). See "drracket.filetypes" in the "drracket" collection for an example.
'uti-exports (Mac OS X) : Provides a list of association lists, one for each Uniform Type Identifier (UTI) exported by the executable; each association is a two-element list, where the first (key) element is a string recognized in a UTI declaration, and the second element is a plist value (see xml/plist). See "drracket.utiexports" in the "drracket" collection for an example.
'resource-files (Mac OS X) : extra files to copy into the "Resources" directory of the generated executable.
'framework-root (Mac OS X) : A string to prefix the executable’s path to the Racket and GRacket frameworks (including a separating slash); note that when the prefix starts "@executable_path/" works for a Racket-based application, the corresponding prefix start for a GRacket-based application is "@executable_path/../../../"; if #f is supplied, the executable’s framework path is left as-is, otherwise the original executable’s path to a framework is converted to an absolute path if it was relative.
'dll-dir (Windows) : A string/path to a directory that contains Racket DLLs needed by the executable, such as "racket‹version›.dll", or a boolean; a path can be relative to the executable; if #f is supplied, the path is left as-is; if #t is supplied, the path is dropped (so that the DLLs must be in the system directory or the user’s PATH); if no value is supplied the original executable’s path to DLLs is converted to an absolute path if it was relative.
'subsystem (Windows) : A symbol, either 'console for a console application or 'windows for a consoleless application; the default is 'console for a Racket-based application and 'windows for a GRacket-based application; see also 'single-instance?, below.
'single-instance? (Windows) : A boolean for GRacket-based apps; the default is #t, which means that the app looks for instances of itself on startup and merely brings the other instance to the front; #f means that multiple instances are expected.
'forget-exe? (Windows, Mac OS X) : A boolean; #t for a launcher (see launcher? below) does not preserve the original executable name for (find-system-path 'exec-file); the main consequence is that library collections will be found relative to the launcher instead of the original executable.
'original-exe? (Unix) : A boolean; #t means that the embedding uses the original Racket or GRacket executable, instead of a wrapper binary that execs the original; the default is #f.
'relative? (Unix, Windows, Mac OS X) : A boolean; #t means that, to the degree that the generated executable must refer to another, it can use a relative path (so the executables can be moved together, but not separately); a #f value (the default) means that absolute paths should be used (so the generated executable can be moved).
'wm-class (Unix) : A string; used as the default WM_CLASS program class for the program’s windows.
If the #:collects-path argument is #f, then the
created executable maintains its built-in (relative) path to the main
"collects" directory—
If the #:launcher? argument is #t, then lid-list should be null, literal-files should be null, literal-sexp should be #f, and the platform should be Windows or Mac OS X. The embedding executable is created in such a way that (find-system-path 'exec-file) produces the source Racket or GRacket path instead of the embedding executable (but the result of (find-system-path 'run-file) is still the embedding executable).
The #:variant argument indicates which variant of the original binary to use for embedding. The default is (system-type 'gc); see also current-launcher-variant.
The #:compiler argument is used to compile the source of modules to be included in the executable (when a compiled form is not already available). It should accept a single argument that is a syntax object for a module form. The default procedure uses compile parameterized to set the current namespace to expand-namespace.
The #:expand-namespace argument selects a namespace for expanding extra modules (and for compiling using the default compile-proc). Extra-module expansion is needed to detect run-time path declarations in included modules, so that the path resolutions can be directed to the current locations (and, ultimately, redirected to copies in a distribution).
The #:src-filter src-filter argument takes a path and returns true if the corresponding file source should be included in the embedding executable in source form (instead of compiled form), #f otherwise. The default returns #f for all paths. Beware that the current output port may be redirected to the result executable when the filter procedure is called. Each path given to src-filter corresponds to the actual file name (e.g., ".ss"/".rkt" conversions have been applied as needed to refer to the existing file).
If the #:on-extension argument is a procedure, the procedure is called when the traversal of module dependencies arrives at an extension (i.e., a DLL or shared object). The default, #f, causes a reference to a single-module extension (in its current location) to be embedded into the executable. The procedure is called with two arguments: a path for the extension, and a #f (for historical reasons).
The #:get-extra-imports extras-proc argument takes a source pathname and compiled module for each module to be included in the executable. It returns a list of quoted module paths (absolute, as opposed to relative to the module) for extra modules to be included in the executable in addition to the modules that the source module requires. For example, these modules might correspond to reader extensions needed to parse a module that will be included as source, as long as the reader is referenced through an absolute module path. Each path given to extras-proc corresponds to the actual file name (e.g., ".ss"/".rkt" conversions have been applied as needed to refer to the existing file).
procedure
(make-embedding-executable dest mred? verbose? mod-list literal-files literal-sexp cmdline [ aux launcher? variant collects-path]) → void? dest : path-string? mred? : any/c verbose? : any/c
mod-list :
(listof (or/c (list/c (or/c symbol? (one-of/c #t #f)) (or/c module-path? path?)) (list/c (or/c symbol? (one-of/c #t #f)) (or/c module-path? path?) (listof symbol?)))) literal-files : (listof path-string?) literal-sexp : any/c cmdline : (listof string?) aux : (listof (cons/c symbol? any/c)) = null launcher? : any/c = #f variant : (one-of/c 'cgc '3m) = (system-type 'gc)
collects-path :
(or/c #f path-string? (listof path-string?)) = #f
procedure
(write-module-bundle verbose? mod-list literal-files literal-sexp) → void? verbose? : any/c
mod-list :
(listof (or/c (list/c (or/c symbol? (one-of/c #t #f)) (or/c module-path? path?)) (list/c (or/c symbol? (one-of/c #t #f)) (or/c module-path? path?) (listof symbol?)))) literal-files : (listof path-string?) literal-sexp : any/c
procedure
(embedding-executable-is-directory? mred?) → boolean
mred? : any/c
procedure
(embedding-executable-is-actually-directory? mred?) → boolean?
mred? : any/c
procedure
(embedding-executable-put-file-extension+style+filters mred?)
→
(or/c string? false/c) (listof (one-of/c 'packages 'enter-packages)) (listof (list/c string? string?)) mred? : any/c
If Racket/GRacket launchers for the current platform were directories form the user’s perspective, the style result is suitable for use with get-directory, and the extension result may be a string indicating a required extension for the directory name.
procedure
(embedding-executable-add-suffix path mred?) → path-string? path : path-string? mred? : any/c
3.1.1 Executable Creation Signature
(require compiler/embed-sig) |
signature
compiler:embed^ : signature
3.1.2 Executable Creation Unit
(require compiler/embed-unit) |
value
3.1.3 Finding the Racket Executable
(require compiler/find-exe) |
procedure
gracket? : any/c = #f variant : (or/c 'cgc '3m) = (system-type 'gc)
3.2 Installation-Specific Launchers
A launcher is similar to a stand-alone executable, but a launcher is usually smaller and can be created more quickly, because it depends permanently on the local Racket installation and the program’s sources. In the case of Unix, a launcher is simply a shell script that runs racket or gracket. Launchers cannot be packaged into a distribution using raco distribute. The raco exe command creates a launcher when the -l or --launcher flag is specified.
(require launcher/launcher) |
The launcher/launcher library provides functions for creating launchers.
3.2.1 Creating Launchers
procedure
(make-gracket-launcher args dest [aux]) → void?
args : (listof string?) dest : path-string? aux : (listof (cons/c symbol? any/c)) = null
The optional aux argument is an association list for platform-specific options (i.e., it is a list of pairs where the first element of the pair is a key symbol and the second element is the value for that key). See also build-aux-from-path. See create-embedding-executable for a list that applies to both stand-alone executables and launchers on Windows and Mac OS X GRacket; the following additional associations apply to launchers:
'independent? (Windows) —
a boolean; #t creates an old-style launcher that work with any Racket or GRacket binary, like setup-plt.exe. No other aux associations are used for an old-style launcher. 'exe-name (Mac OS X, 'script-3m or 'script-cgc variant) —
provides the base name for a '3m-/'cgc-variant launcher, which the script will call ignoring args. If this name is not provided, the script will go through the GRacket executable as usual. 'relative? (all platforms) —
a boolean, where #t means that the generated launcher should find the base GRacket executable through a relative path.
For Unix/X, the script created by make-mred-launcher detects and handles X Windows flags specially when they appear as the initial arguments to the script. Instead of appending these arguments to the end of args, they are spliced in after any X Windows flags already listed in args. The remaining arguments (i.e., all script flags and arguments after the last X Windows flag or argument) are then appended after the spliced args.
procedure
(make-racket-launcher args dest [aux]) → void?
args : (listof string?) dest : path-string? aux : (listof (cons/c symbol? any/c)) = null
procedure
(make-gracket-program-launcher file collection dest) → void? file : string? collection : string? dest : path-string?
procedure
(make-racket-program-launcher file collection dest) → void? file : string? collection : string? dest : path-string?
procedure
(install-gracket-program-launcher file collection name) → void? file : string? collection : string? name : string?
(make-gracket-program-launcher file collection (gracket-program-launcher-path name))
procedure
(install-racket-program-launcher file collection name) → void? file : string? collection : string? name : string?
(make-racket-program-launcher file collection (racket-program-launcher-path name))
procedure
(make-mred-launcher args dest [aux]) → void?
args : (listof string?) dest : path-string? aux : (listof (cons/c symbol? any/c)) = null
procedure
(make-mred-program-launcher file collection dest) → void? file : string? collection : string? dest : path-string?
procedure
(install-mred-program-launcher file collection name) → void? file : string? collection : string? name : string?
procedure
(make-mzscheme-launcher args dest [aux]) → void?
args : (listof string?) dest : path-string? aux : (listof (cons/c symbol? any/c)) = null
procedure
(make-mzscheme-program-launcher file collection dest) → void? file : string? collection : string? dest : path-string?
procedure
(install-mzscheme-program-launcher file collection name) → void? file : string? collection : string? name : string?
3.2.2 Launcher Path and Platform Conventions
procedure
(gracket-program-launcher-path name) → path?
name : string?
procedure
(racket-program-launcher-path name) → path?
name : string?
procedure
procedure
procedure
procedure
procedure
(gracket-launcher-add-suffix path-string?) → path?
path-string? : path
procedure
(racket-launcher-add-suffix path-string?) → path?
path-string? : path
procedure
→
(or/c string? false/c) (listof (one-of/c 'packages 'enter-packages)) (listof (list/c string? string?))
If GRacket launchers for the current platform were directories form the user’s perspective, the style result is suitable for use with get-directory, and the extension result may be a string indicating a required extension for the directory name.
procedure
→
(or/c string? false/c) (listof (one-of/c 'packages 'enter-packages)) (listof (list/c string? string?))
procedure
(mred-program-launcher-path name) → path?
name : string?
procedure
procedure
procedure
(mred-launcher-add-suffix path-string?) → path?
path-string? : path
procedure
→
(or/c string? false/c) (listof (one-of/c 'packages 'enter-packages)) (listof (list/c string? string?))
procedure
(mzscheme-program-launcher-path name) → path?
name : string?
procedure
procedure
procedure
(mzscheme-launcher-add-suffix path-string?) → path?
path-string? : path
procedure
→
(or/c string? false/c) (listof (one-of/c 'packages 'enter-packages)) (listof (list/c string? string?))
3.2.3 Launcher Configuration
procedure
(gracket-launcher-up-to-date? dest aux) → boolean?
dest : path-string? aux : (listof (cons/c symbol? any/c))
procedure
(racket-launcher-up-to-date? dest aux) → boolean?
dest : path-string? aux : (listof (cons/c symbol? any/c))
procedure
(build-aux-from-path path) → (listof (cons/c symbol? any/c))
path : path-string?
procedure
(extract-aux-from-path path) → (listof (cons/c symbol? any/c))
path : path-string?
".icns" → 'icns file for use on Mac OS X
".ico" → 'ico file for use on Windows
".lch" → 'independent? as #t (the file content is ignored) for use on Windows
".creator" → 'creator as the initial four characters in the file for use on Mac OS X
".filetypes" → 'file-types as read content (a single S-expression), and 'resource-files as a list constructed by finding "CFBundleTypeIconFile" entries in 'file-types (and filtering duplicates); for use on Mac OS X
".utiexports" → 'uti-exports as read content (a single S-expression); for use on Mac OS X
".wmclass" → 'wm-class as the literal content, removing a trailing newline if any; for use on Unix
parameter
(current-launcher-variant variant) → void? variant : symbol?
procedure
procedure
procedure
(mred-launcher-up-to-date? dest aux) → boolean?
dest : path-string? aux : (listof (cons/c symbol? any/c))
procedure
(mzscheme-launcher-up-to-date? dest aux) → boolean?
dest : path-string? aux : (listof (cons/c symbol? any/c))
procedure
procedure
3.2.4 Launcher Creation Signature
(require launcher/launcher-sig) |
signature
launcher^ : signature
3.2.5 Launcher Creation Unit
(require launcher/launcher-unit) |