infrastructure for raco ctool --c-mods <dest> --runtime <dir>

Make the runtime-file gatherer, which is normally used by `raco exec`,
work also for modules prepared for an executable that embeds Racket.
This commit is contained in:
Matthew Flatt 2015-09-18 18:55:22 -06:00
parent a9015e5484
commit 1a48418844
5 changed files with 91 additions and 37 deletions

View File

@ -200,6 +200,16 @@ int main(int argc, char *argv[])
}
}
If modules embedded in the executable need to access runtime files
(via @racketmodname[racket/runtime-path] forms), supply the
@DFlag{runtime} flag to @exec{raco ctool}, specifying a directory
where the runtime files are to be gathered. The modules in the
generated @filepath{.c} file will then refer to the files in that
directory; the directory is normally specified relative to the
executable, but the embedding application must call
@cppi{scheme_set_exec_cmd} to set the executable path (typically
@cpp{argv[0]}) before declaring modules.
On Mac OS X, or on Windows when Racket is compiled to a DLL
using Cygwin, the garbage collector cannot find static variables
automatically. In that case, @cppi{scheme_main_setup} must be called with a

View File

@ -64,6 +64,13 @@ Sets the path to be returned by @racket[(find-system-path
'addon-dir)].}
@function[(void scheme_set_exec_cmd
[const-char* path])]{
Sets the path to be returned by @racket[(find-system-path
'exec-file)].}
@function[(void scheme_init_collection_paths_post
[Scheme_Env* env]
[Scheme_Object* pre_extra_paths]

View File

@ -1,5 +1,7 @@
#lang scribble/doc
@(require scribble/manual "common.rkt")
@(require scribble/manual
"common.rkt"
scribble/bnf)
@title[#:tag "c-mods"]{Embedding Modules via C}
@ -14,3 +16,11 @@ a @tt{declare_modules} function that puts the module declarations into
a namespace. Thus, using the output of @exec{raco ctool --c-mods}, a
program can embed Racket with a set of modules so that it does not
need a @filepath{collects} directory to load modules at run time.
If the embedded modules refer to runtime files, the files can be
gathers by supplying the @DFlag{runtime} argument to @exec{raco ctool
--cmods}, specifying a directory @nonterm{dir} to hold the files.
Normally, @nonterm{dir} is a relative path, and files are found at run
time in @nonterm{dir} relative to the executable, but a separate path
(usually relative) for run time can be specified with
@DFlag{runtime-access}.

View File

@ -16,17 +16,26 @@ perform the same work as @exec{raco distribute}.}
@defproc[(assemble-distribution [dest-dir path-string?]
[exec-files (listof path-string?)]
[#:executables? executables? any/c #t]
[#:relative-base relative-base (or/c path-string? #f) #f]
[#:collects-path path (or/c false/c (and/c path-string? relative-path?)) #f]
[#:copy-collects dirs (listof path-string?) null])
void?]{
Copies the executables in @racket[exec-files] to the directory
@racket[dest-dir], along with DLLs, frameworks, and/or shared
libraries that the executables need to run a different machine.
@racket[dest-dir], along with DLLs, frameworks, shared libraries,
and/or runtime files that the executables need to run a different
machine. If @racket[executables?] is @racket[#f], then the
@racket[exec-files] are treated as plain data files, instead of
executables, and they are modified in-place.
The arrangement of the executables and support files in
@racket[dest-dir] depends on the platform. In general
@racket[assemble-distribution] tries to do the Right Thing.
@racket[dest-dir] depends on the platform. In general,
@racket[assemble-distribution] tries to do the Right Thing, but a
non-@racket[#f] value for @racket[relative-base] specifies a
path for reaching the assembled content relative to the executable at
run time. When @racket[executables?] is @racket[#f], then the default
access path is @racket[dest-dir], with its relativeness preserved.
If a @racket[#:collects-path] argument is given, it overrides the
default location of the main @filepath{collects} directory for the
@ -35,4 +44,7 @@ directory (typically inside it).
The content of each directory in the @racket[#:copy-collects] argument
is copied into the main @filepath{collects} directory for the packaged
executables.}
executables.
@history[#:changed "6.2.900.17" @elem{Added the @racket[#:executables?]
and @racket[#:relative-base] arguments.}]}

View File

@ -17,42 +17,50 @@
(define (assemble-distribution dest-dir
orig-binaries
#:executables? [executables? #t]
#:relative-base [relative-base #f]
#:collects-path [collects-path #f] ; relative to dest-dir
#:copy-collects [copy-collects null])
(let* ([types (map get-binary-type orig-binaries)]
(let* ([types (if executables?
(map get-binary-type orig-binaries)
(map (lambda (v) #f) orig-binaries))]
[_ (unless (directory-exists? dest-dir)
(make-directory dest-dir))]
[sub-dirs (map (lambda (b type)
(case (cross-system-type)
[(windows) #f]
[(unix) "bin"]
[(macosx) (if (memq type '(gracketcgc gracket3m))
#f
"bin")]))
orig-binaries
(and type
(case (cross-system-type)
[(windows) #f]
[(unix) "bin"]
[(macosx) (if (memq type '(gracketcgc gracket3m))
#f
"bin")])))
orig-binaries
types)]
;; Copy binaries into place:
[binaries
(map (lambda (b sub-dir type)
(let ([dest-dir (if sub-dir
(build-path dest-dir sub-dir)
dest-dir)])
(unless (directory-exists? dest-dir)
(make-directory dest-dir))
(let-values ([(base name dir?) (split-path b)])
(let ([dest (build-path dest-dir name)])
(if (and (memq type '(gracketcgc gracket3m))
(eq? 'macosx (cross-system-type)))
(begin
(copy-app b dest)
(app-to-file dest))
(begin
(copy-file* b dest)
dest))))))
(if type
(let ([dest-dir (if sub-dir
(build-path dest-dir sub-dir)
dest-dir)])
(unless (directory-exists? dest-dir)
(make-directory dest-dir))
(let-values ([(base name dir?) (split-path b)])
(let ([dest (build-path dest-dir name)])
(if (and (memq type '(gracketcgc gracket3m))
(eq? 'macosx (cross-system-type)))
(begin
(copy-app b dest)
(app-to-file dest))
(begin
(copy-file* b dest)
dest)))))
b))
orig-binaries
sub-dirs
types)]
[single-mac-app? (and (eq? 'macosx (cross-system-type))
[single-mac-app? (and executables?
(eq? 'macosx (cross-system-type))
(= 1 (length types))
(memq (car types) '(gracketcgc gracket3m)))])
;; Create directories for libs, collects, and extensions:
@ -78,7 +86,8 @@
(let* ([specific-lib-dir
(build-path "lib"
"plt"
(if (null? binaries)
(if (or (not executables?)
(null? binaries))
"generic"
(let-values ([(base name dir?)
(split-path (car binaries))])
@ -96,7 +105,8 @@
(make-directory* collects-dir)
(make-directory* exts-dir)
;; Copy libs into place
(install-libs lib-dir types)
(when executables?
(install-libs lib-dir types))
;; Copy collections into place
(for-each (lambda (dir)
(for-each (lambda (f)
@ -106,10 +116,14 @@
(directory-list dir)))
copy-collects)
;; Patch binaries to find libs
(patch-binaries binaries types)
(when executables?
(patch-binaries binaries types))
(let ([relative->binary-relative
(lambda (sub-dir type relative-dir)
(cond
[relative-base relative-base]
[(not executables?)
(build-path dest-dir relative-dir)]
[sub-dir
(build-path 'up relative-dir)]
[(and (eq? 'macosx (cross-system-type))
@ -120,10 +134,11 @@
relative-dir]))])
;; Patch binaries to find collects
(for-each (lambda (b type sub-dir)
(set-collects-path
b
(collects-path->bytes
(relative->binary-relative sub-dir type relative-collects-dir))))
(when type
(set-collects-path
b
(collects-path->bytes
(relative->binary-relative sub-dir type relative-collects-dir)))))
binaries types sub-dirs)
(unless (null? binaries)
;; Copy over extensions and adjust embedded paths: