Hello,
TL/DR: compiling a file using an action
in dune seem to run directly in the directory where the dependency lives, breaking error reporting in emacs.
When compiling an OCaml file for a project, dune jumps to the root of the project (with a message Entering directory…
and then it silently switches to the build directory to actually compile the file. So to compile bin/main.ml
, the compilation command uses that path, as can be seen in the verbose log:
❯ dune exe asm --verbose
Entering directory '/Users/schmitta/work/teaching/asm/skel/cours_2024/asm'
Shared cache: enabled-except-user-rules
Shared cache location: /Users/schmitta/.cache/dune/db
Workspace root: /Users/schmitta/work/teaching/asm/skel/cours_2024/asm
Auto-detected concurrency: 8
Dune context:
{ name = "default"
; kind = "default"
; profile = Dev
; merlin = true
; fdo_target_exe = None
; build_dir = In_build_dir "default"
; instrument_with = []
}
Running[1]: (cd _build/default && /Users/schmitta/.opam/5.2.0/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -w -32 -w -37 -w -27 -g -I bin/.main.eobjs/byte -I bin/.main.eobjs/native -I /Users/schmitta/.opam/5.2.0/lib/necroml -intf-suffix .ml -no-alias-deps -opaque -open Dune__exe -o bin/.main.eobjs/native/dune__exe__Main.cmx -c -impl bin/main.ml)
Command [1] exited with code 2:
$ (cd _build/default && /Users/schmitta/.opam/5.2.0/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -w -32 -w -37 -w -27 -g -I bin/.main.eobjs/byte -I bin/.main.eobjs/native -I /Users/schmitta/.opam/5.2.0/lib/necroml -intf-suffix .ml -no-alias-deps -opaque -open Dune__exe -o bin/.main.eobjs/native/dune__exe__Main.cmx -c -impl bin/main.ml)
File "bin/main.ml", line 171, characters 7-9:
171 | n1 + n2 foo
^^
Error: This expression has type int
This is not a function; it cannot be applied.
The important part is that the error reported mentions bin/main.ml
(as it is the path of the file compiled), so emacs can find it when running dune from it.
This unfortunately does not work when the file is compiled because of an action. I have the following in my dune
file:
(rule
(target arith.ml)
(deps arith.sk)
(action (run necroml -o %{target} %{deps})))
When I have an error in bin/arith.sk
, it is reported as being in arith.sk
directly as it is how the action is run:
❯ dune exe asm --verbose
Entering directory '/Users/schmitta/work/teaching/asm/skel/cours_2024/asm'
Shared cache: enabled-except-user-rules
Shared cache location: /Users/schmitta/.cache/dune/db
Workspace root: /Users/schmitta/work/teaching/asm/skel/cours_2024/asm
Auto-detected concurrency: 8
Dune context:
{ name = "default"
; kind = "default"
; profile = Dev
; merlin = true
; fdo_target_exe = None
; build_dir = In_build_dir "default"
; instrument_with = []
}
Running[1]: (cd _build/default && /Users/schmitta/.opam/5.2.0/bin/ocamldep.opt -modules -impl bin/main.ml) > _build/default/bin/.main.eobjs/dune__exe__Main.impl.d
Running[2]: (cd _build/default/bin && /Users/schmitta/.opam/5.2.0/bin/necroml -o arith.ml arith.sk)
Command [2] exited with code 1:
$ (cd _build/default/bin && /Users/schmitta/.opam/5.2.0/bin/necroml -o arith.ml arith.sk)
File "arith.sk", line 63, characters 10-11:
Syntax error, unexpected token: a
As the path is missing, emacs cannot directly jump to the error.
Is there a way to tell dune to run the action from the build directory root (here to run necroml -o bin/arith.ml bin/arith.sk
)?
Alan