test: lock in incremental-rebuild for root_module-aliased deps#14335
Open
robinbb wants to merge 1 commit intoocaml:mainfrom
Open
test: lock in incremental-rebuild for root_module-aliased deps#14335robinbb wants to merge 1 commit intoocaml:mainfrom
robinbb wants to merge 1 commit intoocaml:mainfrom
Conversation
d3072d0 to
7984ef8
Compare
There was a problem hiding this comment.
Pull request overview
Adds a blackbox regression test to specify incremental rebuild behavior when a consumer uses (root_module ...) to access an aliased dependency, ensuring interface changes trigger rebuilds while implementation-only changes do not.
Changes:
- Add a new blackbox test case under
test/blackbox-tests/test-cases/root-module/to lock in incremental rebuild behavior for root-module-aliased deps. - Validate rebuild/no-rebuild outcomes by querying
dune traceoutput viajq.
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
Apr 25, 2026
A consumer that uses [Root.LibY.foo] reports only [Root] as a top-level ocamldep reference; qualified-path components are not surfaced. The filter therefore needs to look through [Root] to discover [LibY]. But [Root] had no [.d] file (its [Module.kind] short-circuits in [Dep_rules.deps_of] via [is_alias_or_root], an intentional cycle-prevention measure introduced in commit a5d8945 / change ocaml#12227), so [read_immediate_deps_raw_of] returned an empty set and the cross-library walk never reached [LibY]. The consumer's compile rule was missing the dep on [LibY]'s cmi: the OCaml path got away with it because [-I] flags still found the cmi at compile time, but Melange's strict- ordering rules surfaced the gap as a missing-cmi error. Synthesise a [.d]-format file for [Root] alongside [root.ml] in [build_root_module], using [Root_module.entries] (the same input [root.ml] is generated from). The file matches what [ocamldep -modules] would output, so the general path in [Ocamldep.read_immediate_deps_raw_of] reads it like any other module's [.d]. [obj_dir.ml] is updated to return a path for [(Root, Immediate _)] while continuing to refuse [(Root, Transitive _)] — the cycle that motivated the original short-circuit lives in [.all-deps] generation, which we still suppress. This keeps [read_dep_m_raw] uniform (no [Module.kind] switch), shrinks [module_kind_has_readable_ocamldep]'s false branch by one entry, and locates the [Root] knowledge in [build_root_module] where [root.ml] is also produced. The regression test for incremental-rebuild behaviour through [Root] lives separately at test/blackbox-tests/test-cases/root-module/incremental-rebuild.t in the prerequisite PR (ocaml#14335), so the test is on main as a pure regression guard. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
7984ef8 to
5d88955
Compare
5d88955 to
e511ed8
Compare
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
Apr 26, 2026
A consumer that uses [Root.LibY.foo] reports only [Root] as a top-level ocamldep reference; qualified-path components are not surfaced. The filter therefore needs to look through [Root] to discover [LibY]. But [Root] had no [.d] file (its [Module.kind] short-circuits in [Dep_rules.deps_of] via [is_alias_or_root], an intentional cycle-prevention measure introduced in commit a5d8945 / change ocaml#12227), so [read_immediate_deps_raw_of] returned an empty set and the cross-library walk never reached [LibY]. The consumer's compile rule was missing the dep on [LibY]'s cmi: the OCaml path got away with it because [-I] flags still found the cmi at compile time, but Melange's strict- ordering rules surfaced the gap as a missing-cmi error. Synthesise a [.d]-format file for [Root] alongside [root.ml] in [build_root_module], using [Root_module.entries] (the same input [root.ml] is generated from). The file matches what [ocamldep -modules] would output, so the general path in [Ocamldep.read_immediate_deps_raw_of] reads it like any other module's [.d]. [obj_dir.ml] is updated to return a path for [(Root, Immediate _)] while continuing to refuse [(Root, Transitive _)] — the cycle that motivated the original short-circuit lives in [.all-deps] generation, which we still suppress. This keeps [read_dep_m_raw] uniform (no [Module.kind] switch), shrinks [module_kind_has_readable_ocamldep]'s false branch by one entry, and locates the [Root] knowledge in [build_root_module] where [root.ml] is also produced. The regression test for incremental-rebuild behaviour through [Root] lives separately at test/blackbox-tests/test-cases/root-module/incremental-rebuild.t in the prerequisite PR (ocaml#14335), so the test is on main as a pure regression guard. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
Apr 27, 2026
A consumer that uses [Root.LibY.foo] reports only [Root] as a top-level ocamldep reference; qualified-path components are not surfaced. The filter therefore needs to look through [Root] to discover [LibY]. But [Root] had no [.d] file (its [Module.kind] short-circuits in [Dep_rules.deps_of] via [is_alias_or_root], an intentional cycle-prevention measure introduced in commit a5d8945 / change ocaml#12227), so [read_immediate_deps_raw_of] returned an empty set and the cross-library walk never reached [LibY]. The consumer's compile rule was missing the dep on [LibY]'s cmi: the OCaml path got away with it because [-I] flags still found the cmi at compile time, but Melange's strict- ordering rules surfaced the gap as a missing-cmi error. Synthesise a [.d]-format file for [Root] alongside [root.ml] in [build_root_module], using [Root_module.entries] (the same input [root.ml] is generated from). The file matches what [ocamldep -modules] would output, so the general path in [Ocamldep.read_immediate_deps_raw_of] reads it like any other module's [.d]. [obj_dir.ml] is updated to return a path for [(Root, Immediate _)] while continuing to refuse [(Root, Transitive _)] — the cycle that motivated the original short-circuit lives in [.all-deps] generation, which we still suppress. This keeps [read_dep_m_raw] uniform (no [Module.kind] switch), shrinks [module_kind_has_readable_ocamldep]'s false branch by one entry, and locates the [Root] knowledge in [build_root_module] where [root.ml] is also produced. The regression test for incremental-rebuild behaviour through [Root] lives separately at test/blackbox-tests/test-cases/root-module/incremental-rebuild.t in the prerequisite PR (ocaml#14335), so the test is on main as a pure regression guard. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
Add a regression test asserting that a consumer using [(root_module ...)] to alias a dependency rebuilds when the dependency's [.mli] changes, and does not rebuild when only the dependency's [.ml] changes. The property holds today via dune's existing glob-over-objdir mechanism; the test guards it as a specification against future inter-library-dependency-tracking changes (notably the per-module filter being developed in Signed-off-by: Robin Bate Boerop <me@robinbb.com> ocaml#14116).
e511ed8 to
241dd79
Compare
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
Apr 27, 2026
A consumer that uses [Root.LibY.foo] reports only [Root] as a top-level ocamldep reference; qualified-path components are not surfaced. The filter therefore needs to look through [Root] to discover [LibY]. But [Root] had no [.d] file (its [Module.kind] short-circuits in [Dep_rules.deps_of] via [is_alias_or_root], an intentional cycle-prevention measure introduced in commit a5d8945 / change ocaml#12227), so [read_immediate_deps_raw_of] returned an empty set and the cross-library walk never reached [LibY]. The consumer's compile rule was missing the dep on [LibY]'s cmi: the OCaml path got away with it because [-I] flags still found the cmi at compile time, but Melange's strict- ordering rules surfaced the gap as a missing-cmi error. Synthesise a [.d]-format file for [Root] alongside [root.ml] in [build_root_module], using [Root_module.entries] (the same input [root.ml] is generated from). The file matches what [ocamldep -modules] would output, so the general path in [Ocamldep.read_immediate_deps_raw_of] reads it like any other module's [.d]. [obj_dir.ml] is updated to return a path for [(Root, Immediate _)] while continuing to refuse [(Root, Transitive _)] — the cycle that motivated the original short-circuit lives in [.all-deps] generation, which we still suppress. This keeps [read_dep_m_raw] uniform (no [Module.kind] switch), shrinks [module_kind_has_readable_ocamldep]'s false branch by one entry, and locates the [Root] knowledge in [build_root_module] where [root.ml] is also produced. The regression test for incremental-rebuild behaviour through [Root] lives separately at test/blackbox-tests/test-cases/root-module/incremental-rebuild.t in the prerequisite PR (ocaml#14335), so the test is on main as a pure regression guard. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a regression test under
test/blackbox-tests/test-cases/root-module/that asserts the incremental-rebuild property for(root_module …)-aliased dependencies:.mliinvalidates the consumer..mldoes not invalidate the consumer.This property holds on
maintoday via dune's existing glob-over-objdir mechanism. The test locks it in as a specification — any future change to dune's inter-library-dependency tracking (notably the per-module filter being developed in #14116) must preserve it.Test plan
dune runtest test/blackbox-tests/test-cases/root-module/