@@ -5,23 +5,27 @@ module Origin = struct
55 type t =
66 | Library of Library .t
77 | Executables of Executables .t
8+ | Tests of Tests .t
89 | Melange of Melange_stanzas.Emit .t
910
1011 let loc = function
1112 | Library l -> l.buildable.loc
1213 | Executables e -> e.buildable.loc
14+ | Tests t -> t.exes.buildable.loc
1315 | Melange mel -> mel.loc
1416 ;;
1517
1618 let preprocess = function
1719 | Library l -> l.buildable.preprocess
1820 | Executables e -> e.buildable.preprocess
21+ | Tests t -> t.exes.buildable.preprocess
1922 | Melange mel -> mel.preprocess
2023 ;;
2124
2225 let to_dyn = function
2326 | Library _ -> Dyn. variant " Library" [ Dyn. Opaque ]
2427 | Executables _ -> Dyn. variant " Executables" [ Dyn. Opaque ]
28+ | Tests _ -> Dyn. variant " Tests" [ Dyn. Opaque ]
2529 | Melange _ -> Dyn. variant " Melange" [ Dyn. Opaque ]
2630 ;;
2731end
@@ -58,10 +62,11 @@ module Per_stanza = struct
5862 type groups =
5963 { libraries : Library .t group_part list
6064 ; executables : Executables .t group_part list
65+ ; tests : Tests .t group_part list
6166 ; melange_emits : Melange_stanzas.Emit .t group_part list
6267 }
6368
64- let make { libraries = libs ; executables = exes ; melange_emits = emits } =
69+ let make { libraries = libs ; executables = exes ; tests; melange_emits = emits } =
6570 let libraries, libraries_by_obj_dir =
6671 List. fold_left
6772 libs
@@ -84,17 +89,29 @@ module Per_stanza = struct
8489 by_id, by_obj_dir)
8590 in
8691 let executables =
87- match
88- String.Map. of_list_map exes ~f: (fun (part : Executables.t group_part ) ->
89- let first_exe = snd (Nonempty_list. hd part.stanza.names) in
90- let origin : Origin.t = Executables part.stanza in
91- first_exe, (origin, part.modules, part.obj_dir))
92- with
93- | Ok x -> x
94- | Error (name , _ , part ) ->
92+ let entries =
93+ List. concat
94+ [ List. map exes ~f: (fun (part : Executables.t group_part ) ->
95+ let first_exe = snd (Nonempty_list. hd part.stanza.names) in
96+ let origin : Origin.t = Executables part.stanza in
97+ first_exe, (origin, part.modules, part.obj_dir, part.stanza.buildable.loc))
98+ ; List. map tests ~f: (fun (part : Tests.t group_part ) ->
99+ let first_exe = snd (Nonempty_list. hd part.stanza.exes.names) in
100+ let origin : Origin.t = Tests part.stanza in
101+ ( first_exe
102+ , (origin, part.modules, part.obj_dir, part.stanza.exes.buildable.loc) ))
103+ ]
104+ in
105+ match String.Map. of_list entries with
106+ | Ok map ->
107+ String.Map. map map ~f: (fun (origin , modules , obj_dir , _loc ) ->
108+ origin, modules, obj_dir)
109+ | Error (name , (_ , _ , _ , loc1 ), (_ , _ , _ , loc2 )) ->
95110 User_error. raise
96- ~loc: part.stanza.buildable.loc
97- [ Pp. textf " Executable %S appears for the second time in this directory" name ]
111+ ~loc: loc1
112+ [ Pp. textf " Executable %S appears for the second time in this directory" name
113+ ; Pp. textf " Already defined at %s" (Loc. to_file_colon_line loc2)
114+ ]
98115 in
99116 let melange_emits =
100117 match
@@ -118,6 +135,8 @@ module Per_stanza = struct
118135 by_path (Library part.stanza, part.dir) part.sources)
119136 ; List. rev_concat_map exes ~f: (fun part ->
120137 by_path (Executables part.stanza, part.dir) part.sources)
138+ ; List. rev_concat_map tests ~f: (fun part ->
139+ by_path (Tests part.stanza, part.dir) part.sources)
121140 ; List. rev_concat_map emits ~f: (fun part ->
122141 by_path (Melange part.stanza, part.dir) part.sources)
123142 ]
@@ -252,7 +271,7 @@ let find_origin (t : t) ~libs path =
252271 | Some origins ->
253272 Memo.List. filter_map origins ~f: (fun (origin , dir ) ->
254273 match origin with
255- | Executables _ | Melange _ -> Memo. return (Some origin)
274+ | Executables _ | Tests _ | Melange _ -> Memo. return (Some origin)
256275 | Library lib ->
257276 let src_dir = Path. drop_optional_build_context_src_exn (Path. build dir) in
258277 Lib.DB. available_by_lib_id libs (Local (Library. to_lib_id ~src_dir lib))
@@ -469,14 +488,18 @@ let modules_of_stanzas =
469488 | `Skip -> loop l acc
470489 | `Library y -> loop l { acc with libraries = y :: acc .libraries }
471490 | `Executables y -> loop l { acc with executables = y :: acc .executables }
491+ | `Tests y -> loop l { acc with tests = y :: acc .tests }
472492 | `Melange_emit y -> loop l { acc with melange_emits = y :: acc .melange_emits })
473493 in
474- fun l -> loop l { libraries = [] ; executables = [] ; melange_emits = [] }
494+ fun l -> loop l { libraries = [] ; executables = [] ; tests = [] ; melange_emits = [] }
475495 in
476496 fun l ->
477- let { Per_stanza. libraries; executables; melange_emits } = rev_filter_partition l in
497+ let { Per_stanza. libraries; executables; tests; melange_emits } =
498+ rev_filter_partition l
499+ in
478500 { Per_stanza. libraries = List. rev libraries
479501 ; executables = List. rev executables
502+ ; tests = List. rev tests
480503 ; melange_emits = List. rev melange_emits
481504 }
482505 in
@@ -505,6 +528,12 @@ let modules_of_stanzas =
505528 in
506529 `Executables { Per_stanza. stanza = exes; sources; modules; obj_dir; dir }
507530 in
531+ let make_tests ~dir ~expander ~modules ~project tests =
532+ let + result = make_executables ~dir ~expander ~modules ~project tests.Tests. exes in
533+ match result with
534+ | `Executables group_part -> `Tests { group_part with stanza = tests }
535+ | _ -> assert false
536+ in
508537 fun stanzas ~expander ~project ~dir ~libs ~lookup_vlib ~modules ~include_subdirs ->
509538 Memo. parallel_map stanzas ~f: (fun stanza ->
510539 let enabled_if =
@@ -541,7 +570,7 @@ let modules_of_stanzas =
541570 let obj_dir = Library. obj_dir lib ~dir in
542571 `Library { Per_stanza. stanza = lib; sources; modules; dir; obj_dir }
543572 | Executables. T exes -> make_executables ~dir ~expander ~modules ~project exes
544- | Tests. T { exes; _ } -> make_executables ~dir ~expander ~modules ~project exes
573+ | Tests. T tests -> make_tests ~dir ~expander ~modules ~project tests
545574 | Melange_stanzas.Emit. T mel ->
546575 let obj_dir = Obj_dir. make_melange_emit ~dir ~name: mel.target in
547576 let + sources, modules =
@@ -665,9 +694,14 @@ let make
665694 part.stanza, part.modules, part.obj_dir)
666695 in
667696 let exes =
668- List. map
669- modules_of_stanzas.executables
670- ~f: (fun (part : _ Per_stanza.group_part ) -> part.modules, part.obj_dir)
697+ List. concat
698+ [ List. map
699+ modules_of_stanzas.executables
700+ ~f: (fun { Per_stanza. modules; obj_dir; _ } -> modules, obj_dir)
701+ ; List. map
702+ modules_of_stanzas.tests
703+ ~f: (fun { Per_stanza. modules; obj_dir; _ } -> modules, obj_dir)
704+ ]
671705 in
672706 Artifacts_obj. make
673707 ~dir
0 commit comments