From d0d391d76bfc6a6b747108e85c1d0fa0d43b05af Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 11 Mar 2019 17:37:35 -0600 Subject: [PATCH] raco setup: add `--recompile-only` The `--recompile-only` flag is intended to help dectect build problems, especially distribution builds where packages are supposed to be in built form. --- Makefile | 9 +++++--- pkgs/racket-doc/pkg/scribblings/pkg.scrbl | 21 +++++++++++++++---- pkgs/racket-doc/scribblings/raco/setup.scrbl | 19 ++++++++++++++--- .../collects/compiler/private/cm-minimal.rkt | 7 +++++++ racket/collects/pkg/main.rkt | 14 +++++++------ racket/collects/setup/main.rkt | 16 +++++++++----- racket/collects/setup/option.rkt | 1 + racket/collects/setup/parallel-build.rkt | 3 +++ racket/collects/setup/setup-cmdline.rkt | 2 ++ racket/collects/setup/setup-core.rkt | 10 ++++++--- racket/collects/setup/setup-go.rkt | 2 ++ racket/collects/setup/setup.rkt | 8 +++++-- 12 files changed, 86 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index dd9666e2bd..baa4472cd7 100644 --- a/Makefile +++ b/Makefile @@ -610,6 +610,9 @@ SVR_PRT = $(SERVER):$(SERVER_PORT) SVR_CAT = http://$(SVR_PRT)/$(SERVER_CATALOG_PATH) +# Catch problems due to malformed distribution-build packages +RECOMPILE_OPTIONS = --recompile-only + # Helper macros: USER_CONFIG = -G build/user/config -X racket/collects -A build/user $(SETUP_MACHINE_FLAGS) USER_RACKET = $(PLAIN_RACKET) $(USER_CONFIG) @@ -619,8 +622,8 @@ WIN32_RACO = $(WIN32_PLAIN_RACKET) $(USER_CONFIG) -N raco -l- raco X_AUTO_OPTIONS = --skip-installed --deps search-auto --pkgs $(JOB_OPTIONS) USER_AUTO_OPTIONS = --scope user $(X_AUTO_OPTIONS) SOURCE_USER_AUTO_q = --catalog build/catalog-copy $(USER_AUTO_OPTIONS) -REMOTE_USER_AUTO = --catalog $(SVR_CAT) $(USER_AUTO_OPTIONS) -REMOTE_INST_AUTO = --catalog $(SVR_CAT) --scope installation $(X_AUTO_OPTIONS) +REMOTE_USER_AUTO = --catalog $(SVR_CAT) $(USER_AUTO_OPTIONS) $(RECOMPILE_OPTIONS) +REMOTE_INST_AUTO = --catalog $(SVR_CAT) --scope installation $(X_AUTO_OPTIONS) $(RECOMPILE_OPTIONS) CONFIG_MODE_q = "$(CONFIG)" "$(CONFIG_MODE)" BUNDLE_CONFIG = bundle/racket/etc/config.rktd BUNDLE_RACO_FLAGS = -G bundle/racket/etc -X bundle/racket/collects -C -A bundle/user -l raco @@ -825,7 +828,7 @@ bundle-from-server: $(USER_RACKET) -l setup/winstrip bundle/racket $(USER_RACKET) -l setup/winvers-change bundle/racket $(USER_RACKET) -l- distro-build/unpack-collects $(UNPACK_COLLECTS_FLAGS) http://$(SVR_PRT)/$(SERVER_COLLECTS_PATH) - $(IN_BUNDLE_RACO) setup $(JOB_OPTIONS) + $(IN_BUNDLE_RACO) setup $(JOB_OPTIONS) $(RECOMPILE_OPTIONS) $(IN_BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(REQUIRED_PKGS) $(IN_BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(PKGS) $(USER_RACKET) -l setup/unixstyle-install post-adjust "$(SOURCE_MODE)" "$(PKG_SOURCE_MODE)" racket bundle/racket diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index 01b85affd7..7346fd4780 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -616,6 +616,12 @@ sub-commands. @item{@DFlag{no-setup} --- Does not run @exec{raco setup} after installation. This behavior is also the case if the environment variable @envvar{PLT_PKG_NOSETUP} is set to any non-empty value.} + @item{@DFlag{recompile-only} ---Constrains @exec{raco setup} to at most recompile a module from + machine-independent form, reporting an error if compilation from source is needed. This + behavior is useful as a sanity check when installing built packages (to ensure that they + are properly built), but if a compilation error is reported, it will be after the package + is installed.} + @item{@DFlag{jobs} @nonterm{n} or @Flag{j} @nonterm{n} --- Installs and runs @exec{raco setup} with @nonterm{n} parallel jobs.} @item{@DFlag{batch} --- Disables @deftech{interactive mode}, suppressing potential prompts for a user @@ -631,7 +637,8 @@ sub-commands. #:changed "6.1.1.6" @elem{Added the @DFlag{no-trash} flag, and changed the @DFlag{deps} default to depend only on interactive mode.} #:changed "6.1.1.8" @elem{Added the @DFlag{pull} flag.} - #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.}]} + #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} + #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.}]} @subcommand{@command/toc{update} @nonterm{option} ... @nonterm{pkg-source} ... @@ -746,6 +753,7 @@ the given @nonterm{pkg-source}s. @item{@DFlag{dry-run} --- Same as for @command-ref{install}.} @item{@DFlag{no-setup} --- Same as for @command-ref{install}.} + @item{@DFlag{recompile-only} --- Same as for @command-ref{install}.} @item{@DFlag{jobs} @nonterm{n} or @Flag{j} @nonterm{n} --- Same as for @command-ref{install}.} @item{@DFlag{batch} --- Same as for @command-ref{install}.} @item{@DFlag{no-trash} --- Same as for @command-ref{install}.} @@ -759,7 +767,8 @@ the given @nonterm{pkg-source}s. the @DFlag{deps} default to depend only on interactive mode.} #:changed "6.1.1.8" @elem{Added the @DFlag{skip-uninstalled} and @DFlag{pull} flags.} #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} - #:changed "6.90.0.27" @elem{Added the @DFlag{unclone} flag.}]} + #:changed "6.90.0.27" @elem{Added the @DFlag{unclone} flag.} + #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.}]} @subcommand{@command/toc{remove} @nonterm{option} ... @nonterm{pkg} ... --- Attempts to remove the given packages. By default, if a package is the dependency @@ -787,6 +796,7 @@ the given @nonterm{pkg}s. @item{@DFlag{scope-dir} @nonterm{dir} --- Selects @nonterm{dir} as the @tech{package scope}, the same as for @command-ref{install}.} @item{@DFlag{dry-run} --- Same as for @command-ref{install}.} @item{@DFlag{no-setup} --- Same as for @command-ref{install}.} + @item{@DFlag{recompile-only} --- Same as for @command-ref{install}.} @item{@DFlag{jobs} @nonterm{n} or @Flag{j} @nonterm{n} --- Same as for @command-ref{install}.} @item{@DFlag{batch} --- Same as for @command-ref{install}.} @item{@DFlag{no-trash} --- Same as for @command-ref{install}.} @@ -794,7 +804,8 @@ the given @nonterm{pkg}s. @history[#:changed "6.1.1.5" @elem{Added the @DFlag{batch} flag.} #:changed "6.1.1.6" @elem{Added the @DFlag{no-trash} flag.} - #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.}]} + #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} + #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.}]} @subcommand{@command/toc{new} @nonterm{pkg} --- @@ -878,10 +889,12 @@ package is created. @item{@DFlag{no-cache} --- Same as for @command-ref{install}.} @item{@DFlag{dry-run} --- Same as for @command-ref{install}.} @item{@DFlag{no-setup} --- Same as for @command-ref{install}.} + @item{@DFlag{recompile-only} --- Same as for @command-ref{install}.} @item{@DFlag{jobs} @nonterm{n} or @Flag{j} @nonterm{n} --- Same as for @command-ref{install}.} ] -@history[#:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.}]} +@history[#:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} + #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.}]} @subcommand{@command/toc{create} @nonterm{option} ... @nonterm{directory-or-package} --- Bundles a package into an archive. Bundling diff --git a/pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-doc/scribblings/raco/setup.scrbl index e5e15de953..f61b7c035a 100644 --- a/pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -161,6 +161,12 @@ flags: @envvar{PLT_COMPILED_FILE_CHECK} environment variable is set to @litchar{exists}, in which case timestamps are ignored).} + @item{@DFlag{recompile-only} --- disallow recompilation of modules + from source, imposing the constraint that each @filepath{.zo} file + is up-to-date, needs only a timestamp adjustment, or can be + recompiled from an existing @filepath{.zo} in machine-independent + format (when compiling to a machine-dependent format).} + @item{@DFlag{no-launcher} or @Flag{x} --- refrain from creating executables or installing @tt{man} pages (as specified in @filepath{info.rkt}; see @secref["setup-info"]).} @@ -351,7 +357,8 @@ update a compiled file's timestamp if the file is not recompiled. #:changed "6.1.1.6" @elem{Added the @DFlag{only-foreign-libs} flag.} #:changed "6.6.0.3" @elem{Added support for @envvar{PLT_COMPILED_FILE_CHECK}.} #:changed "7.0.0.19" @elem{Added @DFlag{places} and @DFlag{processes}.} - #:changed "7.2.0.7" @elem{Added @DFlag{error-in} and @DFlag{error-out}.}] + #:changed "7.2.0.7" @elem{Added @DFlag{error-in} and @DFlag{error-out}.} + #:changed "7.2.0.8" @elem{Added @DFlag{recompile-only}.}] @; ------------------------------------------------------------------------ @@ -952,6 +959,7 @@ normal dependency counts as a build-time dependency, too). [#:unused-pkg-deps? unused-pkg-deps? any/c #f] [#:clean? clean? any/c #f] [#:tidy? tidy? any/c #f] + [#:recompile-only? recompile-only? any/c #f] [#:jobs jobs exact-nonnegative-integer? #f] [#:fail-fast? fail-fast? any/c #f] [#:get-target-dir get-target-dir (or/c #f (-> path-string?)) #f]) @@ -1010,6 +1018,10 @@ Runs @exec{raco setup} with various options: documentation and metadata indexes even when @racket[collections] or @racket[planet-specs] is non-@racket[#f]} + @item{@racket[recompile-only?] --- if true, disallows compilation + from source, allowing only timestamp adjustments and recompilation + from machine-independent form} + @item{@racket[jobs] --- if not @racket[#f], determines the maximum number of parallel tasks used for setup} @@ -1030,8 +1042,9 @@ sensitive to the @racket[use-compiled-file-check] parameter. @history[#:changed "6.1" @elem{Added the @racket[fail-fast?] argument.} #:changed "6.1.1" @elem{Added the @racket[force-user-docs?] argument.} #:changed "7.2.0.7" @elem{Added the @racket[check-pkg-deps?], - @racket[fix-pkg-deps?], and @racket[unused-pkg-deps?] - arguments.}]} + @racket[fix-pkg-deps?] , and @racket[unused-pkg-deps?] + arguments.} + #:changed "7.2.0.8" @elem{Added the @racket[recompile-only?] argument.}]} diff --git a/racket/collects/compiler/private/cm-minimal.rkt b/racket/collects/compiler/private/cm-minimal.rkt index 3e1dbb02fd..9061b426f5 100644 --- a/racket/collects/compiler/private/cm-minimal.rkt +++ b/racket/collects/compiler/private/cm-minimal.rkt @@ -17,6 +17,7 @@ managed-compile-zo make-caching-managed-compile-zo trust-existing-zos + managed-recompile-only manager-compile-notify-handler manager-skip-file-handler manager-trace-handler @@ -55,6 +56,7 @@ (define manager-trace-handler (make-parameter default-manager-trace-handler)) (define indent (make-parameter 0)) (define trust-existing-zos (make-parameter #f)) +(define managed-recompile-only (make-parameter #f)) (define manager-skip-file-handler (make-parameter (λ (x) #f))) (define depth (make-parameter 0)) (define parallel-lock-client (make-parameter #f)) @@ -370,6 +372,11 @@ #:recompile-from recompile-from #:assume-compiled-sha1 assume-compiled-sha1 #:use-existing-deps use-existing-deps) + (when (and (not recompile-from) + (managed-recompile-only)) + (error 'compile-zo + "compile from source disallowed\n module: ~a" + path)) (cond [(cross-multi-compile? roots) (define running-root (car roots)) diff --git a/racket/collects/pkg/main.rkt b/racket/collects/pkg/main.rkt index 965f9a46d8..79b9b17671 100644 --- a/racket/collects/pkg/main.rkt +++ b/racket/collects/pkg/main.rkt @@ -14,7 +14,7 @@ (for-syntax racket/base syntax/strip-context)) -(define (setup what no-setup? fail-fast? setup-collects jobs) +(define (setup what no-setup? recompile-only? fail-fast? setup-collects jobs) (unless (or (eq? setup-collects 'skip) no-setup? (not (member (getenv "PLT_PKG_NOSETUP") '(#f "")))) @@ -29,6 +29,7 @@ #:tidy? #t #:make-doc-index? #t #:jobs jobs + #:recompile-only? recompile-only? #:fail-fast? fail-fast?) ((current-pkg-error) "packages ~a, although setup reported errors" @@ -253,7 +254,7 @@ (pkg-desc p a-type* name checksum #f #:path (and (eq? a-type* 'clone) (path->complete-path clone)))))))) - (setup "installed" no-setup fail-fast setup-collects jobs))))] + (setup "installed" no-setup recompile-only fail-fast setup-collects jobs))))] ;; ---------------------------------------- [update "Update packages" @@ -357,7 +358,7 @@ #:infer-clone-from-dir? (not (or link static-link copy)) #:dry-run? dry-run #:use-trash? (not no-trash))))) - (setup "updated" no-setup #f setup-collects jobs))))] + (setup "updated" no-setup recompile-only #f setup-collects jobs))))] ;; ---------------------------------------- [remove "Remove packages" @@ -385,7 +386,7 @@ #:force? force #:dry-run? dry-run #:use-trash? (not no-trash)))) - (setup "removed" no-setup #f setup-collects jobs)))] + (setup "removed" no-setup recompile-only #f setup-collects jobs)))] ;; ---------------------------------------- [new "Populate a new directory with the stubs of a package" @@ -484,7 +485,7 @@ (and binary-lib 'binary-lib)) #:force-strip? force #:dry-run? dry-run)))) - (setup "migrated" no-setup #f setup-collects jobs)))] + (setup "migrated" no-setup recompile-only #f setup-collects jobs)))] ;; ---------------------------------------- [create "Bundle package from a directory or installed package" @@ -674,7 +675,8 @@ #:dry-run-flags ([#:bool dry-run () ("Don't actually change package installation")]) #:job-flags - ([#:bool no-setup () ("Don't `raco setup' after changing packages (usually a bad idea)")] + ([#:bool no-setup () ("Don't `raco setup` after changing packages (usually a bad idea)")] + [#:bool recompile-only () ("Expect built packages, possibly machine-independent")] [(#:num n #f) jobs ("-j") "Setup with parallel jobs"] [#:bool batch () ("Disable interactive mode and all prompts")]) #:trash-flags diff --git a/racket/collects/setup/main.rkt b/racket/collects/setup/main.rkt index 45bd98e031..a6beac8da4 100644 --- a/racket/collects/setup/main.rkt +++ b/racket/collects/setup/main.rkt @@ -139,7 +139,8 @@ (if (member (car flags) ;; Flags that take 1 argument: '("--mode" "--doc-pdf" - "-j" "--jobs" "--workers")) + "-j" "--jobs" "--workers" + "--error-in" "--error-out")) (if (pair? (cdr flags)) (filter-flags queued-flags (cddr flags)) queued-flags) @@ -215,7 +216,7 @@ ;; Load the cm instance to be installed while loading Setup PLT. ;; This has to be dynamic, so we get a chance to turn off compiled ;; file loading, and so it can be in a separate namespace. - (let-values ([(mk trust-zos) + (let-values ([(mk trust-zos managed-recompile-only) ;; Load cm.rkt into its own namespace, so that cm compiles ;; itself and its required modules in the right order ;; (i.e., when some module requires cm or one of its @@ -304,12 +305,17 @@ (dynamic-require 'compiler/private/cm-minimal 'make-compilation-manager-load/use-compiled-handler)] [trust-zos - (dynamic-require 'compiler/private/cm-minimal 'trust-existing-zos)]) - ;; Return the two extracted functions: - (lambda () (values mk trust-zos)))))))))]) + (dynamic-require 'compiler/private/cm-minimal 'trust-existing-zos)] + [managed-recompile-only + (dynamic-require 'compiler/private/cm-minimal 'managed-recompile-only)]) + ;; Return the extracted functions: + (lambda () (values mk trust-zos managed-recompile-only)))))))))]) (if (on? "--trust-zos") (trust-zos #t) (void)) + (if (on? "--recompile-only") + (managed-recompile-only #t) + (void)) (current-load/use-compiled (mk)))) ;; This has to be dynamic, so we get a chance to turn off diff --git a/racket/collects/setup/option.rkt b/racket/collects/setup/option.rkt index f329f9e2de..815c2f6967 100644 --- a/racket/collects/setup/option.rkt +++ b/racket/collects/setup/option.rkt @@ -82,6 +82,7 @@ (define-flag-param always-check-dependencies #f) (define-flag-param fix-dependencies #f) (define-flag-param check-unused-dependencies #f) +(define-flag-param recompile-only #f) (define-flag-param call-install #t) (define-flag-param call-post-install #t) (define-flag-param pause-on-errors #f) diff --git a/racket/collects/setup/parallel-build.rkt b/racket/collects/setup/parallel-build.rkt index 6be3f5a0d8..a1f4d75638 100644 --- a/racket/collects/setup/parallel-build.rkt +++ b/racket/collects/setup/parallel-build.rkt @@ -329,6 +329,9 @@ [current-compile-target-machine (if (memq 'compile-any options) #f (current-compile-target-machine))] + [managed-recompile-only (if (memq 'recompile-only options) + #t + (managed-recompile-only))] [current-load-relative-directory dir] [current-input-port (open-input-string "")] [current-output-port out-str-port] diff --git a/racket/collects/setup/setup-cmdline.rkt b/racket/collects/setup/setup-cmdline.rkt index de149b6f42..7753587eba 100644 --- a/racket/collects/setup/setup-cmdline.rkt +++ b/racket/collects/setup/setup-cmdline.rkt @@ -80,6 +80,8 @@ (add-flags '((make-zo #f)))] [("--trust-zos") "Trust existing \".zo\"s (use only with prepackaged \".zo\"s)" (add-flags '((trust-existing-zos #t)))] + [("--recompile-only") "Fail if compilation must start from source" + (add-flags '((recompile-only #t)))] [("-x" "--no-launcher") "Do not produce launcher programs" (add-flags '((make-launchers #f)))] [("-F" "--no-foreign-libs") "Do not install foreign libraries" diff --git a/racket/collects/setup/setup-core.rkt b/racket/collects/setup/setup-core.rkt index 116c9f3125..2c7684672c 100644 --- a/racket/collects/setup/setup-core.rkt +++ b/racket/collects/setup/setup-core.rkt @@ -1138,9 +1138,13 @@ (iterate-cct clean-cc cct) (parallel-compile (parallel-workers) setup-fprintf handle-error cct #:use-places? (parallel-use-places) - #:options (if (not (current-compile-target-machine)) - '(compile-any) - '())) + #:options (append + (if (not (current-compile-target-machine)) + '(compile-any) + '()) + (if (managed-recompile-only) + '(recompile-only) + '()))) (for/fold ([gcs 0]) ([cc planet-dirs-to-compile]) (compile-cc cc gcs has-module-suffix?))))) (with-specified-mode diff --git a/racket/collects/setup/setup-go.rkt b/racket/collects/setup/setup-go.rkt index 580057dfa6..8fa13d7ca5 100644 --- a/racket/collects/setup/setup-go.rkt +++ b/racket/collects/setup/setup-go.rkt @@ -31,6 +31,8 @@ (current-target-plt-directory-getter))] [trust-existing-zos (or (has-x-flag? 'trust-existing-zos) (trust-existing-zos))] + [managed-recompile-only (or (has-x-flag? 'recompile-only) + (managed-recompile-only))] [specific-collections x-specific-collections] [specific-packages x-specific-packages] [archives x-archives] diff --git a/racket/collects/setup/setup.rkt b/racket/collects/setup/setup.rkt index 75c1363693..872eb6271e 100644 --- a/racket/collects/setup/setup.rkt +++ b/racket/collects/setup/setup.rkt @@ -2,7 +2,8 @@ (require "option.rkt" "setup-core.rkt" launcher/launcher - compiler/compiler) + compiler/compiler + compiler/cm) (provide setup) @@ -19,6 +20,7 @@ #:avoid-main? [avoid-main? #f] #:force-user-docs? [force-user-docs? #f] #:jobs [parallel #f] + #:recompile-only? [recompile-only? #f] #:fail-fast? [fail-fast? #f] #:check-pkg-deps? [always-check-dependencies? #f] #:fix-pkg-deps? [fix-dependencies? #f] @@ -68,7 +70,9 @@ always-check-dependencies?)] [setup-program-name "raco setup"] - + + [recompile-only recompile-only?] + [managed-recompile-only recompile-only?] [parallel-workers (if parallel parallel (parallel-workers))]) (let/ec esc