diff --git a/pkgs/base/info.rkt b/pkgs/base/info.rkt index e6317e2e38..e8191da74e 100644 --- a/pkgs/base/info.rkt +++ b/pkgs/base/info.rkt @@ -12,7 +12,7 @@ (define collection 'multi) -(define version "6.5.0.1") +(define version "6.5.0.2") (define deps `("racket-lib" ["racket" #:version ,version])) diff --git a/pkgs/racket-doc/help/info.rkt b/pkgs/racket-doc/help/info.rkt index 05cf936c72..6c69bb06ca 100644 --- a/pkgs/racket-doc/help/info.rkt +++ b/pkgs/racket-doc/help/info.rkt @@ -1,6 +1,6 @@ #lang info -(define post-install-collection "installer.rkt") +(define install-collection "installer.rkt") (define raco-commands '(("docs" help/help "search and view documentation" 110))) (define scribblings '(("help.scrbl"))) diff --git a/pkgs/racket-doc/help/installer.rkt b/pkgs/racket-doc/help/installer.rkt index ef31128e9d..00f862d495 100644 --- a/pkgs/racket-doc/help/installer.rkt +++ b/pkgs/racket-doc/help/installer.rkt @@ -1,18 +1,36 @@ #lang scheme/base +(require launcher + setup/dirs) ;; Builds different kinds of executables for different platforms. ;; The `plt-help' executable is for backward compatibity. ;; The `Racket Documentation' executable is to help Windows and ;; Mac users who are completely lost and need something to click. -(provide post-installer) -(require launcher) +(provide installer) -(define (post-installer path collection user?) +(define (installer path coll user? no-main?) + (unless no-main? + (do-installer path coll user? #f) + (when (and (not user?) + (find-config-tethered-console-bin-dir)) + (do-installer path coll #f #t))) + (when (find-addon-tethered-console-bin-dir) + (do-installer path coll #t #t))) + +(define (do-installer path collection user? tethered?) (for ([mr? (case (system-type) [(macosx) '(#t #f)] [(windows) '(#t)] - [else '(#f)])]) + [else '(#f)])] + #:when (or (not tethered?) + (if mr? + (if user? + (find-addon-tethered-gui-bin-dir) + (find-config-tethered-gui-bin-dir)) + (if user? + (find-addon-tethered-console-bin-dir) + (find-config-tethered-console-bin-dir))))) (define-values (variants mk-launcher mk-path extras) (if mr? (values available-mred-variants @@ -26,10 +44,12 @@ '()))) (for ([variant (remove* '(script-3m script-cgc) (variants))]) (parameterize ([current-launcher-variant variant]) - (mk-launcher '("-l-" "help/help") - (mk-path (if mr? "Racket Documentation" "plt-help") #:user? user?) + (mk-launcher #:tether-mode (and tethered? (if user? 'addon 'config)) + (append + '("-l-" "help/help")) + (mk-path (if mr? "Racket Documentation" "plt-help") #:user? user? #:tethered? tethered?) `([exe-name . ,(if mr? "Racket Documentation" "plt-help")] [relative? . ,(not user?)] [install-mode . ,(if user? 'user 'main)] - [start-menu? . #t] + [start-menu? . ,(not user?)] ,@extras)))))) diff --git a/pkgs/racket-doc/info.rkt b/pkgs/racket-doc/info.rkt index e80f691186..3bc80197e5 100644 --- a/pkgs/racket-doc/info.rkt +++ b/pkgs/racket-doc/info.rkt @@ -3,7 +3,7 @@ (define collection 'multi) (define deps '("scheme-lib" - "base" + ["base" #:version "6.5.0.2"] "net-lib" "sandbox-lib" ["scribble-lib" #:version "1.14"] diff --git a/pkgs/racket-doc/scribblings/raco/config.scrbl b/pkgs/racket-doc/scribblings/raco/config.scrbl index d1fe91c0ca..1184e4f1f4 100644 --- a/pkgs/racket-doc/scribblings/raco/config.scrbl +++ b/pkgs/racket-doc/scribblings/raco/config.scrbl @@ -18,6 +18,10 @@ to configure other directories as described below. Use the @racketmodname[setup/dirs] library (which combines information from the configuration files and other sources) to locate configured directories, instead of reading @filepath{config.rktd} directly. +A @filepath{config.rktd} file can also appear in the directory +@racket[(build-path (find-system-path 'addon-dir) "etc")], but it +controls only the results of @racket[find-addon-tethered-console-bin-dir] and +@racket[find-addon-tethered-gui-bin-dir]. The path of the @deftech{main collection directory} is built into the Racket executable, and it can be changed via the @@ -166,4 +170,12 @@ directory}: binary identifies itself as CGC, then the suffix is @racket["3m"], otherwise it is @racket[""].} -] + @item{@indexed-racket['config-tethered-console-bin-dir] and + @indexed-racket['config-tethered-gui-bin-dir] --- a path for a + directory to hold extra copies of executables that are tied to the + configuration directory (as reported by @racket[find-config-dir]) + that is active at the time the executables are created. See also + @racket[find-config-tethered-console-bin-dir] and + @racket[find-config-tethered-gui-bin-dir].} + + ] diff --git a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl index 24b5c9183e..075bda22ed 100644 --- a/pkgs/racket-doc/scribblings/raco/exe-api.scrbl +++ b/pkgs/racket-doc/scribblings/raco/exe-api.scrbl @@ -15,7 +15,8 @@ compiler/embed-unit racket/runtime-path launcher/launcher - compiler/find-exe)) + compiler/find-exe + setup/dirs)) @title{API for Creating Executables} @@ -474,6 +475,7 @@ A unit that imports nothing and exports @racket[compiler:embed^].} @defmodule[compiler/find-exe] @defproc[(find-exe [#:cross? cross? any/c #f] + [#:untetherd? untethered? any/c #f] [gracket? any/c #f] [variant (or/c 'cgc '3m) (if cross? (cross-system-type 'gc) @@ -486,4 +488,10 @@ A unit that imports nothing and exports @racket[compiler:embed^].} If @racket[cross?] is true, the executable is found for the target platform in @seclink["cross-system"]{cross-installation mode}. - @history[#:changed "6.3" @elem{Added the @racket[#:cross?] argument.}]} + If @racket[untethered?] is true, then the original executable is + found, instead of an executable that is tethered to a configuration + or addon directory via @racket[(find-addon-tethered-console-bin-dir)] + and related functions. + + @history[#:changed "6.3" @elem{Added the @racket[#:cross?] argument.} + #:changed "6.2.0.5" @elem{Added the @racket[#:untethered?] argument.}]} diff --git a/pkgs/racket-doc/scribblings/raco/launcher.scrbl b/pkgs/racket-doc/scribblings/raco/launcher.scrbl index ce1500dc0d..fed3699922 100644 --- a/pkgs/racket-doc/scribblings/raco/launcher.scrbl +++ b/pkgs/racket-doc/scribblings/raco/launcher.scrbl @@ -28,7 +28,8 @@ creating @tech{launchers}. @defproc[(make-gracket-launcher [args (listof string?)] [dest path-string?] - [aux (listof (cons/c symbol? any/c)) null]) + [aux (listof (cons/c symbol? any/c)) null] + [#:tether-mode tether-mode (or/c 'addon 'config #f) 'addon]) void?]{ Creates the launcher @racket[dest], which starts GRacket with the @@ -69,9 +70,13 @@ the following additional associations apply to launchers: base GRacket executable through a relative path.} @item{@racket['install-mode] (Windows, Unix) --- either - @racket['user] or @racket['main], indicates that the launcher - is being installed to a user-specific place or to an - installation-wide place, which in turn determines where to + @racket['main], @racket['user], @racket['config-tethered], or + @racket['addon-tethered], indicates that the launcher + is being installed to an + installation-wide place, a user-specific place, an installation-wide + place that embeds the configuration path, or a specific place that + embeds an addon-directory path; + the install mode, in turn, determines whether and where to record @racket['start-menu], @racket['extension-registry], and/or @racket['desktop] information.} @@ -146,7 +151,17 @@ arguments to the script. Instead of appending these arguments to the end of @racket[args], they are spliced in after any X Windows flags already listed in @racket[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 @racket[args].} +argument) are then appended after the spliced @racket[args]. + +The @racket[tether-mode] argument indicates how much to preserve the +current installation's tethering to a configuration directory and/or +addon directory based on @racket[(find-addon-tether-console-bin-dir)] +and @racket[(find-config-tether-console-bin-dir)]. The @racket['addon] +mode allows full tethering, the @racket['config] mode allows only +configuration-directory tethering, and the @racket[#f] mode disables +tethering. + +@history[#:changed "6.5.0.2" @elem{Added the @racket[#:tether-mode] argument.}]} @defproc[(make-racket-launcher [args (listof string?)] @@ -251,27 +266,50 @@ arguments.} @section{Launcher Path and Platform Conventions} @defproc[(gracket-program-launcher-path [name string?] - [#:user? user? any/c #f]) + [#:user? user? any/c #f] + [#:tethered? tethered? any/c #f]) path?]{ Returns a pathname for an executable called something like @racket[name] -in the Racket installation (if @racket[user?] is @racket[#f]) or the -user's Racket executable directory (if @racket[user?] is @racket[#t]). +in + +@itemlist[ + + @item{the Racket installation --- when @racket[user?] is @racket[#f] + and @racket[tethered?] is @racket[#f];} + + @item{the user's Racket executable directory --- when @racket[user?] + is @racket[#t] and @racket[tethered?] is @racket[#f];} + + @item{an additional executable directory for executables tethered to a + particular configuration directory --- when @racket[user?] is + @racket[#f] and @racket[tethered?] is @racket[#t]; or} + + @item{an additional executable directory for executables tethered to + a particular addon and configuration directory --- when + @racket[user?] is @racket[#t] and @racket[tethered?] is + @racket[#t].} + +] + For Windows, the @filepath{.exe} suffix is automatically appended to @racket[name]. For Unix, @racket[name] is changed to lowercase, whitespace is changed to @litchar{-}, and the path includes the @filepath{bin} subdirectory of the Racket installation. For Mac OS X, the @filepath{.app} suffix -is appended to @racket[name].} +is appended to @racket[name]. + +@history[#:changed "6.5.0.2" @elem{Added the @racket[#:tethered?] argument.}]} @defproc[(racket-program-launcher-path [name string?] - [#:user? user? any/c #f]) + [#:user? user? any/c #f] + [#:tethered? tethered? any/c #f]) path?]{ -Returns the same path as @racket[(gracket-program-launcher-path name #:user? user?)] -for Unix and Windows. For Mac OS X, the result is the same as for -Unix.} +Returns the same path as @racket[(gracket-program-launcher-path name #:user? user? #:tethered tethered?)]. + +@history[#:changed "6.5.0.2" @elem{Added the @racket[#:tethered?] argument.}]} @defproc[(gracket-launcher-is-directory?) boolean?]{ @@ -335,7 +373,7 @@ Like @racket[gracket-launcher-get-file-extension+style+filters], but for Racket launchers.} @deftogether[( -@defproc[(mred-program-launcher-path [name string?] [#:user? user? any/c #f]) path?] +@defproc[(mred-program-launcher-path [name string?] [#:user? user? any/c #f] [#:tethered? tethered? any/c #f]) path?] @defproc[(mred-launcher-is-directory?) boolean?] @defproc[(mred-launcher-is-actually-directory?) boolean?] @defproc[(mred-launcher-add-suffix [path-string? path]) path?] @@ -346,10 +384,12 @@ Racket launchers.} )]{ Backward-compatible aliases for -@racket[gracket-program-launcher-path], etc.} +@racket[gracket-program-launcher-path], etc. + +@history[#:changed "6.5.0.2" @elem{Added the @racket[#:tethered?] argument.}]} @deftogether[( -@defproc[(mzscheme-program-launcher-path [name string?] [#:user? user? any/c #f]) path?] +@defproc[(mzscheme-program-launcher-path [name string?] [#:user? user? any/c #f] [#:tethered? tethered? any/c #f]) path?] @defproc[(mzscheme-launcher-is-directory?) boolean?] @defproc[(mzscheme-launcher-is-actually-directory?) boolean?] @defproc[(mzscheme-launcher-add-suffix [path-string? path]) path?] @@ -360,7 +400,9 @@ Backward-compatible aliases for )]{ Backward-compatible aliases for -@racket[racket-program-launcher-path], etc.} +@racket[racket-program-launcher-path], etc. + +@history[#:changed "6.5.0.2" @elem{Added the @racket[#:tethered?] argument.}]} @defproc[(installed-executable-path->desktop-path [exec-path path-string?] [user? any/c]) diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index a48b3fa240..06dcf8c408 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -708,35 +708,52 @@ Optional @filepath{info.rkt} fields trigger additional actions by specification is compared to @racket[(system-type)] and @racket[(system-library-subpath #f)].} - @item{@indexed-racket[install-collection] : @racket[path-string?] --- A - library module relative to the collection that provides - @racket[installer]. The @racket[installer] procedure accepts one - to three arguments. The first argument is a directory path to the - parent of the Racket installation's @filepath{collects} directory; the - second argument, if accepted, is a path to the collection's own - directory; the third argument, if accepted, is a boolean indicating + @item{@indexed-racket[install-collection] : @racket[path-string?] --- + A library module relative to the collection that provides + @racket[installer]. The @racket[installer] procedure must accept + one, two, three, or four arguments: + + @itemlist[ + + @item{The first argument is a directory path to the parent of the + Racket installation's @filepath{collects} directory.} + + @item{The second argument, if accepted, is a path to the + collection's own directory.} + + @item{The third argument, if accepted, is a boolean indicating whether the collection is installed as user-specific (@racket[#t]) - or installation-wide (@racket[#f]). The procedure should perform collection-specific - installation work, and it should avoid unnecessary work in the case - that it is called multiple times for the same installation.} + or installation-wide (@racket[#f]).} + + @item{The fourth argument, if accepted, is a boolean indicating + whether the collection is installed as installation-wide and should + nevertheless avoid modifying the installation; an + @racket[installer] procedure that does not accept this argument is + never called when the argument would be @racket[#t]. An installer + that does accept this argument is called with @racket[#t] to that + it can perform user-specific work, even though the collection is + installed installation-wide.} + + ]} @item{@indexed-racket[pre-install-collection] : @racket[path-string?] --- Like @racket[install-collection], except that the corresponding - installer is called @emph{before} the normal @filepath{.zo} build, - instead of after. The provided procedure should be named - @racket[pre-installer] in this case, so it can be provided by the - same file that provides an @racket[installer].} + installer procedures are called @emph{before} the normal @filepath{.zo} build, + instead of after. The provided procedure is + @racket[pre-installer], so it can be provided by the + same file that provides an @racket[installer] procedure.} @item{@indexed-racket[post-install-collection] : @racket[path-string?] --- - Like @racket[install-collection]. It is called right after the - @racket[install-collection] procedure is executed. The only - difference between these is that the @DFlag{no-install} flag can be - used to disable the previous two installers, but not this one. It - is therefore expected to perform operations that are always needed, + Like @racket[install-collection] for a procedure that is called right after the + @racket[install-collection] procedure is executed. The + @DFlag{no-install} flag can be provided to @exec{raco setup} + to disable @racket[install-collection] and @racket[pre-install-collection], + but not @racket[post-install-collection]. The @racket[post-install-collection] + function is therefore expected to perform operations that are always needed, even after an installation that contains pre-compiled files. The - provided procedure should be named @racket[post-installer] in this - case, so it can be provided by the same file that provides the - previous two.} + provided procedure is @racket[post-installer], so it + can be provided by the same file that provides an + @racket[installer] procedure.} @item{@indexed-racket[assume-virtual-sources] : @racket[any/c] --- A true value indicates that bytecode files without a corresponding @@ -1412,6 +1429,52 @@ function for installing a single @filepath{.plt} file. absolute path names for executable and library references, @racket[#f] otherwise.} +@deftogether[( +@defproc[(find-addon-tethered-console-bin-dir) (or/c #f path?)] +@defproc[(find-addon-tethered-gui-bin-dir) (or/c #f path?)] +)]{ + Returns a path to a user-specific directory to hold an extra copy of + each installed executable, where the extra copy is created by + @exec{raco setup} and tethered to a particular result for + @racket[(find-system-path 'addon-dir)] and + @racket[(find-config-dir)]. + + Unlike other directories, which are configured via + @filepath{config.rktd} in the @racket[(find-config-dir)] directory + (see @secref["config-file"]), these paths are configured via + @racket['addon-tethered-console-bin-dir] and + @racket['addon-tethered-gui-bin-dir] entries in + @filepath{config.rktd} in @racket[(build-path (find-system-path + 'addon-dir) "etc")]. If no configuration is present, the result from + the corresponding function, + @racket[find-addon-tethered-console-bin-dir] or + @racket[find-addon-tethered-gui-bin-dir], is @racket[#f] instead of + a path. + + The intent of this protocol is to support a kind of sandbox: an + installation that is more specific than user-specific, and where + copies of executables such as @exec{racket} serve as entry points + into the sandbox. Assuming that the addon directory is set to a + directory other than the user's default addon directory when + @exec{raco setup} creates the executable copies, then further + package build and setup operations through the entry points will be + confined to the sandbox and not affect a user's default environment. + + @history[#:added "6.5.0.2"]} + + +@deftogether[( +@defproc[(find-config-tethered-console-bin-dir) (or/c #f path?)] +@defproc[(find-config-tethered-gui-bin-dir) (or/c #f path?)] +)]{ + Similar to @racket[find-addon-tethered-console-bin-dir] and + @racket[find-addon-tethered-gui-bin-dir], but configured via + @filepath{config.rktd} in the @racket[(find-config-dir)] directory + (see @secref["config-file"]) and triggers executables that are + tethered only to a particular value of @racket[(find-config-dir)]. + + @history[#:added "6.5.0.2"]} + @; ------------------------------------------------------------------------ @section[#:tag "getinfo"]{API for Reading @filepath{info.rkt} Files} diff --git a/racket/collects/compiler/embed.rkt b/racket/collects/compiler/embed.rkt index 8ed985785f..2815d51f87 100644 --- a/racket/collects/compiler/embed.rkt +++ b/racket/collects/compiler/embed.rkt @@ -1436,7 +1436,7 @@ cmdline)) . < . 80)) (error 'create-embedding-executable "command line too long: ~e" cmdline)) (check-collects-path 'create-embedding-executable collects-path collects-path-bytes) - (let ([exe (find-exe #:cross? #t mred? variant)]) + (let ([exe (find-exe #:cross? #t #:untethered? #t mred? variant)]) (when verbose? (eprintf "Copying to ~s\n" dest)) (let-values ([(dest-exe orig-exe osx?) diff --git a/racket/collects/compiler/find-exe.rkt b/racket/collects/compiler/find-exe.rkt index 1dfc67cf54..bdad1f3e9d 100644 --- a/racket/collects/compiler/find-exe.rkt +++ b/racket/collects/compiler/find-exe.rkt @@ -5,13 +5,20 @@ (provide find-exe) (define (find-exe #:cross? [cross? #f] + #:untethered? [untethered? #f] [mred? #f] [variant (if cross? (cross-system-type 'gc) (system-type 'gc))]) (let* ([base (if mred? - (find-lib-dir) - (find-console-bin-dir))] + (or (and (not untethered?) + (find-addon-tethered-gui-bin-dir) + (find-config-tethered-gui-bin-dir)) + (find-lib-dir)) + (or (and (not untethered?) + (find-addon-tethered-console-bin-dir) + (find-config-tethered-console-bin-dir)) + (find-console-bin-dir)))] [fail (lambda () (error 'find-exe diff --git a/racket/collects/launcher/launcher.rkt b/racket/collects/launcher/launcher.rkt index 8bf48c802d..41020e4eb3 100644 --- a/racket/collects/launcher/launcher.rkt +++ b/racket/collects/launcher/launcher.rkt @@ -364,6 +364,9 @@ (format "~a~a.app/Contents/MacOS/~a~a" (cdr m) (variant-suffix variant #t) (cdr m) (variant-suffix variant #t))))] + [alt-exe-is-gracket? (and alt-exe + (let ([m (assq 'exe-is-gracket aux)]) + (and m (cdr m))))] [x-flags? (and (eq? kind 'mred) (eq? (cross-system-type) 'unix) (not (script-variant? variant)))] @@ -373,6 +376,7 @@ flags))] [post-flags (cond [x-flags? (skip-x-flags flags)] + [alt-exe-is-gracket? flags] [alt-exe null] [else flags])] [pre-flags (cond @@ -389,9 +393,12 @@ "# This script was created by make-" (symbol->string kind)"-launcher\n")] [use-librktdir? (if alt-exe - (let ([m (assq 'exe-is-gracket aux)]) - (and m (cdr m))) + alt-exe-is-gracket? (eq? kind 'mred))] + [addon? (let ([im (assoc 'install-mode aux)]) + (and im (eq? (cdr im) 'addon-tethered)))] + [config? (let ([im (assoc 'install-mode aux)]) + (and im (eq? (cdr im) 'config-tethered)))] [dir-finder (let ([bindir (if alt-exe (let ([m (assq 'exe-is-gracket aux)]) @@ -399,8 +406,16 @@ (find-lib-dir) (let ([p (path-only dest)]) (if (eq? 'macosx (cross-system-type)) - (let* ([cdir (find-console-bin-dir)] - [gdir (find-gui-bin-dir)] + (let* ([cdir (or (and addon? + (find-addon-tethered-console-bin-dir)) + (and config? + (find-config-tethered-console-bin-dir)) + (find-console-bin-dir))] + [gdir (or (and addon? + (find-addon-tethered-gui-bin-dir)) + (and config? + (find-config-tethered-gui-bin-dir)) + (find-gui-bin-dir))] [rel (find-relative-path cdir gdir)]) (cond [(relative-path? rel) @@ -729,15 +744,30 @@ [(macos) make-macos-launcher] [(macosx) make-macosx-launcher])) -(define (make-gracket-launcher flags dest [aux null]) - ((get-maker) 'mred (current-launcher-variant) flags dest aux)) -(define (make-mred-launcher flags dest [aux null]) - ((get-maker) 'mred (current-launcher-variant) (list* "-I" "scheme/gui/init" flags) dest aux)) +(define (make-gracket-launcher flags dest [aux null] #:tether-mode [tether-mode 'addon]) + ((get-maker) 'mred (current-launcher-variant) (add-tether tether-mode flags) dest aux)) +(define (make-mred-launcher flags dest [aux null] #:tether-mode [tether-mode 'addon]) + (let ([flags (list* "-I" "scheme/gui/init" (add-tether tether-mode flags))]) + ((get-maker) 'mred (current-launcher-variant) flags dest aux))) -(define (make-racket-launcher flags dest [aux null]) - ((get-maker) 'mzscheme (current-launcher-variant) flags dest aux)) -(define (make-mzscheme-launcher flags dest [aux null]) - ((get-maker) 'mzscheme (current-launcher-variant) (list* "-I" "scheme/init" flags) dest aux)) +(define (make-racket-launcher flags dest [aux null] #:tether-mode [tether-mode 'addon]) + ((get-maker) 'mzscheme (current-launcher-variant) (add-tether tether-mode flags) dest aux)) +(define (make-mzscheme-launcher flags dest [aux null] #:tether-mode [tether-mode 'addon]) + (let ([flags (list* "-I" "scheme/init" (add-tether tether-mode flags))]) + ((get-maker) 'mzscheme (current-launcher-variant) flags dest aux))) + +(define (add-tether tether-mode flags) + (cond + [(not tether-mode) flags] + [(and (not (eq? tether-mode 'config)) + (find-addon-tethered-console-bin-dir)) + (list* "-G" (path->string (find-config-dir)) + "-A" (path->string (find-system-path 'addon-dir)) + flags)] + [(find-config-tethered-console-bin-dir) + (list* "-G" (path->string (find-config-dir)) + flags)] + [else flags])) (define (strip-suffix s) (path-replace-suffix s #"")) @@ -894,7 +924,7 @@ (string-append (if mred? file (unix-sfx file mred?)) ".exe")] [else file])) -(define (program-launcher-path name mred? user?) +(define (program-launcher-path name mred? user? tethered?) (let* ([variant (current-launcher-variant)] [mac-script? (and (eq? (cross-system-type) 'macosx) (script-variant? variant))]) @@ -902,11 +932,19 @@ (build-path (if (or mac-script? (not mred?)) (if user? - (find-user-console-bin-dir) - (find-console-bin-dir)) + (or (and tethered? + (find-addon-tethered-console-bin-dir)) + (find-user-console-bin-dir)) + (or (and tethered? + (find-config-tethered-console-bin-dir)) + (find-console-bin-dir))) (if user? - (find-user-gui-bin-dir) - (find-gui-bin-dir))) + (or (and tethered? + (find-addon-tethered-gui-bin-dir)) + (find-user-gui-bin-dir)) + (or (and tethered? + (find-config-tethered-gui-bin-dir)) + (find-gui-bin-dir)))) ((if mac-script? unix-sfx sfx) name mred?)) variant mred?)]) @@ -915,23 +953,27 @@ (path-replace-suffix p #".app") p)))) -(define (gracket-program-launcher-path name #:user? [user? #f]) - (program-launcher-path name #t user?)) -(define (mred-program-launcher-path name #:user? [user? #f]) - (gracket-program-launcher-path name #:user? user?)) +(define (gracket-program-launcher-path name #:user? [user? #f] #:tethered? [tethered? #f]) + (program-launcher-path name #t user? tethered?)) +(define (mred-program-launcher-path name #:user? [user? #f] #:tethered? [tethered? #f]) + (gracket-program-launcher-path name #:user? user? #:tethered? tethered?)) -(define (racket-program-launcher-path name #:user? [user? #f]) +(define (racket-program-launcher-path name #:user? [user? #f] #:tethered? [tethered? #f]) (case (cross-system-type) [(macosx) (add-file-suffix (build-path (if user? - (find-user-console-bin-dir) - (find-console-bin-dir)) + (or (and tethered? + (find-addon-tethered-console-bin-dir)) + (find-user-console-bin-dir)) + (or (and tethered? + (find-config-tethered-console-bin-dir)) + (find-console-bin-dir))) (unix-sfx name #f)) (current-launcher-variant) #f)] - [else (program-launcher-path name #f user?)])) -(define (mzscheme-program-launcher-path name #:user? [user? #f]) - (racket-program-launcher-path name #:user? user?)) + [else (program-launcher-path name #f user? tethered?)])) +(define (mzscheme-program-launcher-path name #:user? [user? #f] #:tethered? [tethered? #f]) + (racket-program-launcher-path name #:user? user? #:tethered? tethered?)) (define (gracket-launcher-is-directory?) #f) diff --git a/racket/collects/racket/info.rkt b/racket/collects/racket/info.rkt index c13257f41f..9c27bb7cb7 100644 --- a/racket/collects/racket/info.rkt +++ b/racket/collects/racket/info.rkt @@ -8,3 +8,5 @@ ("Porting from v1xxx to v2xxx" "MzScheme_200.txt"))))) (define copy-man-pages '("racket.1")) + +(define install-collection "private/tethered-installer.rkt") diff --git a/racket/collects/racket/private/tethered-installer.rkt b/racket/collects/racket/private/tethered-installer.rkt new file mode 100644 index 0000000000..f033e946a3 --- /dev/null +++ b/racket/collects/racket/private/tethered-installer.rkt @@ -0,0 +1,30 @@ +#lang racket/base +(require setup/dirs + racket/file + compiler/embed + launcher) + +(provide installer) + +(define (installer path coll user? no-main?) + (unless (or user? no-main?) + (do-installer #f (find-config-tethered-console-bin-dir))) + (do-installer #t (find-addon-tethered-console-bin-dir))) + +(define (do-installer user? dir) + (when dir + (make-directory* dir) + (define variants (available-racket-variants)) + (for ([v (in-list variants)]) + (parameterize ([current-launcher-variant v]) + (create-embedding-executable + (racket-program-launcher-path "Racket" #:user? user? #:tethered? #t) + #:variant v + #:cmdline (append + (list "-X" (path->string (find-collects-dir)) + "-G" (path->string (find-config-dir))) + (if user? + (list "-A" (path->string (find-system-path 'addon-dir))) + null)) + #:launcher? #t + #:aux `((relative? . #f))))))) diff --git a/racket/collects/setup/dirs.rkt b/racket/collects/setup/dirs.rkt index f85c1bc45e..b60419199c 100644 --- a/racket/collects/setup/dirs.rkt +++ b/racket/collects/setup/dirs.rkt @@ -8,6 +8,8 @@ (provide (except-out (all-from-out "private/dirs.rkt") config:dll-dir config:bin-dir + config:config-tethered-console-bin-dir + config:config-tethered-gui-bin-dir define-finder) find-dll-dir) @@ -30,6 +32,49 @@ [(windows macosx) 'same] [(unix) "bin"])) +(provide find-config-tethered-console-bin-dir + find-config-tethered-gui-bin-dir) + +(define (find-config-tethered-console-bin-dir) + (force config:config-tethered-console-bin-dir)) + +(define (find-config-tethered-gui-bin-dir) + (force config:config-tethered-gui-bin-dir)) + +(provide find-addon-tethered-console-bin-dir + find-addon-tethered-gui-bin-dir) + +(define addon-bin-table + (delay/sync + (let () + (define f (build-path (find-system-path 'addon-dir) + "etc" + "config.rktd")) + (and (file-exists? f) + (call-with-input-file* + f + (lambda (in) + (call-with-default-reading-parameterization + (lambda () + (read in))))))))) + +(define (find-addon-bin-dir key) + (define t (force addon-bin-table)) + (and (hash? t) + (let ([v (hash-ref t key #f)]) + (and (path-string? v) + (simplify-path + (path->complete-path + v + (build-path (find-system-path 'addon-dir) + "etc"))))))) + +(define (find-addon-tethered-console-bin-dir) + (find-addon-bin-dir 'addon-tethered-console-bin-dir)) + +(define (find-addon-tethered-gui-bin-dir) + (find-addon-bin-dir 'addon-tethered-gui-bin-dir)) + ;; ---------------------------------------- ;; DLLs diff --git a/racket/collects/setup/private/dirs.rkt b/racket/collects/setup/private/dirs.rkt index 4ad0e241bd..982c67c949 100644 --- a/racket/collects/setup/private/dirs.rkt +++ b/racket/collects/setup/private/dirs.rkt @@ -58,6 +58,8 @@ (define-config config:include-dir 'include-dir to-path) (define-config config:include-search-dirs 'include-search-dirs to-path) (define-config config:bin-dir 'bin-dir to-path) +(define-config config:config-tethered-console-bin-dir 'config-tethered-console-bin-dir to-path) +(define-config config:config-tethered-gui-bin-dir 'config-tethered-gui-bin-dir to-path) (define-config config:man-dir 'man-dir to-path) (define-config config:links-file 'links-file to-path) (define-config config:links-search-files 'links-search-files to-path) @@ -268,7 +270,9 @@ ;; `setup/dirs` -(provide config:bin-dir) +(provide config:bin-dir + config:config-tethered-console-bin-dir + config:config-tethered-gui-bin-dir) ;; ---------------------------------------- ;; DLLs diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index 3b3f4d3ce5..5559704d02 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -319,7 +319,7 @@ (setup-printf "WARNING" "~a" (exn->string exn)) v) - ;; Maps a colletion name to a list of `cc's: + ;; Maps a collection name to a list of `cc's: (define collection-ccs-table (make-hash)) ;; collection-cc! : listof-path .... -> cc @@ -664,10 +664,7 @@ x-specific-planet-dirs))) null)) - (define top-level-plt-collects - ((if (avoid-main-installation) - (lambda (l) (filter (lambda (cc) (not (cc-main? cc))) l)) - values) + (define all-top-level-plt-collects (if no-specific-collections? all-collections (check-against-all @@ -690,7 +687,13 @@ (string-join sc "/"))) ccs) x-specific-collections) - (null? planet-collects))))) + (null? planet-collects)))) + + (define top-level-plt-collects + (if (avoid-main-installation) + (filter (lambda (cc) (not (cc-main? cc))) + all-top-level-plt-collects) + all-top-level-plt-collects)) (define planet-dirs-to-compile (sort-collections @@ -699,12 +702,29 @@ (lambda (cc subs) (map (lambda (p) (planet-cc->sub-cc cc (list (path->bytes p)))) subs))))) - - (define ccs-to-compile + + (define (combine-collections top-level-plt-collects) (append (sort-collections (lookup-collection-closure top-level-plt-collects)) planet-dirs-to-compile)) + + (define ccs-to-compile + (combine-collections top-level-plt-collects)) + (define ccs-to-call-installers + (if (avoid-main-installation) + ;; Although we mostly avoid the main installation, we'll + ;; need to call main-installaiton launchers in case they + ;; support being called to perform only user-specific + ;; actions. + (combine-collections all-top-level-plt-collects) + ccs-to-compile)) + + (define ccs-to-make-launchers + (if (or (find-addon-tethered-console-bin-dir) + (find-addon-tethered-gui-bin-dir)) + ccs-to-call-installers + ccs-to-compile)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Clean ;; @@ -839,7 +859,7 @@ [(pre) "pre-"] [(general) ""] [(post) "post-"]))) - (for ([cc ccs-to-compile]) + (for ([cc ccs-to-call-installers]) (let/ec k (begin-record-error cc (case part [(pre) "early install"] @@ -865,26 +885,36 @@ (error name-sym "error loading installer: ~a" (exn->string exn)))]) - (dynamic-require (build-path (cc-path cc) fn) - (case part - [(pre) 'pre-installer] - [(general) 'installer] - [(post) 'post-installer])))) - (setup-printf (format "~ainstalling" - (case part - [(pre) "pre-"] - [(post) "post-"] - [else ""])) - "~a" - (cc-name cc)) - (define dir (build-path main-collects-dir 'up)) - (cond - [(procedure-arity-includes? installer 3) - (installer dir (cc-path cc) (not (cc-main? cc)))] - [(procedure-arity-includes? installer 2) - (installer dir (cc-path cc))] - [else - (installer dir)])))))) + (define base-installer + (dynamic-require (build-path (cc-path cc) fn) + (case part + [(pre) 'pre-installer] + [(general) 'installer] + [(post) 'post-installer]))) + (if (and (cc-main? cc) + (avoid-main-installation) + (not (procedure-arity-includes? base-installer 4))) + #f + base-installer))) + (when installer + (setup-printf (format "~ainstalling" + (case part + [(pre) "pre-"] + [(post) "post-"] + [else ""])) + "~a" + (cc-name cc)) + (define dir (build-path main-collects-dir 'up)) + (cond + [(procedure-arity-includes? installer 4) + (installer dir (cc-path cc) (not (cc-main? cc)) (and (cc-main? cc) + (avoid-main-installation)))] + [(procedure-arity-includes? installer 3) + (installer dir (cc-path cc) (not (cc-main? cc)))] + [(procedure-arity-includes? installer 2) + (installer dir (cc-path cc))] + [else + (installer dir)]))))))) (define (bytecode-file-exists? p) (parameterize ([use-compiled-file-paths (list mode-dir)]) @@ -1366,7 +1396,7 @@ (error "result is not a list of strings:" l))) (define ((or-f f) x) (when x (f x))) (define created-launchers (make-hash)) - (for ([cc ccs-to-compile]) + (for ([cc ccs-to-make-launchers]) (begin-record-error cc "launcher setup" (define info (cc-info cc)) (define (make-launcher kind @@ -1396,6 +1426,15 @@ [mzll (in-list (or mzlls (map (lambda (_) #f) mzlns)))] [mzlf (in-list (or mzlfs (map (lambda (_) #f) mzlns)))]) (define p (program-launcher-path mzln #:user? (not (cc-main? cc)))) + (define addon-p (and (if (eq? kind 'gui) + (find-addon-tethered-gui-bin-dir) + (find-addon-tethered-console-bin-dir)) + (program-launcher-path mzln #:user? #t #:tethered? #t))) + (define config-p (and (cc-main? cc) + (if (eq? kind 'gui) + (find-config-tethered-gui-bin-dir) + (find-config-tethered-console-bin-dir)) + (program-launcher-path mzln #:user? #f #:tethered? #t))) (define receipt-path (build-path (if (cc-main? cc) (find-lib-dir) @@ -1404,42 +1443,65 @@ (define (prep-dir p) (define dir (path-only p)) (make-directory* dir)) - (prep-dir p) - (prep-dir receipt-path) + (define skip-non-addon? (and (cc-main? cc) + (avoid-main-installation))) + (unless skip-non-addon? + (prep-dir p) + (prep-dir receipt-path) + (when config-p + (prep-dir config-p))) + (when addon-p + (prep-dir addon-p)) (hash-set! created-launchers (record-launcher receipt-path mzln kind (current-launcher-variant) (cc-collection cc) (cc-path cc)) #t) - (define aux - (append - `((exe-name . ,mzln) - (relative? . ,(and (cc-main? cc) - (not (get-absolute-installation?)))) - (install-mode . ,(if (cc-main? cc) 'main 'user)) - ,@(build-aux-from-path - (build-path (cc-path cc) - (path-replace-suffix (or mzll mzln) #"")))))) - (unless (up-to-date? p aux) - (setup-printf - "launcher" - "~a~a" - (case kind - [(gui) (path->relative-string/gui-bin p)] - [(console) (path->relative-string/console-bin p)] - [else (error 'make-launcher "internal error (~s)" kind)]) - (let ([v (current-launcher-variant)]) - (if (eq? v (cross-system-type 'gc)) "" (format " [~a]" v)))) - (make-launcher - (or mzlf - (if (cc-collection cc) - (list "-l-" (string-append - (string-append* - (map (lambda (s) (format "~a/" s)) - (cc-collection cc))) - mzll)) - (list "-t-" (path->string (build-path (cc-path cc) mzll))))) - p - aux)))] + (define (create p user? tethered?) + (define aux + (append + `((exe-name . ,mzln) + (relative? . ,(and (cc-main? cc) + (not tethered?) + (not (get-absolute-installation?)))) + (install-mode . ,(if tethered? + (if user? 'addon-tethered 'config-tethered) + (if (cc-main? cc) 'main 'user))) + ,@(build-aux-from-path + (build-path (cc-path cc) + (path-replace-suffix (or mzll mzln) #"")))))) + (unless (up-to-date? p aux) + (setup-printf + "launcher" + "~a~a" + (case kind + [(gui) (path->relative-string/gui-bin p)] + [(console) (path->relative-string/console-bin p)] + [else (error 'make-launcher "internal error (~s)" kind)]) + (let ([v (current-launcher-variant)]) + (if (eq? v (cross-system-type 'gc)) "" (format " [~a]" v)))) + (make-launcher + #:tether-mode (if tethered? + (if user? + 'addon + 'config) + #f) + (append + (or mzlf + (if (cc-collection cc) + (list "-l-" (string-append + (string-append* + (map (lambda (s) (format "~a/" s)) + (cc-collection cc))) + mzll)) + (list "-t-" (path->string (build-path (cc-path cc) mzll)))))) + p + aux))) + (unless skip-non-addon? + (create p (not (cc-main? cc)) #f) + (when config-p + (create config-p #f #t))) + (when addon-p + (create addon-p #t #t)))] [else (define fault (if (or (not mzlls) (= (length mzlns) (length mzlls))) 'f 'l)) @@ -1485,15 +1547,11 @@ (make-tidy)) (unless (avoid-main-installation) (tidy-launchers #f - (find-console-bin-dir) - (find-gui-bin-dir) (find-lib-dir) created-launchers ccs-to-compile)) (when (make-user) (tidy-launchers #t - (find-user-console-bin-dir) - (find-user-gui-bin-dir) (find-user-lib-dir) created-launchers ccs-to-compile)))) @@ -1535,7 +1593,7 @@ (write-receipt-hash receipt-path ht))) exe-key)) - (define (tidy-launchers user? bin-dir gui-bin-dir lib-dir created ccs-to-compile) + (define (tidy-launchers user? lib-dir created ccs-to-compile) (define receipt-path (build-path lib-dir "launchers.rktd")) (define ht (read-receipt-hash receipt-path)) (define ht2 (for/fold ([ht (hash)]) ([(k v) (in-hash ht)]) @@ -1562,27 +1620,36 @@ (define variant (vector-ref k 1)) (define name (vector-ref k 2)) (parameterize ([current-launcher-variant variant]) - (define exe-path ((if (eq? kind 'gui) - gracket-program-launcher-path - racket-program-launcher-path) - name - #:user? user?)) + (define (get-path user? tethered?) + ((if (eq? kind 'gui) + gracket-program-launcher-path + racket-program-launcher-path) + name + #:user? user? + #:tethered? tethered?)) + (define exe-path (get-path user? #f)) + (define config-exe-path (and (not user?) (get-path #f #t))) + (define addon-exe-path (get-path #t #t)) (define is-dir? (if (eq? kind 'gui) (gracket-launcher-is-actually-directory?) (racket-launcher-is-actually-directory?))) - (define rel-exe-path - ((if (eq? kind 'gui) - path->relative-string/gui-bin - path->relative-string/console-bin) - exe-path)) - (cond - [(and (not is-dir?) (file-exists? exe-path)) - (setup-printf "deleting" "launcher ~a" rel-exe-path) - (delete-file exe-path)] - [(and is-dir? (directory-exists? exe-path)) - (setup-printf "deleting" "launcher ~a" rel-exe-path) - (delete-directory/files exe-path)]) + (define (delete exe-path) + (define rel-exe-path + ((if (eq? kind 'gui) + path->relative-string/gui-bin + path->relative-string/console-bin) + exe-path)) + (cond + [(and (not is-dir?) (file-exists? exe-path)) + (setup-printf "deleting" "launcher ~a" rel-exe-path) + (delete-file exe-path)] + [(and is-dir? (directory-exists? exe-path)) + (setup-printf "deleting" "launcher ~a" rel-exe-path) + (delete-directory/files exe-path)])) + (delete exe-path) + (when config-exe-path (delete config-exe-path)) + (when addon-exe-path (delete addon-exe-path)) ;; Clean up any associated .desktop file and icon file: (when (eq? 'unix (cross-system-type)) (let ([desktop (installed-executable-path->desktop-path diff --git a/racket/src/racket/src/schvers.h b/racket/src/racket/src/schvers.h index 7d7cc35ed6..94ecf921ed 100644 --- a/racket/src/racket/src/schvers.h +++ b/racket/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "6.5.0.1" +#define MZSCHEME_VERSION "6.5.0.2" #define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_Y 5 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 1 +#define MZSCHEME_VERSION_W 2 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)