Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions src/dune_lang/preprocess.ml
Original file line number Diff line number Diff line change
Expand Up @@ -369,20 +369,30 @@ module Per_module = struct
;;
end

let preprocess_fields =
let preprocess_fields_with_prefix ~prefix:field_prefix =
let open Decoder in
let+ preprocess = field "preprocess" Per_module.decode ~default:(Per_module.default ())
let prefix =
let prefix x = x ^ "." in
Option.map field_prefix ~f:prefix |> Option.value ~default:""
in
let+ preprocess =
match field_prefix with
| None ->
let+ v = field "preprocess" Per_module.decode ~default:(Per_module.default ()) in
Some v
| Some _ -> field_o (prefix ^ "preprocess") Per_module.decode
and+ preprocessor_deps =
field_o
"preprocessor_deps"
(let+ loc = loc
and+ l = repeat Dep_conf.decode in
loc, l)
let decode =
let+ loc = loc
and+ l = repeat Dep_conf.decode in
loc, l
in
field_o (prefix ^ "preprocessor_deps") decode
and+ syntax = Syntax.get_exn Stanza.syntax in
let preprocessor_deps =
match preprocessor_deps with
| None -> []
| Some (loc, deps) ->
match preprocessor_deps, preprocess with
| Some _, None | None, _ -> []
| Some (loc, deps), Some preprocess ->
let deps_might_be_used =
Module_name.Per_item.exists preprocess ~f:(fun p ->
match p with
Expand All @@ -394,15 +404,22 @@ let preprocess_fields =
User_warning.emit
~loc
~is_error:(syntax >= (2, 0))
[ Pp.text
"This preprocessor_deps field will be ignored because no preprocessor that \
might use them is configured."
[ Pp.textf
"This %spreprocessor_deps field will be ignored because no preprocessor \
that might use them is configured."
prefix
];
deps
in
preprocess, preprocessor_deps
;;

let preprocess_fields =
let open Decoder in
let+ preprocess, deps = preprocess_fields_with_prefix ~prefix:None in
Option.value_exn preprocess, deps
;;

type preprocess =
{ config : With_instrumentation.t Per_module.t
; preprocessor_deps : Dep_conf.t list
Expand Down
50 changes: 47 additions & 3 deletions src/dune_rules/stanzas/buildable.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,40 @@ let decode_melange_pps =
(Dune_lang.Syntax.since Stanza.syntax (3, 24) >>> Preprocess.Pps.decode)
;;

let decode_melange_preprocess =
let+ preprocess = field_o "melange.preprocess" Preprocess.Per_module.decode
and+ preprocessor_deps =
field_o
"melange.preprocessor_deps"
(Dune_lang.Syntax.since Stanza.syntax (3, 24)
>>> let+ loc = loc
and+ l = repeat Dep_conf.decode in
loc, l)
and+ syntax = Dune_lang.Syntax.get_exn Stanza.syntax in
let preprocessor_deps =
match preprocessor_deps, preprocess with
| Some _, None | None, _ -> []
| Some (loc, deps), Some preprocess ->
let deps_might_be_used =
Module_name.Per_item.exists preprocess ~f:(fun p ->
match p with
| Preprocess.Action _ | Preprocess.Pps _ -> true
| Preprocess.No_preprocessing | Preprocess.Future_syntax _ -> false)
in
if not deps_might_be_used
then
User_warning.emit
~loc
~is_error:(syntax >= (2, 0))
[ Pp.text
"This melange.preprocessor_deps field will be ignored because no \
preprocessor that might use them is configured."
];
deps
in
preprocess, preprocessor_deps
;;

let decode (for_ : for_) =
let use_foreign =
Dune_lang.Syntax.deleted_in
Expand All @@ -78,6 +112,7 @@ let decode (for_ : for_) =
let+ loc = loc
and+ instrumentation = Preprocess.Instrumentation.instrumentation
and+ preprocess, preprocessor_deps = Preprocess.preprocess_fields
and+ melange_preprocess, melange_preprocessor_deps = decode_melange_preprocess
and+ melange_pps = decode_melange_pps
and+ lint = decode_lint
and+ foreign_stubs =
Expand Down Expand Up @@ -153,11 +188,20 @@ let decode (for_ : for_) =
Preprocess.preprocess_config ~preprocess ~instrumentation ~preprocessor_deps
in
let melange_preprocess =
match melange_pps with
| None -> preprocess
| Some pps ->
match melange_preprocess, melange_pps with
| None, None -> preprocess
| Some preprocess, None ->
Preprocess.preprocess_config
~preprocess
~instrumentation
~preprocessor_deps:melange_preprocessor_deps
| None, Some pps ->
let preprocess = Module_name.Per_item.for_all (Preprocess.Pps pps) in
Preprocess.preprocess_config ~preprocess ~instrumentation ~preprocessor_deps:[]
| Some _, Some pps ->
User_error.raise
~loc:pps.loc
[ Pp.text "Cannot use both melange.pps and melange.preprocess." ]
in
let foreign_stubs =
foreign_stubs
Expand Down
4 changes: 3 additions & 1 deletion src/dune_rules/vimpl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ let make ~sctx ~scope ~(lib : Library.t) ~info ~vlib ~for_ =
let* preprocess =
(* TODO wrong, this should be delayed *)
Instrumentation.with_instrumentation
lib.buildable.preprocess.config
(match for_ with
| Ocaml -> lib.buildable.preprocess.config
| Melange -> lib.buildable.melange_preprocess.config)
~instrumentation_backend:(Lib.DB.instrumentation_backend db)
|> Resolve.Memo.read_memo
in
Expand Down
53 changes: 53 additions & 0 deletions test/blackbox-tests/test-cases/melange/conditional-pps.t
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,56 @@ The field is available starting in Dune 3.24.
$ find ./app/_build/default -name '*.pp.ml' | censor | sort
./app/_build/default/.melange_src/foo.pp.ml
./app/_build/default/.melange_src/melange_only.pp.ml

`melange.preprocessor_deps` is available starting in Dune 3.24.

$ mkdir old-preprocessor-deps
$ cat > old-preprocessor-deps/dune-project <<EOF
> (lang dune 3.23)
> (using melange 0.1)
> EOF
$ cat > old-preprocessor-deps/dune <<EOF
> (library
> (name old_preprocessor_deps)
> (modes melange)
> (melange.preprocessor_deps dep.txt))
> EOF
$ dune build --root old-preprocessor-deps
Entering directory 'old-preprocessor-deps'
File "dune", line 4, characters 1-36:
4 | (melange.preprocessor_deps dep.txt))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: 'melange.preprocessor_deps' is only available since version 3.24 of
the dune language. Please update your dune-project file to have (lang dune
3.24).
Leaving directory 'old-preprocessor-deps'
[1]

`melange.preprocessor_deps` applies only to Melange preprocessing.

$ mkdir deps
$ cat > deps/dune-project <<EOF
> (lang dune 3.24)
> (using melange 0.1)
> EOF
$ cat > deps/dune <<EOF
> (library
> (modes melange :standard)
> (name deps)
> (melange.preprocess (action (run ./pp.sh %{input-file})))
> (melange.preprocessor_deps pp.sh))
> EOF

$ cat > deps/foo.ml <<EOF
> let x = "foo"
> EOF
$ cat > deps/pp.sh <<EOF
> #!/bin/sh
> cat "\$1"
> echo 'let y = "from melange preprocessor"'
> EOF
$ chmod +x deps/pp.sh

$ dune build --root deps
$ grep y deps/_build/default/.melange_src/foo.pp.ml
let y = "from melange preprocessor"
Loading