diff --git a/doc/dune-files.rst b/doc/dune-files.rst index 06221c85cbd3..8d09dcf0d0ff 100644 --- a/doc/dune-files.rst +++ b/doc/dune-files.rst @@ -75,9 +75,10 @@ dialect Specify the file extension used for this dialect. - The extension string must not contain any dots and be unique in a given + The extension string must not start with a dot and be unique in a given project (so that a given extension can be mapped back to a - corresponding dialect). + corresponding dialect). In Dune 3.8 and later, the extension string may + contain embedded dots (eg `cppo.ml`). This field is required. diff --git a/src/dune_rules/dialect.ml b/src/dune_rules/dialect.ml index cbe815918dbb..fac14e334455 100644 --- a/src/dune_rules/dialect.ml +++ b/src/dune_rules/dialect.ml @@ -77,10 +77,15 @@ let decode = (map ~f:(fun (loc, x) -> (loc, x, [])) (located Action.decode_dune_file)) - in + and+ syntax_ver = Syntax.get_exn Stanza.syntax in let extension = - if String.contains extension '.' then - User_error.raise ~loc [ Pp.textf "extension must not contain '.'" ]; + if String.length extension > 0 && extension.[0] = '.' then + User_error.raise ~loc [ Pp.textf "extension must not start with a '.'" ]; + let ver = (3, 8) in + if syntax_ver < ver && String.contains extension '.' then begin + let what = "the possibility of defining extensions with embedded dots" in + Syntax.Error.since loc Stanza.syntax ver ~what + end; "." ^ extension in { File_kind.kind; extension; preprocess; format } diff --git a/test/blackbox-tests/test-cases/dialects/bad3.t/run.t b/test/blackbox-tests/test-cases/dialects/bad3.t/run.t index 1eb6acbdcd2b..be25b618df76 100644 --- a/test/blackbox-tests/test-cases/dialects/bad3.t/run.t +++ b/test/blackbox-tests/test-cases/dialects/bad3.t/run.t @@ -2,5 +2,5 @@ File "dune-project", line 5, characters 28-32: 5 | (implementation (extension .foo)) ^^^^ - Error: extension must not contain '.' + Error: extension must not start with a '.' [1] diff --git a/test/blackbox-tests/test-cases/dialects/dots.t/cppo.ml b/test/blackbox-tests/test-cases/dialects/dots.t/cppo.ml new file mode 100644 index 000000000000..e729c918f0b0 --- /dev/null +++ b/test/blackbox-tests/test-cases/dialects/dots.t/cppo.ml @@ -0,0 +1,2 @@ +let () = + print_endline {|print_endline "Hello, World"|} diff --git a/test/blackbox-tests/test-cases/dialects/dots.t/dune b/test/blackbox-tests/test-cases/dialects/dots.t/dune new file mode 100644 index 000000000000..61867531c4ff --- /dev/null +++ b/test/blackbox-tests/test-cases/dialects/dots.t/dune @@ -0,0 +1,11 @@ +(executable + (name main) + (modules main)) + +(executable + (name cppo) + (modules cppo)) + +(rule + (alias show) + (action (cat main.cppo.ml.ml))) diff --git a/test/blackbox-tests/test-cases/dialects/dots.t/dune-project.in b/test/blackbox-tests/test-cases/dialects/dots.t/dune-project.in new file mode 100644 index 000000000000..2229acf9bc38 --- /dev/null +++ b/test/blackbox-tests/test-cases/dialects/dots.t/dune-project.in @@ -0,0 +1,8 @@ +(dialect + (name cppo) + (implementation + (extension cppo.ml) + (preprocess (run ./cppo.exe %{input-file}))) + (interface + (extension cppo.mli) + (preprocess (run ./cppo.exe %{input-file})))) diff --git a/test/blackbox-tests/test-cases/dialects/dots.t/main.cppo.ml b/test/blackbox-tests/test-cases/dialects/dots.t/main.cppo.ml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/blackbox-tests/test-cases/dialects/dots.t/main.mli b/test/blackbox-tests/test-cases/dialects/dots.t/main.mli new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/blackbox-tests/test-cases/dialects/dots.t/run.t b/test/blackbox-tests/test-cases/dialects/dots.t/run.t new file mode 100644 index 000000000000..0d99bfffa8f2 --- /dev/null +++ b/test/blackbox-tests/test-cases/dialects/dots.t/run.t @@ -0,0 +1,26 @@ +Test the (dialect ...) stanza inside the dune-project file. + + $ { echo '(lang dune 3.7)'; cat dune-project.in; } >dune-project + + $ dune build --display short + File "dune-project", line 5, characters 13-20: + 5 | (extension cppo.ml) + ^^^^^^^ + Error: the possibility of defining extensions with embedded dots is only + available since version 3.8 of the dune language. Please update your + dune-project file to have (lang dune 3.8). + [1] + + $ { echo '(lang dune 3.8)'; cat dune-project.in; } >dune-project + + $ dune build --display short + ocamlc .cppo.eobjs/byte/dune__exe__Cppo.{cmi,cmti} + ocamlc .main.eobjs/byte/dune__exe__Main.{cmi,cmti} + ocamlopt .cppo.eobjs/native/dune__exe__Cppo.{cmx,o} + ocamlopt cppo.exe + cppo main.cppo.ml.ml + ocamlopt .main.eobjs/native/dune__exe__Main.{cmx,o} + ocamlopt main.exe + + $ dune build @show + print_endline "Hello, World"