Skip to content

Commit 97fb11b

Browse files
committed
Fix optional handling for executables
* if an executable is optional, evaluate its dependencies to see if should be available * if the executable isn't optional, always provide the binary Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
1 parent b20a615 commit 97fb11b

File tree

6 files changed

+56
-35
lines changed

6 files changed

+56
-35
lines changed

CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ Unreleased
162162
- Allow depending on `ocamldoc` library when `ocamlfind` is not installed.
163163
(#4811, fixes #4809, @nojb)
164164

165+
- Improve lookup of optional or disabled binaries. Previously, we'd treat every
166+
executable with missing libraries as optional. Now, we treat make sure to
167+
look at the library's optional or enabled_if status (#4786).
168+
165169
2.9.1 (unreleased)
166170
------------------
167171

src/dune_rules/artifacts.mli

-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ module Bin : sig
1515
-> Action.Prog.t Memo.Build.t
1616

1717
val add_binaries : t -> dir:Path.Build.t -> File_binding.Expanded.t list -> t
18-
19-
val create : context:Context.t -> local_bins:Path.Build.Set.t -> t
2018
end
2119

2220
module Public_libs : sig

src/dune_rules/expander.ml

+7-4
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,11 @@ module With_reduced_var_set = struct
731731
let expand_str_partial ~context ~dir sw =
732732
String_with_vars.expand_as_much_as_possible ~dir:(Path.build dir) sw
733733
~f:(expand_pform_opt ~context ~bindings:Pform.Map.empty ~dir)
734+
735+
let eval_blang ~context ~dir blang =
736+
Blang.eval
737+
~f:(expand_pform ~context ~bindings:Pform.Map.empty ~dir)
738+
~dir:(Path.build dir) blang
734739
end
735740

736741
let expand_and_eval_set t set ~standard =
@@ -744,9 +749,7 @@ let expand_and_eval_set t set ~standard =
744749
Ordered_set_lang.eval set ~standard ~eq:String.equal ~parse:(fun ~loc:_ s ->
745750
s)
746751

747-
let eval_blang t = function
748-
| Blang.Const x -> Memo.Build.return x (* common case *)
749-
| blang ->
750-
Blang.eval blang ~dir:(Path.build t.dir) ~f:(No_deps.expand_pform t)
752+
let eval_blang t blang =
753+
Blang.eval ~f:(No_deps.expand_pform t) ~dir:(Path.build t.dir) blang
751754

752755
let find_package t pkg = t.find_package pkg

src/dune_rules/expander.mli

+3
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ module With_reduced_var_set : sig
130130
-> dir:Path.Build.t
131131
-> String_with_vars.t
132132
-> String_with_vars.t Memo.Build.t
133+
134+
val eval_blang :
135+
context:Context.t -> dir:Path.Build.t -> Blang.t -> bool Memo.Build.t
133136
end
134137

135138
(** Expand forms of the form (:standard \ foo bar). Expansion is only possible

src/dune_rules/super_context.ml

+33-22
Original file line numberDiff line numberDiff line change
@@ -461,29 +461,40 @@ let get_installed_binaries stanzas ~(context : Context.t) =
461461
binaries_from_install files
462462
| Dune_file.Executables
463463
({ install_conf = Some { section = Section Bin; files; _ }; _ } as
464-
exes) ->
465-
let* compile_info =
466-
let project = Scope.project d.scope in
467-
let dune_version = Dune_project.dune_version project in
468-
let+ pps =
469-
Resolve.read_memo_build
470-
(Preprocess.Per_module.with_instrumentation
471-
exes.buildable.preprocess
472-
~instrumentation_backend:
473-
(Lib.DB.instrumentation_backend (Scope.libs d.scope)))
474-
>>| Preprocess.Per_module.pps
475-
in
476-
Lib.DB.resolve_user_written_deps_for_exes (Scope.libs d.scope)
477-
exes.names exes.buildable.libraries ~pps ~dune_version
478-
~allow_overlaps:exes.buildable.allow_overlapping_dependencies
464+
exes) -> (
465+
let* enabled_if =
466+
Expander.With_reduced_var_set.eval_blang ~context ~dir:d.ctx_dir
467+
exes.enabled_if
479468
in
480-
let available =
481-
Resolve.is_ok (Lib.Compile.direct_requires compile_info)
482-
in
483-
if available then
484-
binaries_from_install files
485-
else
486-
Memo.Build.return Path.Build.Set.empty
469+
match enabled_if with
470+
| false -> Memo.Build.return Path.Build.Set.empty
471+
| true -> (
472+
match exes.optional with
473+
| false -> binaries_from_install files
474+
| true ->
475+
let* compile_info =
476+
let project = Scope.project d.scope in
477+
let dune_version = Dune_project.dune_version project in
478+
let+ pps =
479+
Resolve.read_memo_build
480+
(Preprocess.Per_module.with_instrumentation
481+
exes.buildable.preprocess
482+
~instrumentation_backend:
483+
(Lib.DB.instrumentation_backend (Scope.libs d.scope)))
484+
>>| Preprocess.Per_module.pps
485+
in
486+
Lib.DB.resolve_user_written_deps_for_exes (Scope.libs d.scope)
487+
exes.names exes.buildable.libraries ~pps ~dune_version
488+
~allow_overlaps:
489+
exes.buildable.allow_overlapping_dependencies
490+
in
491+
let available =
492+
Resolve.is_ok (Lib.Compile.direct_requires compile_info)
493+
in
494+
if available then
495+
binaries_from_install files
496+
else
497+
Memo.Build.return Path.Build.Set.empty))
487498
| _ -> Memo.Build.return Path.Build.Set.empty)
488499
>>| Path.Build.Set.union_all)
489500
>>| Path.Build.Set.union_all

test/blackbox-tests/test-cases/optional-executable.t/run.t

+9-7
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,17 @@ present even if the binary is not optional.
120120

121121
$ mkdir bin
122122
$ cat >bin/dunetestbar <<EOF
123-
> /usr/bin/env bash
123+
> #!/usr/bin/env bash
124124
> echo shadow
125125
> EOF
126126
$ chmod +x ./bin/dunetestbar
127127

128128
$ PATH=./bin:$PATH dune build @run-x
129-
binary path: $TESTCASE_ROOT/optional-binary-absent/./bin/dunetestbar
129+
File "exe/dune", line 3, characters 12-29:
130+
3 | (libraries doesnotexistatall)
131+
^^^^^^^^^^^^^^^^^
132+
Error: Library "doesnotexistatall" not found.
133+
[1]
130134

131135
Optional on the executable should be respected:
132136

@@ -139,6 +143,7 @@ Optional on the executable should be respected:
139143
> EOF
140144

141145
$ PATH=./bin:$PATH dune build @run-x
146+
binary path: $TESTCASE_ROOT/optional-binary-absent/./bin/dunetestbar
142147

143148
In the same way as enabled_if:
144149

@@ -149,11 +154,8 @@ In the same way as enabled_if:
149154
> (name bar))
150155
> EOF
151156

152-
$ PATH=./bin:$PATH dune build @run-x
153-
Error: No rule found for install bin/dunetestbar
154-
-> required by %{bin:dunetestbar} at dune:3
155-
-> required by alias run-x in dune:1
156-
[1]
157+
$ PATH=./bin:$PATH dune build @run-x --force
158+
binary path: $TESTCASE_ROOT/optional-binary-absent/./bin/dunetestbar
157159

158160
$ cd ..
159161

0 commit comments

Comments
 (0)