Permalink
Browse files

Merge pull request #13 from paurkedal/InterfaceModules-3

Support pure interface modules in libraries.
  • Loading branch information...
2 parents 0cef1db + a3743ea commit 63678bdc6113a5543bee63837d52c011e8ddd625 @gildor478 gildor478 committed Mar 23, 2013
@@ -0,0 +1,12 @@
+OASISFormat: 0.3
+Name: pimlib
+Version: 0.1
+Synopsis: Library with pure interface modules in subdirectory
+Authors: Petter A. Urkedal
+License: GPL
+Plugins: META (0.3)
+
+Library pimlib
+ Path: src
+ BuildTools: ocamlbuild
+ Modules: Pim_intf, Pim_impl, Pim_types
@@ -0,0 +1,12 @@
+OASISFormat: 0.3
+Name: pimlib
+Version: 0.1
+Synopsis: Library with pure interface modules in top source directory
+Authors: Petter A. Urkedal
+License: GPL
+Plugins: META (0.3)
+
+Library pimlib
+ Path: .
+ BuildTools: ocamlbuild
+ Modules: Pim_intf, Pim_impl, Pim_types
@@ -0,0 +1,24 @@
+(******************************************************************************)
+(* OASIS: architecture for building OCaml libraries and applications *)
+(* *)
+(* Copyright (C) 2008-2010, OCamlCore SARL *)
+(* *)
+(* This library is free software; you can redistribute it and/or modify it *)
+(* under the terms of the GNU Lesser General Public License as published by *)
+(* the Free Software Foundation; either version 2.1 of the License, or (at *)
+(* your option) any later version, with the OCaml static compilation *)
+(* exception. *)
+(* *)
+(* This library is distributed in the hope that it will be useful, but *)
+(* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *)
+(* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *)
+(* details. *)
+(* *)
+(* You should have received a copy of the GNU Lesser General Public License *)
+(* along with this library; if not, write to the Free Software Foundation, *)
+(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)
+(******************************************************************************)
+
+type t = string
+let create s = s
+let value s = s
@@ -0,0 +1,22 @@
+(******************************************************************************)
+(* OASIS: architecture for building OCaml libraries and applications *)
+(* *)
+(* Copyright (C) 2008-2010, OCamlCore SARL *)
+(* *)
+(* This library is free software; you can redistribute it and/or modify it *)
+(* under the terms of the GNU Lesser General Public License as published by *)
+(* the Free Software Foundation; either version 2.1 of the License, or (at *)
+(* your option) any later version, with the OCaml static compilation *)
+(* exception. *)
+(* *)
+(* This library is distributed in the hope that it will be useful, but *)
+(* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *)
+(* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *)
+(* details. *)
+(* *)
+(* You should have received a copy of the GNU Lesser General Public License *)
+(* along with this library; if not, write to the Free Software Foundation, *)
+(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)
+(******************************************************************************)
+
+include Pim_intf.S
@@ -0,0 +1,26 @@
+(******************************************************************************)
+(* OASIS: architecture for building OCaml libraries and applications *)
+(* *)
+(* Copyright (C) 2008-2010, OCamlCore SARL *)
+(* *)
+(* This library is free software; you can redistribute it and/or modify it *)
+(* under the terms of the GNU Lesser General Public License as published by *)
+(* the Free Software Foundation; either version 2.1 of the License, or (at *)
+(* your option) any later version, with the OCaml static compilation *)
+(* exception. *)
+(* *)
+(* This library is distributed in the hope that it will be useful, but *)
+(* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *)
+(* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *)
+(* details. *)
+(* *)
+(* You should have received a copy of the GNU Lesser General Public License *)
+(* along with this library; if not, write to the Free Software Foundation, *)
+(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)
+(******************************************************************************)
+
+module type S = sig
+ type t
+ val create : string -> t
+ val value : t -> string
+end
@@ -0,0 +1,25 @@
+(******************************************************************************)
+(* OASIS: architecture for building OCaml libraries and applications *)
+(* *)
+(* Copyright (C) 2008-2010, OCamlCore SARL *)
+(* *)
+(* This library is free software; you can redistribute it and/or modify it *)
+(* under the terms of the GNU Lesser General Public License as published by *)
+(* the Free Software Foundation; either version 2.1 of the License, or (at *)
+(* your option) any later version, with the OCaml static compilation *)
+(* exception. *)
+(* *)
+(* This library is distributed in the hope that it will be useful, but *)
+(* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *)
+(* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *)
+(* details. *)
+(* *)
+(* You should have received a copy of the GNU Lesser General Public License *)
+(* along with this library; if not, write to the Free Software Foundation, *)
+(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)
+(******************************************************************************)
+
+(* This module is not referred by the library itself. The mli and cmi files
+ * should still be installed. *)
+
+type ('a, 'b) either = This of 'a | That of 'b
View
@@ -91,21 +91,26 @@ let generated_unix_files
let find_modules lst ext =
let find_module modul =
match find_module source_file_exists bs modul with
+ | `Sources (base_fn, [fn]) when ext <> "cmi"
+ && Filename.check_suffix fn ".mli" ->
+ None (* No implementation files for pure interface. *)
| `Sources (base_fn, _) ->
- [base_fn]
+ Some [base_fn]
| `No_sources lst ->
OASISMessage.warning
~ctxt
(f_ "Cannot find source file matching \
module '%s' in library %s")
modul cs.cs_name;
- lst
+ Some lst
in
- List.map
- (fun nm ->
- List.map
- (fun base_fn -> base_fn ^"."^ext)
- (find_module nm))
+ List.fold_left
+ (fun acc nm ->
+ match find_module nm with
+ | None -> acc
+ | Some base_fns ->
+ List.map (fun base_fn -> base_fn ^"."^ext) base_fns :: acc)
+ []
lst
in
@@ -56,7 +56,7 @@ let rec odn_of_spec =
type t =
{
- lib_ocaml: (name * dir list) list;
+ lib_ocaml: (name * dir list * string list) list;
lib_c: (name * dir * file list) list;
flags: (tag list * (spec OASISExpr.choices)) list;
(* Replace the 'dir: include' from _tags by a precise interdepends in
@@ -112,17 +112,26 @@ let dispatch t e =
(* Declare OCaml libraries *)
List.iter
(function
- | nm, [] ->
- ocaml_lib nm
- | nm, dir :: tl ->
+ | nm, [], intf_modules ->
+ ocaml_lib nm;
+ let cmis =
+ List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
+ intf_modules in
+ dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
+ | nm, dir :: tl, intf_modules ->
ocaml_lib ~dir:dir (dir^"/"^nm);
List.iter
(fun dir ->
List.iter
(fun str ->
flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir]))
["compile"; "infer_interface"; "doc"])
- tl)
+ tl;
+ let cmis =
+ List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
+ intf_modules in
+ dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
+ cmis)
t.lib_ocaml;
(* Declare directories dependencies, replace "include" in _tags. *)
@@ -667,6 +667,16 @@ let compute_includes map_dirs pkg =
includes
[]
+let is_pure_interface bs mn =
+ let fn_lc = prepend_bs_path bs (String.uncapitalize mn) in
+ let fn_uc = prepend_bs_path bs mn in
+ let have ext =
+ OASISFileUtil.file_exists_case
+ (OASISHostPath.add_extension fn_lc ext) ||
+ OASISFileUtil.file_exists_case
+ (OASISHostPath.add_extension fn_uc ext) in
+ not (have "ml") && have "mli"
+
let add_ocamlbuild_files ctxt pkg =
let map_dirs =
@@ -749,13 +759,19 @@ let add_ocamlbuild_files ctxt pkg =
myocamlbuild_t
in
+ let intf_module_list, impl_module_list =
+ List.partition (is_pure_interface bs)
+ (lib.lib_modules @ lib.lib_internal_modules) in
+
let myocamlbuild_t =
{myocamlbuild_t with
lib_ocaml =
(cs.cs_name,
List.filter
(fun fn -> not (OASISUnixPath.is_current fn))
- src_dirs) :: myocamlbuild_t.lib_ocaml}
+ src_dirs,
+ intf_module_list)
+ :: myocamlbuild_t.lib_ocaml}
in
let () =
@@ -771,13 +787,12 @@ let add_ocamlbuild_files ctxt pkg =
let fn_base = prepend_bs_path bs cs.cs_name in
let mllib = OASISHostPath.add_extension fn_base "mllib" in
let mlpack = OASISHostPath.add_extension fn_base "mlpack" in
- let module_list = lib.lib_modules @ lib.lib_internal_modules in
let mllib_template_lines =
(* mllib contains either the name of the pack or the list of modules*)
if lib.lib_pack then
[ String.capitalize cs.cs_name ]
else
- module_list
+ impl_module_list
in
let ctxt =
add_file
@@ -796,7 +811,7 @@ let add_ocamlbuild_files ctxt pkg =
mlpack
comment_ocamlbuild
[]
- module_list
+ impl_module_list
[])
ctxt
else {
@@ -882,7 +897,8 @@ let add_ocamlbuild_files ctxt pkg =
(cs.cs_name,
List.filter
(fun fn -> not (OASISUnixPath.is_current fn))
- src_dirs) :: myocamlbuild_t.lib_ocaml}
+ src_dirs,
+ []) :: myocamlbuild_t.lib_ocaml}
in
let () =
View
@@ -1266,6 +1266,46 @@ let tests =
try_installed_library "test" ["Test"];
]);
+ (* Library with a pure interface module in subdirectory. *)
+ "../examples/with-interface-module",
+ (fun () ->
+ long_test,
+ [
+ "src/META";
+ "src/pimlib.mllib";
+ ] @ oasis_ocamlbuild_files,
+ [
+ in_ocaml_library "pimlib"
+ ["META";
+ "pimlib.cma"; "pimlib.cmxa"; "pimlib.a"; "pimlib.cmxs";
+ "pim_impl.mli"; "pim_impl.cmi"; "pim_impl.cmx";
+ "pim_intf.mli"; "pim_intf.cmi";
+ "pim_types.mli"; "pim_types.cmi"];
+ ],
+ [
+ try_installed_library "pimlib" ["Pim_intf"; "Pim_impl"];
+ ]);
+
+ (* Library with a pure interface module in top source directory. *)
+ "../examples/with-interface-module/src",
+ (fun () ->
+ long_test,
+ [
+ "META";
+ "pimlib.mllib";
+ ] @ oasis_ocamlbuild_files,
+ [
+ in_ocaml_library "pimlib"
+ ["META";
+ "pimlib.cma"; "pimlib.cmxa"; "pimlib.a"; "pimlib.cmxs";
+ "pim_impl.mli"; "pim_impl.cmi"; "pim_impl.cmx";
+ "pim_intf.mli"; "pim_intf.cmi";
+ "pim_types.mli"; "pim_types.cmi"];
+ ],
+ [
+ try_installed_library "pimlib" ["Pim_intf"; "Pim_impl"];
+ ]);
+
(* Test executable *)
"../examples/with-test",
(fun () ->

0 comments on commit 63678bd

Please sign in to comment.