<div dir="ltr">This change seemed to change the format of .dep files, likely as intended to add the indirect dependencies. Is there any documentation of what the format is supposed to be? Currently I've just been trying to read cm.rkt and understand how it treats them.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 8, 2015 at 9:31 AM,  <span dir="ltr"><<a href="mailto:mflatt@racket-lang.org" target="_blank">mflatt@racket-lang.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">mflatt has updated `master' from c56c9250f1 to 95e85ec5bd.<br>
  <a href="http://git.racket-lang.org/plt/c56c9250f1..95e85ec5bd" target="_blank">http://git.racket-lang.org/plt/c56c9250f1..95e85ec5bd</a><br>
<br>
=====[ 2 Commits ]======================================================<br>
Directory summary:<br>
  45.1% pkgs/racket-doc/scribblings/raco/<br>
   4.7% pkgs/racket-doc/scribblings/reference/<br>
  47.5% racket/collects/compiler/<br>
<br>
~~~~~~~~~~<br>
<br>
fe9a04d Matthew Flatt <<a href="mailto:mflatt@racket-lang.org">mflatt@racket-lang.org</a>> 2015-01-08 09:11<br>
:<br>
| doc tweaks for `raco {setup,make}`<br>
:<br>
  M pkgs/racket-doc/scribblings/raco/make.scrbl  |  4 ++--<br>
  M pkgs/racket-doc/scribblings/raco/setup.scrbl | 22 ++++++++++++----------<br>
<br>
~~~~~~~~~~<br>
<br>
95e85ec Matthew Flatt <<a href="mailto:mflatt@racket-lang.org">mflatt@racket-lang.org</a>> 2015-01-08 09:57<br>
:<br>
| add support for indirect CM dependencies; use in `lazy-require`<br>
|<br>
| If module M in package P imports module N from package Q,<br>
| and if N has a `lazy-require` for a module in R that is<br>
| triggered during the compilation of M, then P doesn't really<br>
| depend on R; P depends on Q, and Q depends on R, and P<br>
| shoudn't necessarily know anything about Q. At the same time,<br>
| a change to the file in R means that M must be recompiled.<br>
| So, continue to track the compilation dependency, but mark<br>
| it as "indirect" so that the package-dependency checker can<br>
| ignore the dependency.<br>
:<br>
  M pkgs/racket-doc/scribblings/raco/make.scrbl       | 33 ++++++++-----<br>
  M racket/collects/compiler/cm-accomplice.rkt        | 14 +++---<br>
  M racket/collects/compiler/cm.rkt                   | 49 ++++++++++++++------<br>
  M racket/collects/racket/lazy-require.rkt           |  2 +-<br>
  M racket/collects/setup/private/pkg-deps.rkt        |  1 +<br>
  M .../racket-doc/scribblings/reference/syntax.scrbl |  8 ++--<br>
<br>
=====[ Overall Diff ]===================================================<br>
<br>
pkgs/racket-doc/scribblings/raco/make.scrbl<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/pkgs/racket-doc/scribblings/raco/make.scrbl<br>
+++ NEW/pkgs/racket-doc/scribblings/raco/make.scrbl<br>
@@ -123,7 +123,7 @@ would create only @filepath{compiled/b_rkt.zo} and<br>
<br>
 @; ----------------------------------------------------------------------<br>
<br>
-@section{Dependency Files}<br>
+@section[#:tag "Dependency Files"]{Dependency Files}<br>
<br>
 In addition to a bytecode file, @exec{raco make} creates a file<br>
 @filepath{compiled/@nonterm{name}_@nonterm{ext}.dep} that records<br>
@@ -538,7 +538,7 @@ messages are instances of a @racket[parallel-compile-event] prefab structure:<br>
<br>
 @racketblock[<br>
   (struct parallel-compile-event (worker event) #:prefab)<br>
-].<br>
+]<br>
<br>
 The worker field is the index of the worker that the created the event. The event<br>
 field is a @racket[compile-event] as document in<br>
@@ -550,25 +550,36 @@ field is a @racket[compile-event] as document in<br>
<br>
 @defmodule[compiler/cm-accomplice]<br>
<br>
-@defproc[(register-external-file [file (and path? complete-path?)]) void?]{<br>
+@defproc[(register-external-file [file (and path? complete-path?)]<br>
+                                 [#:indirect? indirect? any/c #f])<br>
+         void?]{<br>
<br>
-Logs a message (see @racket[log-message]) at level @racket['info] to<br>
-a logger named @racket['cm-accomplice]. The<br>
-message data is a @racketidfont{file-dependency} prefab structure type<br>
-with two fields; the first field's value is @racket[file] and the second<br>
-field's value is @racket[#f] (to indicate a non-module dependency).<br>
+Logs a message (see @racket[log-message]) at level @racket['info] to a<br>
+logger named @racket['cm-accomplice]. The message data is a<br>
+@racketidfont{file-dependency} prefab structure type with two fields;<br>
+the first field's value is @racket[file] and the second field's value<br>
+is @racket[#f] (to indicate a non-module dependency). If the<br>
+@racket[indirect?] argument is true, the data is more specifically an<br>
+instance of a @racketidfont{file-dependency/indirect} prefab structure<br>
+type that is a subtype of @racketidfont{file-dependency} with no new<br>
+fields.<br>
<br>
 A compilation manager implemented by @racketmodname[compiler/cm] looks<br>
-for such messages to register an external dependency. The compilation<br>
-manager records (in a @filepath{.dep} file) the path as contributing<br>
-to the implementation of the module currently being<br>
+for such messages to register an external dependency. In response, the<br>
+compilation manager records (in a @filepath{.dep} file) the path as<br>
+contributing to the implementation of the module currently being<br>
 compiled. Afterward, if the registered file is modified, the<br>
-compilation manager will know to recompile the module.<br>
+compilation manager will know to recompile the module. An ``indirect''<br>
+dependency has no effect on recompilation, but it can signal to other<br>
+tools, such as a package-dependency checker, that the dependency is<br>
+indirect (and should not imply a direct package dependency).<br>
<br>
 The @racket[include] macro, for example, calls this procedure with the<br>
 path of an included file as it expands an @racket[include] form.}<br>
<br>
-@defproc[(register-external-module [file (and path? complete-path?)]) void?]{<br>
+@defproc[(register-external-module [file (and path? complete-path?)]<br>
+                                   [#:indirect? indirect? any/c #f])<br>
+         void?]{<br>
<br>
 Like @racket[register-external-file], but logs a message with a<br>
 @racketidfont{file-dependency} prefab structure type whose second<br>
<br>
pkgs/racket-doc/scribblings/raco/setup.scrbl<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/pkgs/racket-doc/scribblings/raco/setup.scrbl<br>
+++ NEW/pkgs/racket-doc/scribblings/raco/setup.scrbl<br>
@@ -744,13 +744,14 @@ Optional @filepath{info.rkt} fields trigger additional actions by<br>
    module. More specifically, used modules are determined when<br>
    deleting a @filepath{.dep} file, which would have been created to<br>
    accompany a @filepath{.zo} file when the @filepath{.zo} was built<br>
-   by @exec{raco setup}. If the @filepath{.dep} file indicates another<br>
-   module, that module's @filepath{.zo} is deleted only if it also has<br>
-   an accompanying @filepath{.dep} file. In that case, the<br>
-   @filepath{.dep} file is deleted, and additional used modules are<br>
-   deleted based on the used module's @filepath{.dep} file, etc.<br>
-   Supplying a specific list of collections to @exec{raco setup} disables<br>
-   this dependency-based deletion of compiled files.}<br>
+   by @exec{raco setup} or @exec{raco make} (see<br>
+   @secref["Dependency\x20Files"]). If the @filepath{.dep} file<br>
+   indicates another module, that module's @filepath{.zo} is deleted<br>
+   only if it also has an accompanying @filepath{.dep} file. In that<br>
+   case, the @filepath{.dep} file is deleted, and additional used<br>
+   modules are deleted based on the used module's @filepath{.dep}<br>
+   file, etc. Supplying a specific list of collections to @exec{raco<br>
+   setup} disables this dependency-based deletion of compiled files.}<br>
<br>
 ]<br>
<br>
@@ -816,9 +817,10 @@ with fewer dependencies.<br>
 @subsection{How Dependency Checking Works}<br>
<br>
 Dependency checking uses @filepath{.zo} files, associated<br>
-@filepath{.dep} files, and the documentation index. Dynamic<br>
-references, such as through @racket[dynamic-require], are not visible<br>
-to the dependency checker; only dependencies via @racket[require],<br>
+@filepath{.dep} files (see @secref["Dependency Files"]), and the<br>
+documentation index. Dynamic references, such as through<br>
+@racket[dynamic-require], are not visible to the dependency checker;<br>
+only dependencies via @racket[require],<br>
 @racket[define-runtime-module-path-index], and other forms that<br>
 cooperate with @racket[raco make] are visible for dependency checking.<br>
<br>
<br>
pkgs/racket-doc/scribblings/reference/syntax.scrbl<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/pkgs/racket-doc/scribblings/reference/syntax.scrbl<br>
+++ NEW/pkgs/racket-doc/scribblings/reference/syntax.scrbl<br>
@@ -3005,10 +3005,10 @@ submodule). Introduced submodules have the names<br>
 @racket[lazy-require-]@racket[_n]@racketidfont{-}@racket[_m], where<br>
 @racket[_n] is a phase-level number and @racket[_m] is a number.<br>
<br>
-When the use of a lazily-required function triggers module loading,<br>
-@racket[register-external-module] declares a potential compilation<br>
-dependency (in case the function is used in the process of compiling a<br>
-module).<br>
+When the use of a lazily-required function triggers module loading, it<br>
+also triggers a use of @racket[register-external-module] to declare an<br>
+indirect compilation dependency (in case the function is used in the<br>
+process of compiling a module).<br>
<br>
 @examples[#:eval lazy-require-eval<br>
 (lazy-require<br>
<br>
racket/collects/compiler/cm-accomplice.rkt<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/racket/collects/compiler/cm-accomplice.rkt<br>
+++ NEW/racket/collects/compiler/cm-accomplice.rkt<br>
@@ -3,16 +3,18 @@<br>
 (provide register-external-file<br>
          register-external-module)<br>
<br>
-(define (register-external-file f)<br>
-  (register-external 'register-external-file f #f))<br>
-(define (register-external-module f)<br>
-  (register-external 'register-external-module f #t))<br>
+(define (register-external-file f #:indirect? [indirect? #f])<br>
+  (register-external 'register-external-file f #f indirect?))<br>
+(define (register-external-module f #:indirect? [indirect? #f])<br>
+  (register-external 'register-external-module f #t indirect?))<br>
<br>
-(define (register-external who f module?)<br>
+(define (register-external who f module? indirect?)<br>
   (unless (and (path? f) (complete-path? f))<br>
     (raise-type-error who "complete path" f))<br>
   (log-message (current-logger)<br>
                'info<br>
                'cm-accomplice<br>
                (format "file dependency: ~s" f)<br>
-               `#s(file-dependency ,f ,module?)))<br>
+               (if indirect?<br>
+                   `#s((file-dependency/indirect file-dependency 2) ,f ,module?)<br>
+                   `#s(file-dependency ,f ,module?))))<br>
<br>
racket/collects/compiler/cm.rkt<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/racket/collects/compiler/cm.rkt<br>
+++ NEW/racket/collects/compiler/cm.rkt<br>
@@ -231,9 +231,13 @@<br>
 (define (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots must-exist? seen)<br>
   (let ([l (for/fold ([l null]) ([dep (in-list deps)])<br>
              (and l<br>
+                  ;; (cons 'indirect dep) => indirect dependency (for pkg-dep checking)<br>
                   ;; (cons 'ext rel-path) => a non-module file, check source<br>
                   ;; rel-path => a module file name, check cache<br>
-                  (let* ([ext? (and (pair? dep) (eq? 'ext (car dep)))]<br>
+                  (let* ([dep (if (and (pair? dep) (eq? 'indirect (car dep)))<br>
+                                  (cdr dep)<br>
+                                  dep)]<br>
+                         [ext? (and (pair? dep) (eq? 'ext (car dep)))]<br>
                          [p (collects-relative*->path (if ext? (cdr dep) dep) collection-cache)])<br>
                     (cond<br>
                      [ext? (let ([v (get-source-sha1 p)])<br>
@@ -273,19 +277,26 @@<br>
                                          external-module-deps ; can create cycles if misused!<br>
                                          reader-deps))]<br>
         [external-deps (remove-duplicates external-deps)])<br>
+    (define (path*->collects-relative/maybe-indirect dep)<br>
+      (if (and (pair? dep) (eq? 'indirect (car dep)))<br>
+          (cons 'indirect (path*->collects-relative (cdr dep)))<br>
+          (path*->collects-relative dep)))<br>
     (with-compile-output dep-path<br>
       (lambda (op tmp-path)<br>
         (let ([deps (append<br>
-                     (map path*->collects-relative deps)<br>
+                     (map path*->collects-relative/maybe-indirect deps)<br>
                      (map (lambda (x)<br>
-                            (cons 'ext (path*->collects-relative x)))<br>
+                            (define d (path*->collects-relative/maybe-indirect x))<br>
+                            (if (and (pair? d) (eq? 'indirect d))<br>
+                                (cons 'indirect (cons 'ext (cdr d)))<br>
+                                (cons 'ext d)))<br>
                           external-deps))])<br>
-        (write (list* (version)<br>
-                      (cons (or src-sha1 (get-source-sha1 path))<br>
-                            (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots #t #hash()))<br>
-                      deps)<br>
-               op)<br>
-        (newline op))))))<br>
+          (write (list* (version)<br>
+                        (cons (or src-sha1 (get-source-sha1 path))<br>
+                              (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots #t #hash()))<br>
+                        deps)<br>
+                 op)<br>
+          (newline op))))))<br>
<br>
 (define (format-time sec)<br>
   (let ([d (seconds->date sec)])<br>
@@ -311,6 +322,7 @@<br>
 (define-struct ext-reader-guard (proc top)<br>
   #:property prop:procedure (struct-field-index proc))<br>
 (define-struct file-dependency (path module?) #:prefab)<br>
+(define-struct (file-dependency/indirect file-dependency) () #:prefab)<br>
<br>
 (define (compile-zo* mode roots path src-sha1 read-src-syntax zo-name up-to-date collection-cache)<br>
   ;; The `path' argument has been converted to .rkt or .ss form,<br>
@@ -322,10 +334,14 @@<br>
   (define reader-deps null)<br>
   (define deps-sema (make-semaphore 1))<br>
   (define done-key (gensym))<br>
-  (define (external-dep! p module?)<br>
+  (define (external-dep! p module? indirect?)<br>
+    (define bstr (path->bytes p))<br>
+    (define dep (if indirect?<br>
+                    (cons 'indirect bstr)<br>
+                    bstr))<br>
     (if module?<br>
-        (set! external-module-deps (cons (path->bytes p) external-module-deps))<br>
-        (set! external-deps (cons (path->bytes p) external-deps))))<br>
+        (set! external-module-deps (cons dep external-module-deps))<br>
+        (set! external-deps (cons dep external-deps))))<br>
   (define (reader-dep! p)<br>
     (call-with-semaphore<br>
      deps-sema<br>
@@ -386,7 +402,8 @@<br>
                    (file-dependency? (vector-ref l 2))<br>
                    (path? (file-dependency-path (vector-ref l 2))))<br>
           (external-dep! (file-dependency-path (vector-ref l 2))<br>
-                         (file-dependency-module? (vector-ref l 2))))<br>
+                         (file-dependency-module? (vector-ref l 2))<br>
+                         (file-dependency/indirect? (vector-ref l 2))))<br>
         (loop))))<br>
<br>
   ;; Write the code and dependencies:<br>
@@ -627,9 +644,13 @@<br>
               ;; If `sha1-only?', then `maybe-compile-zo' returns a #f or thunk:<br>
               (maybe-compile-zo sha1-only? deps mode roots path orig-path read-src-syntax up-to-date collection-cache new-seen)]<br>
              [(ormap<br>
-               (lambda (p)<br>
+               (lambda (raw-p)<br>
+                 ;; (cons 'indirect dep) => indirect dependency (for pkg-dep checking)<br>
                  ;; (cons 'ext rel-path) => a non-module file (check date)<br>
                  ;; rel-path => a module file name (check transitive dates)<br>
+                 (define p (if (and (pair? raw-p) (eq? 'indirect (car raw-p)))<br>
+                               (cdr raw-p)<br>
+                               raw-p))<br>
                  (define ext? (and (pair? p) (eq? 'ext (car p))))<br>
                  (define d (collects-relative*->path (if ext? (cdr p) p) collection-cache))<br>
                  (define t<br>
<br>
racket/collects/racket/lazy-require.rkt<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/racket/collects/racket/lazy-require.rkt<br>
+++ NEW/racket/collects/racket/lazy-require.rkt<br>
@@ -110,4 +110,4 @@<br>
                  modpath<br>
                  (variable-reference->resolved-module-path vr))))])<br>
     (when (path? path)<br>
-      (register-external-module path))))<br>
+      (register-external-module path #:indirect? #t))))<br>
<br>
racket/collects/setup/private/pkg-deps.rkt<br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
--- OLD/racket/collects/setup/private/pkg-deps.rkt<br>
+++ NEW/racket/collects/setup/private/pkg-deps.rkt<br>
@@ -489,6 +489,7 @@<br>
             ;; Treat everything in ".dep" as 'build mode...<br>
             (define deps (cddr (call-with-input-file* (build-path dir f) read)))<br>
             (for ([dep (in-list deps)])<br>
+              ;; Note: indirect dependencies (which start with 'indirect) are ignored<br>
               (when (and (pair? dep)<br>
                          (eq? 'collects (car dep)))<br>
                 (define path-strs (map bytes->string/utf-8 (cdr dep)))<br>
</blockquote></div><br></div>