Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactor ocamlbuild build plugin to have some features in doc plugin.

- ExtraArgs, PluginTags are now available for ocamlbuild doc plugin
- '-use-ocamlfind' is set for doc and build plugin.
  • Loading branch information...
commit f2bb1c48372de57f1bb5b4cccb60441fc5d8b469 1 parent 83981cc
@gildor478 gildor478 authored
View
2  Makefile
@@ -117,7 +117,7 @@ PRECOMMIT_ARGS= \
--exclude _tags
precommit:
- @if command -v OCamlPrecommit > /dev/null; then \
+ -@if command -v OCamlPrecommit > /dev/null; then \
OCamlPrecommit $(PRECOMMIT_ARGS); \
else \
echo "Skipping precommit checks.";\
View
1  _tags
@@ -222,6 +222,7 @@
"src/plugins/ocamlbuild/OCamlbuildPlugin.ml": syntax_camlp4o, pkg_odn.with.syntax
"src/plugins/ocamlbuild/OCamlbuildPlugin.ml": use_ocamlbuild
"src/plugins/ocamlbuild/OCamlbuildDocPlugin.ml": syntax_camlp4o, pkg_odn.with.syntax
+"src/plugins/ocamlbuild/OCamlbuildCommon.ml": syntax_camlp4o, pkg_odn.with.syntax
# TODO: The fact that we need to remove these tags is maybe a bug
<test/test.byte>: -use_base
View
92 src/plugins/ocamlbuild/OCamlbuildCommon.ml
@@ -28,10 +28,15 @@
open OASISGettext
open BaseEnv
open BaseStandardVar
+open OASISTypes
+
+
+TYPE_CONV_PATH "OCamlbuildCommon"
+
+type extra_args = string list with odn
-let ocamlbuild_clean_ev =
- "ocamlbuild-clean"
+let ocamlbuild_clean_ev = "ocamlbuild-clean"
let ocamlbuildflags =
@@ -128,9 +133,7 @@ let build_dir extra_argv =
(* END EXPORT *)
-
-open OASISTypes
-
+open OASISValues
let fix_build_tools tool pkg =
let fix_build_tools' sct bs =
@@ -175,3 +178,82 @@ struct
let filename_concat fn1 fn2 =
OASISUnixPath.concat (OASISUnixPath.reduce fn1) fn2
end
+
+(** Check OCaml version constraint defined in _oasis. *)
+let check_ocaml_version version pkg =
+ match pkg.ocaml_version with
+ | Some ocaml_version ->
+ let min_ocaml_version = OASISVersion.version_of_string version in
+ OASISVersion.comparator_ge min_ocaml_version ocaml_version
+ | None ->
+ false
+
+
+let ocamlbuild_more_args =
+ OASISFeatures.create "ocamlbuild_more_args"
+ OASISFeatures.alpha
+ (fun () ->
+ s_ "Allow to pass arguments to ocamlbuild.")
+
+
+let ocamlbuild_supports_ocamlfind = check_ocaml_version "3.12.1"
+let ocamlbuild_supports_plugin_tags = check_ocaml_version "4.01"
+
+
+type ocamlbuild_common =
+ {
+ plugin_tags: string option;
+ extra_args: string list;
+ } with odn
+
+
+let ocamlbuild_common_generator pivot_data schm id =
+ let new_field nm = OASISSchema.new_field schm id nm in
+ let plugin_tags =
+ new_field
+ "PluginTags"
+ ~default:None
+ ~feature:ocamlbuild_more_args
+ (opt string_not_empty)
+ (fun () -> s_ "Gives the plugin tags to ocambuild through \
+ '-plugin-tags' (OCaml >= 4.01 only)")
+ pivot_data (fun _ t -> t.plugin_tags)
+ in
+ let extra_args =
+ new_field
+ "ExtraArgs"
+ ~default:[]
+ ~feature:ocamlbuild_more_args
+ command_line_options
+ (fun () -> s_ "Gives extra arguments to ocamlbuild")
+ pivot_data (fun _ t -> t.extra_args)
+ in
+ fun data ->
+ {
+ extra_args = extra_args data;
+ plugin_tags = plugin_tags data;
+ }
+
+
+let extra_args_ocamlbuild_common ~ctxt pkg t =
+ let extra_args =
+ if t.plugin_tags <> None &&
+ not (ocamlbuild_supports_plugin_tags pkg) then begin
+ OASISMessage.error
+ ~ctxt:ctxt
+ (f_ "'XOCamlbuildPluginTags' in only available for OCaml >= 4.01. \
+ Please restrict your requirements with 'OCamlVersion: >= 4.01'");
+ t.extra_args
+ end else begin
+ match t.plugin_tags with
+ | Some tags -> "-plugin-tags" :: ("'" ^ tags ^ "'") :: t.extra_args
+ | None -> t.extra_args
+ end
+ in
+ let extra_args =
+ if ocamlbuild_supports_ocamlfind pkg then
+ "-use-ocamlfind" :: extra_args
+ else
+ extra_args
+ in
+ extra_args
View
185 src/plugins/ocamlbuild/OCamlbuildDocPlugin.ml
@@ -35,12 +35,18 @@ open BaseStandardVar
TYPE_CONV_PATH "OCamlbuildDocPlugin"
+type run_t =
+ {
+ extra_args: string list;
+ run_path: unix_filename;
+ } with odn
-let doc_build path pkg (cs, doc) argv =
+
+let doc_build run pkg (cs, doc) argv =
let index_html =
OASISUnixPath.make
[
- path;
+ run.run_path;
cs.cs_name^".docdir";
"index.html";
]
@@ -49,11 +55,11 @@ let doc_build path pkg (cs, doc) argv =
OASISHostPath.make
[
build_dir argv;
- OASISHostPath.of_unix path;
+ OASISHostPath.of_unix run.run_path;
cs.cs_name^".docdir";
]
in
- run_ocamlbuild [index_html] argv;
+ run_ocamlbuild (index_html :: run.extra_args) argv;
List.iter
(fun glb ->
BaseBuilt.register
@@ -64,7 +70,7 @@ let doc_build path pkg (cs, doc) argv =
["*.html"; "*.css"]
-let doc_clean t pkg (cs, doc) argv =
+let doc_clean run pkg (cs, doc) argv =
run_clean argv;
BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name
@@ -92,11 +98,12 @@ type t =
libraries: findlib_full list;
intro: unix_filename option;
flags: string list;
+ common: ocamlbuild_common;
}
-let pivot_data =
- data_new_property plugin
+let pivot_data = data_new_property plugin
+let pivot_sub_data = data_new_property plugin
let self_id, all_id =
@@ -167,75 +174,89 @@ let flags =
(* TODO: use -t for title *)
-let doit ctxt pkg (cs, doc) =
-
- let path =
- path cs.cs_data
+let generator =
+ let generator_common =
+ (* Register fields. *)
+ ocamlbuild_common_generator pivot_sub_data OASISDocument.schema all_id
in
+ fun data pkg ->
+ let path = path data in
+
+ let modules_from_libraries =
+ (* Convert findlib name to internal library and compute
+ * the module they shipped.
+ *)
+ let lib_of_findlib =
+ let _, _, library_name_of_findlib_name =
+ OASISFindlib.findlib_mapping pkg
+ in
+ let lib_of_name =
+ List.fold_left
+ (fun mp ->
+ function
+ | Library ({cs_name = name}, bs, lib) ->
+ MapString.add name (bs, lib) mp
+ | _ ->
+ mp)
+ MapString.empty
+ pkg.sections
+ in
+ fun fndlb_nm ->
+ let nm =
+ library_name_of_findlib_name fndlb_nm
+ in
+ MapString.find nm lib_of_name
+ in
+
+ (* Fetch modules from internal libraries *)
+ List.flatten
+ (List.map
+ (fun fndlb_nm ->
+ let bs, lib =
+ lib_of_findlib fndlb_nm
+ in
+ (* Rebase modules in the doc path *)
+ List.map
+ (fun modul ->
+ OASISUnixPath.make_relative
+ path
+ (OASISUnixPath.concat bs.bs_path modul))
+ lib.lib_modules)
+
+ (libraries data))
+ in
- let modules_from_libraries =
- (* Convert findlib name to internal library and compute
- * the module they shipped.
- *)
- let lib_of_findlib =
- let _, _, library_name_of_findlib_name =
- OASISFindlib.findlib_mapping pkg
+ let modules_from_doc =
+ (* Fetch modules defined directly *)
+ modules data
in
- let lib_of_name =
- List.fold_left
- (fun mp ->
- function
- | Library ({cs_name = name}, bs, lib) ->
- MapString.add name (bs, lib) mp
- | _ ->
- mp)
- MapString.empty
- pkg.sections
+
+ let modules =
+ modules_from_libraries @ modules_from_doc
in
- fun fndlb_nm ->
- let nm =
- library_name_of_findlib_name fndlb_nm
- in
- MapString.find nm lib_of_name
- in
-
- (* Fetch modules from internal libraries *)
- List.flatten
- (List.map
- (fun fndlb_nm ->
- let bs, lib =
- lib_of_findlib fndlb_nm
- in
- (* Rebase modules in the doc path *)
- List.map
- (fun modul ->
- OASISUnixPath.make_relative
- path
- (OASISUnixPath.concat bs.bs_path modul))
- lib.lib_modules)
-
- (libraries cs.cs_data))
- in
+ {
+ path = path;
+ modules = modules;
+ libraries = libraries data;
+ intro = None;
+ flags = [];
+ common = generator_common data;
+ }
- let modules_from_doc =
- (* Fetch modules defined directly *)
- modules cs.cs_data
- in
- let modules =
- modules_from_libraries @ modules_from_doc
- in
+let doit ctxt pkg (cs, doc) =
+ let t = generator cs.cs_data pkg in
let ctxt =
(* Create .odocl file *)
add_file
(template_make
(OASISHostPath.add_extension
- (Filename.concat path cs.cs_name)
+ (Filename.concat t.path cs.cs_name)
"odocl")
comment_ocamlbuild
[]
- modules
+ t.modules
[])
ctxt
in
@@ -260,32 +281,38 @@ let doit ctxt pkg (cs, doc) =
cs.cs_name);
set_error
- (modules = [])
+ (t.modules = [])
(Printf.sprintf
(f_ "No module defined for document %s.")
cs.cs_name);
]
in
- ctxt,
+ let run =
{
- chng_moduls =
- [OCamlbuildData.ocamlbuildsys_ml];
-
- chng_main =
- ODNFunc.func_with_arg
- doc_build "OCamlbuildDocPlugin.doc_build"
- path ODN.of_string;
-
- chng_clean =
- Some
- (ODNFunc.func_with_arg
- doc_clean "OCamlbuildDocPlugin.doc_clean"
- path ODN.of_string);
-
- chng_distclean =
- None;
+ run_path = t.path;
+ extra_args = extra_args_ocamlbuild_common ~ctxt:ctxt.ctxt pkg t.common;
}
+ in
+ ctxt,
+ {
+ chng_moduls =
+ [OCamlbuildData.ocamlbuildsys_ml];
+
+ chng_main =
+ ODNFunc.func_with_arg
+ doc_build "OCamlbuildDocPlugin.doc_build"
+ run odn_of_run_t;
+
+ chng_clean =
+ Some
+ (ODNFunc.func_with_arg
+ doc_clean "OCamlbuildDocPlugin.doc_clean"
+ run odn_of_run_t);
+
+ chng_distclean =
+ None;
+ }
let qstrt_completion pkg =
View
114 src/plugins/ocamlbuild/OCamlbuildPlugin.ml
@@ -43,27 +43,7 @@ let cond_targets_hook =
ref (fun lst -> lst)
-type ocamlbuild_plugin =
- {
- plugin_tags: string option;
- extra_args: string list;
- } with odn
-
-
-let check_ocaml_version version pkg =
- match pkg.ocaml_version with
- | Some ocaml_version ->
- let min_ocaml_version = OASISVersion.version_of_string version in
- OASISVersion.comparator_ge min_ocaml_version ocaml_version
- | None ->
- false
-
-
-let ocamlbuild_supports_ocamlfind = check_ocaml_version "3.12.1"
-let ocamlbuild_supports_plugin_tags = check_ocaml_version "4.01"
-
-
-let build t pkg argv =
+let build extra_args pkg argv =
(* Return the filename in build directory *)
let in_build_dir fn =
Filename.concat
@@ -207,33 +187,13 @@ let build t pkg argv =
(BaseBuilt.register bt bnm lst)
in
- let cond_targets =
- (* Run the hook *)
- !cond_targets_hook cond_targets
- in
-
- let extra_args =
- match t.plugin_tags with
- | Some tags -> "-plugin-tags" :: ("'" ^ tags ^ "'") :: t.extra_args
- | None -> t.extra_args
- in
- let extra_args =
- if ocamlbuild_supports_ocamlfind pkg then
- "-use-ocamlfind" :: extra_args
- else
- extra_args
- in
+ (* Run the hook *)
+ let cond_targets = !cond_targets_hook cond_targets in
- (* Run a list of target... *)
- run_ocamlbuild
- (List.flatten
- (List.map snd cond_targets)
- @ extra_args)
- argv;
- (* ... and register events *)
- List.iter
- check_and_register
- (List.flatten (List.map fst cond_targets))
+ (* Run a list of target... *)
+ run_ocamlbuild (List.flatten (List.map snd cond_targets) @ extra_args) argv;
+ (* ... and register events *)
+ List.iter check_and_register (List.flatten (List.map fst cond_targets))
let clean pkg extra_args =
@@ -260,7 +220,6 @@ open OASISGettext
open ODN
open OASISPlugin
open OASISTypes
-open OASISValues
open OASISSchema
open MyOCamlbuildBase
open Ocamlbuild_plugin
@@ -283,13 +242,6 @@ let pure_interface_test =
s_ "Allow to have module with only .mli file."))
-let ocamlbuild_more_args =
- OASISFeatures.create "ocamlbuild_more_args" ~plugin
- OASISFeatures.alpha
- (fun () ->
- s_ "Allow to pass arguments to ocamlbuild.")
-
-
let pivot_data =
data_new_property plugin
@@ -898,7 +850,7 @@ let add_ocamlbuild_files ctxt pkg =
[])
ctxt
in
- if lib.lib_pack then
+ if lib.lib_pack then begin
(* generate .mlpack for packed libraries *)
add_file
(template_make
@@ -908,9 +860,9 @@ let add_ocamlbuild_files ctxt pkg =
impl_module_list
[])
ctxt
- else {
+ end else begin
(* make sure there is no conflicting mlpack file *)
- ctxt with
+ {ctxt with
other_actions =
(fun ()->
if OASISFileUtil.file_exists_case mlpack then
@@ -918,8 +870,8 @@ let add_ocamlbuild_files ctxt pkg =
(f_ "Conflicting file '%s' and '%s' \
exists, remove '%s'.")
mllib mlpack mlpack)
- :: ctxt.other_actions
- }
+ :: ctxt.other_actions}
+ end
in
ctxt, tag_t, myocamlbuild_t
end
@@ -1174,48 +1126,20 @@ let add_ocamlbuild_files ctxt pkg =
let generator =
- let new_field nm = new_field OASISPackage.schema all_id nm in
- let plugin_tags =
- new_field
- "PluginTags"
- ~default:None
- ~feature:ocamlbuild_more_args
- (opt string_not_empty)
- (fun () -> s_ "Gives the plugin tags to ocambuild through \
- '-plugin-tags' (OCaml >= 4.01 only)")
- pivot_data (fun _ t -> t.plugin_tags)
- in
- let extra_args =
- new_field
- "ExtraArgs"
- ~default:[]
- ~feature:ocamlbuild_more_args
- command_line_options
- (fun () -> s_ "Gives extra arguments to ocamlbuild")
- pivot_data (fun _ t -> t.extra_args)
- in
- fun data ->
- {
- extra_args = extra_args data;
- plugin_tags = plugin_tags data;
- }
-
+ ocamlbuild_common_generator pivot_data OASISPackage.schema all_id
let doit ctxt pkg =
- let t = generator pkg.schema_data in
+ let extra_args =
+ extra_args_ocamlbuild_common ~ctxt:ctxt.ctxt pkg
+ (generator pkg.schema_data)
+ in
let ctxt = add_ocamlbuild_files ctxt pkg in
-
- if t.plugin_tags <> None && not (ocamlbuild_supports_plugin_tags pkg) then
- OASISMessage.warning
- ~ctxt:ctxt.ctxt
- (f_ "'XOCamlbuildPluginTags' in only available for OCaml >= 4.01. \
- Please restrict your requirements with 'OCamlVersion: >= 4.01'");
-
ctxt,
{
chng_moduls = [OCamlbuildData.ocamlbuildsys_ml];
chng_main = ODNFunc.func_with_arg build
- "OCamlbuildPlugin.build" t odn_of_ocamlbuild_plugin;
+ "OCamlbuildPlugin.build"
+ extra_args odn_of_extra_args;
chng_clean = Some (ODNFunc.func clean "OCamlbuildPlugin.clean");
chng_distclean = None;
}
View
48 test/TestCommon.ml
@@ -117,21 +117,46 @@ module DiffListOutput = OUnitDiff.ListSimpleMake (Output)
(* Assert checking that command run well *)
-let assert_command ~ctxt ?chdir ?exit_code ?output ?extra_env ?(unorder=false)
+let assert_command ~ctxt
+ ?chdir
+ ?exit_code
+ ?output
+ ?extra_env
+ ?(unorder=false)
+ (* TODO: this should be true, but too many errors: fix this. *)
+ ?(check_output=false)
cmd args =
let foutput =
+ let read_check_output strm =
+ let output =
+ let buff =
+ Buffer.create 13
+ in
+ Stream.iter (Buffer.add_char buff) strm;
+ Buffer.contents buff
+ in
+ let lines = OASISString.nsplit output '\n' in
+ (* Check for warnings/errors. *)
+ if check_output then
+ List.iter
+ (fun line ->
+ non_fatal ctxt
+ (fun test_ctxt ->
+ List.iter
+ (fun (what, fmt) ->
+ if OASISString.starts_with ~what line then
+ assert_failure (Printf.sprintf fmt line))
+ ["E:", ""^^"Error in line %S";
+ "W:", ""^^"Warning in line %S";
+ "Warning", ""^^"Warning in line %S"]))
+ lines;
+ lines
+ in
match output with
| Some exp_output ->
let foutput strm =
- let output =
- let buff =
- Buffer.create 13
- in
- Stream.iter (Buffer.add_char buff) strm;
- Buffer.contents buff
- in
+ let rel_output = read_check_output strm in
let exp_output = OASISString.nsplit exp_output '\n' in
- let rel_output = OASISString.nsplit output '\n' in
let assert_equal_diff ~msg t1 t2 =
if unorder then
@@ -154,7 +179,10 @@ let assert_command ~ctxt ?chdir ?exit_code ?output ?extra_env ?(unorder=false)
Some foutput
| None ->
- None
+ Some
+ (fun strm ->
+ let _lst: string list = read_check_output strm in
+ ())
in
let env =
let readd lst nm =
View
30 test/TestFullUtils.ml
@@ -322,6 +322,7 @@ let assert_command_with_ocaml_env
?(extra_env=[])
?exit_code
?chdir
+ ?check_output
test_ctxt t cmd args =
(* Libraries located inside the test directory *)
let local_lib_paths =
@@ -374,6 +375,7 @@ let assert_command_with_ocaml_env
~ctxt:test_ctxt
?exit_code
?chdir
+ ?check_output
~extra_env:((add_path "OCAMLPATH" t.ocaml_lib_dir)
::
(List.map
@@ -388,6 +390,7 @@ let assert_command_with_ocaml_env
let run_ocaml_setup_ml
?(with_ocaml_env=false)
?exit_code
+ ?check_output
?(extra_env=[])
test_ctxt t args =
(* Speed up for testing, compile setup.ml *)
@@ -408,11 +411,11 @@ let run_ocaml_setup_ml
"ocaml", ((in_src_dir t setup_ml) :: "-info" :: "-debug" :: args)
in
if with_ocaml_env then
- assert_command_with_ocaml_env ?exit_code ~extra_env ~chdir:t.src_dir
- test_ctxt t cmd args
+ assert_command_with_ocaml_env ?exit_code ?check_output ~extra_env
+ ~chdir:t.src_dir test_ctxt t cmd args
else
- assert_command ~ctxt:test_ctxt ?exit_code ~extra_env ~chdir:t.src_dir
- cmd args;
+ assert_command ~ctxt:test_ctxt ?exit_code ?check_output ~extra_env
+ ~chdir:t.src_dir cmd args;
timer_stop test_ctxt timer
@@ -725,6 +728,25 @@ let check_tags test_ctxt t =
(* Run oasis setup and fix generated files accordingly. *)
let oasis_setup ?(dev=false) ?(dynamic=false) test_ctxt t =
+ let () =
+ let pkg =
+ OASISParse.from_file
+ ~ctxt:oasis_ctxt
+ (in_src_dir t OASISParse.default_oasis_fn)
+ in
+ match pkg.OASISTypes.ocaml_version with
+ | Some ver_cmp ->
+ skip_if
+ (not
+ (OASISVersion.comparator_apply
+ (OASISVersion.version_of_string t.ocaml_version)
+ ver_cmp))
+ (Printf.sprintf
+ "Need ocaml version %s."
+ (OASISVersion.string_of_comparator ver_cmp))
+ | None ->
+ ()
+ in
let timer = timer_start "oasis_setup" in
(* Create build system using OASIS *)
assert_oasis_cli
View
16 test/TestOCamlbuild.ml
@@ -98,6 +98,22 @@ let tests =
line fake_ocamlfind)
(OASISString.starts_with ~what:fake_ocamlfind line))
(OASISString.nsplit build_log '\n'));
+
+ "use-ocamlfind" >::
+ (fun test_ctxt ->
+ let t =
+ setup_test_directories test_ctxt
+ ~is_native:(is_native test_ctxt)
+ ~native_dynlink:(native_dynlink test_ctxt)
+ (in_testdata_dir test_ctxt ["TestOCamlbuild"; "use-ocamlfind"])
+ in
+ oasis_setup test_ctxt t;
+ run_ocaml_setup_ml ~check_output:true test_ctxt t
+ ["-configure"; "--enable-docs"];
+ run_ocaml_setup_ml ~check_output:true test_ctxt t
+ ["-build"];
+ run_ocaml_setup_ml ~check_output:true test_ctxt t
+ ["-doc"]);
]
View
7 test/data/TestOCamlbuild/set-ocamlfind/_oasis
@@ -1,11 +1,10 @@
-OASISFormat: 0.1
-Name: dev
+OASISFormat: 0.4
+Name: set-ocamlfind
Version: 0.0.1
Authors: Sylvain Le Gall
LicenseFile: LICENSE
License: LGPL with OCaml linking exception
-Synopsis: Minimal project for dev support.
-Plugins: META
+Synopsis: Minimal project.
BuildTools: ocamlbuild
Executable "myexec"
View
0  test/data/TestOCamlbuild/use-ocamlfind/A.ml
No changes.
View
21 test/data/TestOCamlbuild/use-ocamlfind/_oasis
@@ -0,0 +1,21 @@
+OASISFormat: 0.4
+OCamlVersion: >= 3.12.1
+Name: use-ocamlfind
+Version: 0.0.1
+Authors: Sylvain Le Gall
+LicenseFile: LICENSE
+License: LGPL with OCaml linking exception
+Synopsis: Minimal project.
+BuildTools: ocamlbuild
+
+Library foo
+ Path: .
+ Modules: A
+ BuildDepends: oUnit
+
+Document api
+ Title: API reference for foo
+ Type: ocamlbuild (0.4)
+ BuildTools+: ocamldoc
+ XOCamlbuildPath: .
+ XOCamlbuildLibraries: foo
Please sign in to comment.
Something went wrong with that request. Please try again.