-
Notifications
You must be signed in to change notification settings - Fork 10
/
myocamlbuild.ml
313 lines (288 loc) · 9.49 KB
/
myocamlbuild.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
open Nonstd
open Solvuu_build.Std
let (//) = Filename.concat
let failwithf fmt = ksprintf failwith fmt
let project_name = "ketrew"
let version = "3.2.0+dev"
let build_tests =
try Sys.getenv "WITH_TESTS" = "true" with _ -> false
let jsoo_debug =
try Sys.getenv "JSOO_DEBUG_MODE" = "true" with _ -> false
let with_bisect =
try Sys.getenv "WITH_BISECT" = "true" with _ -> false
let with_postgresql =
Findlib.installed "postgresql"
let pure_lib_packages = [
"sosa"; "nonstd"; "docout"; "pvem"; "yojson"; "uri"; "cohttp";
"ppx_deriving_yojson"; "ppx_deriving.std"; "react"; "reactiveData";
] @ (if with_bisect then ["bisect_ppx"] else [])
(* Older versionso of Lwt build `lwt.react`, then Lwt ≥ 3.0.0 uses
`lwt_react` as a separate opam package. *)
let lwt_react =
if Findlib.installed "lwt_react"
then "lwt_react"
else "lwt.react"
let lwt_unix_lib_packages = pure_lib_packages @ [
"threads"; "pvem_lwt_unix"; "cmdliner"; "cohttp-lwt-unix"; "conduit";
"dynlink"; "findlib"; lwt_react;
]
@ (if with_postgresql then ["postgresql"] else [])
let joo_packages = pure_lib_packages @ [
"js_of_ocaml"; "js_of_ocaml-lwt"; "js_of_ocaml-ppx"; "js_of_ocaml-tyxml";
]
let ocaml_options (f : _ Project.with_options) =
f ~bin_annot:()
~short_paths:()
~g:()
~w:"+9"
~strict_sequence:()
~safe_string:()
let project_lib =
(ocaml_options Project.lib)
~build_plugin:true
let project_app =
(ocaml_options Project.app)
let meta_dot_ml = "src/pure/metadata.ml"
let generate_meta_data () =
let cmd_option cmd =
try
Some (
Ocamlbuild_pack.My_unix.run_and_read cmd
|> fun x -> String.sub x 0 (String.length x - 1)
)
with _ -> None in
let git_last_commit () = cmd_option "git rev-parse HEAD" in
let git_describe () = cmd_option "git describe --tags --long --dirty" in
let option_to_string =
Option.value_map ~default:"None" ~f:(sprintf "Some %S") in
Solvuu_build.Util.Rule.rule
~name:"meta-data-generation"
~prods:[meta_dot_ml]
~deps:[]
~insert:`bottom
begin fun env builder ->
let def name ~doc fmt =
ksprintf (fun s -> sprintf "\n(** %s *)\nlet %s = %s" doc name s) fmt in
let lines =
List.map ~f:(sprintf "%s\n") [
"(** Metadata Module Generated by the Build System *)";
def "version" ~doc:"Official version string of the current build"
"%S" version;
def "git_commit" ~doc:"Current Git commit (if avaiable at build-time)"
"%s" (git_last_commit () |> option_to_string);
def "git_description"
~doc:"Current result of [\"git describe\"] \
(if avaiable at build-time)"
"%s" (git_describe () |> option_to_string);
def "findlib_packages"
~doc:"List of find-lib packages linked in the [ketrew] binary."
"[%s]"
(List.map lwt_unix_lib_packages ~f:(sprintf "%S")
|> String.concat "; ");
def "with_postgresql"
~doc:"Whether the [ketrew.lwt_unix] (and hence the [ketrew] app) \
are linked with PostgreSQL (and hence “server”) support."
"%b" with_postgresql;
def "jsoo_debug"
~doc:"Whether the WebUI's code was build using a bunch of \
[js_of_ocaml] debug flags."
"%b" with_postgresql;
def "with_bisect"
~doc:"Whether the Ketrew was built with [bisect_ppx]."
"%b" with_bisect;
] in
let open Ocamlbuild_plugin in
Seq [
Echo (lines, meta_dot_ml);
]
end
let pure_lib : Project.item =
project_lib (project_name ^ ".pure")
~thread:()
~findlib_deps:pure_lib_packages
~ml_files:(`Add [Filename.basename meta_dot_ml])
~dir:"src/pure"
~style:(`Pack (project_name ^ "_pure" |> String.capitalize_ascii))
let js_lib : Project.item =
let name = project_name ^ ".client-joo" in
project_lib name
~install:`No
~dir:"src/client-joo/"
~internal_deps:[pure_lib]
~findlib_deps:joo_packages
~style:`Basic
let js_app : Project.item =
let name = project_name ^ "-client-joo" in
project_app name
~install:`No
~file:"src/client-joo/webapp.ml"
~internal_deps:[js_lib]
~findlib_deps:joo_packages
let cmdf fmt = ksprintf Ocamlbuild_plugin.(fun s -> Cmd (Sh s)) fmt
let gui_page = "src/lib/client_html.ml"
let make_gui_page () =
let client_dot_byte =
match js_app with
| Project.Lib _ -> assert false
| Project.App app -> Project.path_of_app ~suffix:".byte" app in
let jsoo_flags =
if jsoo_debug then "--pretty --no-inline --debug-info" else "" in
let css = "src/css/bootstrap_335_min.css" in
let template = "tools/template-gui.sh" in
let jsoo_debug_level = if jsoo_debug then 1 else 0 in
Solvuu_build.Util.Rule.rule
~name:"gui-page-generation"
~prods:[gui_page]
~deps:[client_dot_byte; template; css]
~insert:`bottom
begin fun env builder ->
let open Ocamlbuild_plugin in
Seq [
cmdf "cp ../%s style.css" css;
cmdf "js_of_ocaml %s +weak.js %s -o client.js"
jsoo_flags client_dot_byte;
cmdf "../%s \
gui-page.html client.js \
style.css '' %d" template jsoo_debug_level;
cmdf "ocamlify --var-string gui_page \
gui-page.html --output %s" gui_page;
]
end
let persistent_data_ml = "src/lib/persistent_data.ml"
let make_persistent_data () =
let src = "src/lib/persistent_data.cppo.ml" in
Solvuu_build.Util.Rule.rule
~name:"cppo-persistent-data"
~prods:[persistent_data_ml]
~deps:[src]
~insert:`top
begin fun env builder ->
let open Ocamlbuild_plugin in
Seq [
cmdf "cppo %s %s > %s"
(if with_postgresql then "-D WITH_POSTGRESQL=true" else "")
src persistent_data_ml;
]
end
let lwt_unix_lib : Project.item =
let dir = "src/lib" in
let ml_files = (* We need to override the files to remove the ".cppo.ml" *)
let all_files = try Sys.readdir dir |> Array.to_list with _ -> [] in
[
Filename.basename gui_page;
Filename.basename persistent_data_ml;
] @ List.filter all_files
~f:(fun f ->
not (Filename.check_suffix f ".mli")
&& not (Filename.check_suffix f ".cppo.ml"))
in
project_lib project_name
~thread:()
~findlib_deps:lwt_unix_lib_packages
~ml_files:(`Replace ml_files)
~dir
~internal_deps:[pure_lib]
~style:(`Pack project_name)
let app : Project.item =
project_app project_name
~thread:()
~file:"src/app/cli_main.ml"
~internal_deps:[lwt_unix_lib]
let test_apps : Project.item list =
if build_tests
then [
project_app (project_name ^ "-test")
~thread:()
~file:"src/test/main.ml"
~install:`No
~internal_deps:[lwt_unix_lib];
project_app (project_name ^ "-workflow-examples")
~thread:()
~file:"src/test/Workflow_Examples.ml"
~install:`No
~internal_deps:[lwt_unix_lib];
project_app (project_name ^ "-preconfigured-main-test")
~thread:()
~file:"src/test/preconfigured_main.ml"
~install:`No
~internal_deps:[lwt_unix_lib];
project_app (project_name ^ "-persistance-test")
~thread:()
~file:"src/test/persistance.ml"
~install:`No
~internal_deps:[lwt_unix_lib];
project_app (project_name ^ "-synth-workflows")
~thread:()
~file:"src/test/synthetic_workflows.ml"
~install:`No
~internal_deps:[lwt_unix_lib];
] @ begin
let plugin =
project_lib (project_name ^ ".dummy-plugin")
~thread:()
~dir:"src/test/dummy-plugin/"
~install:`No
~internal_deps:[lwt_unix_lib]
~style:(`Pack "dummy_plugin_test_lib") in
[
plugin;
project_app (project_name ^ "-dummy-plugin-user")
~thread:()
~file:"src/test/dummy_plugin_user.ml"
~install:`No
~internal_deps:[plugin];
]
end
else []
let build_doc () =
let lib = (match lwt_unix_lib with Project.Lib l -> l | _ -> assert false) in
let paths d =
try Sys.readdir d
|> Array.to_list
|> List.filter ~f:(fun f ->
(Filename.check_suffix f ".mli"
|| Filename.check_suffix f ".ml")
)
|> List.map ~f:(fun p -> d // p)
with e ->
failwithf "Cannot read dir: %S, %s, from %s"
d (Printexc.to_string e) (Sys.getcwd ()) in
let deps =
["README.md"]
@ [Project.path_of_pack ~suffix:".cmo" lib]
@ paths "src/doc"
@ paths "src/test"
@ paths "src/test/dummy-plugin"
in
Solvuu_build.Util.Rule.rule
~name:"Build-doc"
~prods:["doc/index.html"]
~deps
~insert:`bottom
begin fun env builder ->
let open Ocamlbuild_plugin in
Seq [
cmdf "../tools/build-documentation.sh %s"
(String.concat "," lwt_unix_lib_packages);
]
end
let ocamlinit_postfix = [
sprintf "open %s_pure" (String.capitalize_ascii project_name);
sprintf "open %s" (String.capitalize_ascii project_name);
]
let () =
Project.basic1 ~project_name ~version ~ocamlinit_postfix
~additional_rules:[
generate_meta_data;
make_gui_page;
make_persistent_data;
begin fun () -> (* We want the rules of the JSOO app but not the app
itself since it doesn't build in `native` mode *)
let open Project in
match js_lib, js_app with
| Lib l, App a -> build_app a; build_lib l
| _, _ -> assert false
end;
build_doc;
]
([pure_lib; lwt_unix_lib; app;] @ test_apps)