Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cxx extension for C++ stubs #1831

Merged
merged 4 commits into from
Feb 13, 2019
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
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ unreleased
fixes the support for `[@@deriving_inline]` with older versions of
ppxlib (#...., @diml)

- Add support for `.cxx` extension for C++ stubs (#1831, @rgrinberg)

1.7.1 (13/02/2019)
------------------

Expand All @@ -16,6 +18,7 @@ unreleased
1.7.0 (12/02/2019)
------------------


- Second step of the deprecation of jbuilder: the `jbuilder` binary
now emits a warning on every startup and both `jbuilder` and `dune`
emit warnings when encountering `jbuild` files (#1752, @diml)
Expand Down
29 changes: 22 additions & 7 deletions src/c.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,31 @@ module Kind = struct
| C -> Format.pp_print_string fmt "c"
| Cxx -> Format.pp_print_string fmt "cpp"

let split_extension fn =
match String.lsplit2 fn ~on:'.' with
| Some (obj, "c") -> Some (obj, C)
| Some (obj, "cpp") -> Some (obj, Cxx)
| _ -> None
type split =
| Unrecognized
| Not_allowed_until of Syntax.Version.t
| Recognized of string * t

let possible_fns t fn =
let split_extension fn ~dune_version =
match String.lsplit2 fn ~on:'.' with
| Some (obj, "c") -> Recognized (obj, C)
| Some (obj, "cpp") -> Recognized (obj, Cxx)
| Some (obj, "cxx") ->
if dune_version >= (1, 8) then
Recognized (obj, Cxx)
else
Not_allowed_until (1, 8)
| _ -> Unrecognized

let possible_fns t fn ~dune_version =
match t with
| C -> [fn ^ ".c"]
| Cxx -> [fn ^ ".cpp"]
| Cxx ->
let cxx = [fn ^ ".cpp"] in
if dune_version >= (1, 8) then
(fn ^ ".cxx") :: cxx
else
cxx

module Dict = struct
type 'a t =
Expand Down
12 changes: 10 additions & 2 deletions src/c.mli
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ module Kind : sig

val pp : t Fmt.t

val split_extension : string -> (string * t) option
type split =
| Unrecognized
| Not_allowed_until of Syntax.Version.t
| Recognized of string * t

val split_extension
: string
-> dune_version:Syntax.Version.t
-> split

(** [possible_fns t s] returns the possible filenames given the extension-less
basenames [s] *)
val possible_fns : t -> string -> string list
val possible_fns : t -> string -> dune_version:Syntax.Version.t -> string list

module Dict : sig
type kind
Expand Down
18 changes: 13 additions & 5 deletions src/c_sources.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,18 @@ module Eval = struct
include Ordered_set_lang.Make_loc(String)(Value)
end

let load_sources ~dir ~files =
let load_sources ~dune_version ~dir ~files =
let init = C.Kind.Dict.make String.Map.empty in
String.Set.fold files ~init ~f:(fun fn acc ->
match C.Kind.split_extension fn with
| None -> acc
| Some (obj, kind) ->
match C.Kind.split_extension fn ~dune_version with
| Unrecognized -> acc
| Not_allowed_until version ->
let loc = Loc.in_dir dir in
Errors.warn loc
"Source file %s with extension %s is not allowed before version %a"
fn (Filename.extension fn) Syntax.Version.pp version;
acc
| Recognized (obj, kind) ->
let path = Path.relative dir fn in
C.Kind.Dict.update acc kind ~f:(fun v ->
String.Map.add v obj (C.Source.make ~kind ~path)
Expand Down Expand Up @@ -79,9 +85,11 @@ let make (d : _ Dir_with_dune.t)
match String.Map.find c_sources s with
| Some source -> (loc, source)
| None ->
let dune_version = d.dune_version in
Errors.fail loc "%s does not exist as a C source. \
%s must be present"
s (String.enumerate_one_of (C.Kind.possible_fns kind s))
s (String.enumerate_one_of
(C.Kind.possible_fns kind s ~dune_version))
)
in
let names =
Expand Down
3 changes: 2 additions & 1 deletion src/c_sources.mli
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ val for_lib : t -> dir:Path.t -> name:Lib_name.t -> C.Sources.t
map. The first level will is keyed by C vs. C++ sources. The second level is
keyed by the object name of the source. *)
val load_sources
: dir:Path.t
: dune_version:Syntax.Version.t
-> dir:Path.t
-> files:String.Set.t
-> C.Source.t String.Map.t C.Kind.Dict.t

Expand Down
8 changes: 6 additions & 2 deletions src/dir_contents.ml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ let load_text_files sctx ft_dir
; scope = _
; data = stanzas
; kind = _
; dune_version = _
} =
(* Interpret a few stanzas in order to determine the list of
files generated by the user. *)
Expand Down Expand Up @@ -355,8 +356,10 @@ let rec get sctx ~dir =
~modules:(modules_of_files ~dir:d.ctx_dir ~files))
; mlds = lazy (build_mlds_map d ~files)
; c_sources = lazy (
let dune_version = d.dune_version in
C_sources.make d
~c_sources:(C_sources.load_sources ~dir:d.ctx_dir ~files))
~c_sources:(C_sources.load_sources ~dune_version ~dir:d.ctx_dir
~files))
}
| Some (_, None)
| None ->
Expand Down Expand Up @@ -422,11 +425,12 @@ let rec get sctx ~dir =
Modules.make d ~modules)
in
let c_sources = lazy (
let dune_version = d.dune_version in
let init = C.Kind.Dict.make String.Map.empty in
let c_sources =
List.fold_left ((dir, files) :: subdirs) ~init
~f:(fun acc (dir, files) ->
let sources = C_sources.load_sources ~dir ~files in
let sources = C_sources.load_sources ~dir ~dune_version ~files in
let f acc sources =
String.Map.union acc sources ~f:(fun name x y ->
Errors.fail (Loc.in_file
Expand Down
11 changes: 6 additions & 5 deletions src/dir_with_dune.ml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
open Stdune

type 'data t =
{ src_dir : Path.t
; ctx_dir : Path.t
; data : 'data
; scope : Scope.t
; kind : Dune_lang.Syntax.t
{ src_dir : Path.t
; ctx_dir : Path.t
; data : 'data
; scope : Scope.t
; kind : Dune_lang.Syntax.t
; dune_version : Syntax.Version.t
}
11 changes: 6 additions & 5 deletions src/dir_with_dune.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ open Stdune

(** A directory with a [dune] file *)
type 'data t =
{ src_dir : Path.t
; ctx_dir : Path.t (** [_build/context-name/src_dir] *)
; data : 'data
; scope : Scope.t
; kind : Dune_lang.Syntax.t
{ src_dir : Path.t
; ctx_dir : Path.t (** [_build/context-name/src_dir] *)
; data : 'data
; scope : Scope.t
; kind : Dune_lang.Syntax.t
; dune_version : Syntax.Version.t
}
12 changes: 10 additions & 2 deletions src/dune_project.ml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ type t =
; extension_args : Univ_map.t
; parsing_context : Univ_map.t
; implicit_transitive_deps : bool
; dune_version : Syntax.Version.t
}

let packages t = t.packages
Expand All @@ -177,7 +178,7 @@ let implicit_transitive_deps t = t.implicit_transitive_deps

let pp fmt { name ; root ; version ; project_file ; parsing_context = _
; extension_args = _; stanza_parser = _ ; packages
; implicit_transitive_deps } =
; implicit_transitive_deps ; dune_version } =
Fmt.record fmt
[ "name", Fmt.const Name.pp name
; "root", Fmt.const Path.Local.pp root
Expand All @@ -189,6 +190,7 @@ let pp fmt { name ; root ; version ; project_file ; parsing_context = _
(Package.Name.Map.to_list packages)
; "implicit_transitive_deps",
Fmt.const Format.pp_print_bool implicit_transitive_deps
; "dune_version", Fmt.const Syntax.Version.pp dune_version
]

let find_extension_args t key =
Expand Down Expand Up @@ -422,14 +424,15 @@ let key =
Univ_map.Key.create ~name:"dune-project"
(fun { name; root; version; project_file
; stanza_parser = _; packages = _ ; extension_args = _
; parsing_context ; implicit_transitive_deps } ->
; parsing_context ; implicit_transitive_deps ; dune_version } ->
Sexp.Encoder.record
[ "name", Name.to_sexp name
; "root", Path.Local.to_sexp root
; "version", Sexp.Encoder.(option string) version
; "project_file", Project_file.to_sexp project_file
; "parsing_context", Univ_map.to_sexp parsing_context
; "implicit_transitive_deps", Sexp.Encoder.bool implicit_transitive_deps
; "dune_version", Syntax.Version.to_sexp dune_version
])

let set t = Dune_lang.Decoder.set key t
Expand Down Expand Up @@ -469,6 +472,7 @@ let anonymous = lazy (
; project_file
; extension_args
; parsing_context
; dune_version = lang.version
})

let default_name ~dir ~packages =
Expand Down Expand Up @@ -537,6 +541,7 @@ let parse ~dir ~lang ~packages ~file =
; extension_args
; parsing_context
; implicit_transitive_deps
; dune_version = lang.version
})

let load_dune_project ~dir packages =
Expand Down Expand Up @@ -565,6 +570,7 @@ let make_jbuilder_project ~dir packages =
; extension_args
; parsing_context
; implicit_transitive_deps = true
; dune_version = lang.version
}

let read_name file =
Expand Down Expand Up @@ -603,5 +609,7 @@ let load ~dir ~files =
else
None

let dune_version t = t.dune_version

let set_parsing_context t parser =
Dune_lang.Decoder.set_many t.parsing_context parser
2 changes: 2 additions & 0 deletions src/dune_project.mli
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,6 @@ val set_parsing_context : t -> 'a Dune_lang.Decoder.t -> 'a Dune_lang.Decoder.t

val implicit_transitive_deps : t -> bool

val dune_version : t -> Syntax.Version.t

val pp : t Fmt.t
2 changes: 1 addition & 1 deletion src/gen_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module Gen(P : Install_rules.Params) = struct

let gen_rules dir_contents cctxs
{ Dir_with_dune. src_dir; ctx_dir; data = stanzas
; scope; kind = dir_kind } =
; scope; kind = dir_kind ; dune_version = _ } =
let expander = Super_context.expander sctx ~dir:ctx_dir in
let for_stanza stanza =
let dir = ctx_dir in
Expand Down
2 changes: 2 additions & 0 deletions src/install_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ module Gen(P : Params) = struct
~f:(fun ({ Dir_with_dune.
data =
{ Dune_file.Install_conf. section; files; package = _ }
; dune_version = _
; ctx_dir = dir
; src_dir = _
; scope = _
Expand Down Expand Up @@ -380,6 +381,7 @@ module Gen(P : Params) = struct
; ctx_dir = dir
; src_dir = _
; kind = dir_kind
; dune_version = _
} ->
let sub_dir = (Option.value_exn lib.public).sub_dir in
let dir_contents = Dir_contents.get sctx ~dir in
Expand Down
4 changes: 2 additions & 2 deletions src/local_package.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ let is_odig_doc_file fn =
let add_stanzas t ~sctx =
List.fold_left ~init:t
~f:(fun t ({ Dir_with_dune. ctx_dir = dir ; scope = _ ; data
; src_dir = _ ; kind = _} as d) ->
; src_dir = _ ; kind = _; dune_version = _ } as d) ->
let expander = Super_context.expander sctx ~dir in
let path_expander sw =
(String_with_vars.loc sw, Expander.expand_str expander sw) in
Expand All @@ -45,7 +45,7 @@ let stanzas_to_consider_for_install stanzas ~external_lib_deps_mode =
if not external_lib_deps_mode then
List.concat_map stanzas
~f:(fun ({ Dir_with_dune.ctx_dir = _; data = stanzas
; scope; kind = _ ; src_dir = _ } as d) ->
; scope; kind = _ ; src_dir = _ ; dune_version = _ } as d) ->
List.filter_map stanzas ~f:(fun stanza ->
let keep =
match (stanza : Stanza.t) with
Expand Down
2 changes: 1 addition & 1 deletion src/stanza.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ end
let syntax =
Syntax.create ~name:"dune" ~desc:"the dune language"
[ (0, 0) (* Jbuild syntax *)
; (1, 7)
; (1, 8)
]

module File_kind = struct
Expand Down
2 changes: 2 additions & 0 deletions src/super_context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,14 @@ let create
List.map stanzas
~f:(fun { Dune_load.Dune_file. dir; project; stanzas; kind } ->
let ctx_dir = Path.append context.build_dir dir in
let dune_version = Dune_project.dune_version project in
{ Dir_with_dune.
src_dir = dir
; ctx_dir
; data = stanzas
; scope = Scope.DB.find_by_name scopes (Dune_project.name project)
; kind
; dune_version
})
in
let stanzas_per_dir =
Expand Down
10 changes: 10 additions & 0 deletions test/blackbox-tests/dune.inc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@
test-cases/custom-build-dir
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))

(alias
(name cxx-extension)
(deps (package dune) (source_tree test-cases/cxx-extension))
(action
(chdir
test-cases/cxx-extension
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))

(alias
(name default-targets)
(deps (package dune) (source_tree test-cases/default-targets))
Expand Down Expand Up @@ -1277,6 +1285,7 @@
(alias copy_files)
(alias cross-compilation)
(alias custom-build-dir)
(alias cxx-extension)
(alias default-targets)
(alias dep-vars)
(alias depend-on-the-universe)
Expand Down Expand Up @@ -1433,6 +1442,7 @@
(alias copy_files)
(alias cross-compilation)
(alias custom-build-dir)
(alias cxx-extension)
(alias default-targets)
(alias dep-vars)
(alias depend-on-the-universe)
Expand Down
7 changes: 7 additions & 0 deletions test/blackbox-tests/test-cases/cxx-extension/bar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdio.h>
#include "foo.cxx"

void foo () {
int n = cppfoo();
printf("n = %d\n", n);
}
1 change: 1 addition & 0 deletions test/blackbox-tests/test-cases/cxx-extension/bar.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Foo.foo ()
14 changes: 14 additions & 0 deletions test/blackbox-tests/test-cases/cxx-extension/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(library
(name foo)
(cxx_names foo)
(c_names bar)
(modules foo))

(executable
(name bar)
(libraries foo)
(modules bar))

(alias
(name default)
(action (run ./bar.exe)))
1 change: 1 addition & 0 deletions test/blackbox-tests/test-cases/cxx-extension/dune-project
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(lang dune 1.8)
Loading