Record library dependencies using Build.prefix_rules

This commit is contained in:
Jeremie Dimino 2018-03-30 16:10:26 -04:00 committed by Rudi Grinberg
parent 950a37b1ad
commit 9b1adee13c
5 changed files with 60 additions and 49 deletions

View File

@ -549,7 +549,8 @@ module Gen(P : Install_rules.Params) = struct
it references are built after. *)
let alias_module_build_sandbox = ctx.version < (4, 03, 0)
let library_rules (lib : Library.t) ~modules_partitioner ~dir ~files ~scope =
let library_rules (lib : Library.t) ~modules_partitioner ~dir ~files ~scope
~requires ~compile_info =
let obj_dir = Utils.library_object_directory ~dir lib.name in
let dep_kind = if lib.optional then Build.Optional else Required in
let flags = Ocaml_flags.make lib.buildable sctx ~scope ~dir in
@ -606,20 +607,11 @@ module Gen(P : Install_rules.Params) = struct
|> String.concat ~sep:"\n")
>>> Build.write_file_dyn (Path.relative dir file.name)));
let compile_info =
Lib.DB.get_compile_info (Scope.libs scope) lib.name
~allow_overlaps:lib.buildable.allow_overlapping_dependencies
in
SC.Libs.gen_select_rules sctx compile_info ~dir;
let requires =
SC.Libs.requires sctx compile_info
~dir ~has_dot_merlin:true
in
let dynlink = lib.dynlink in
let js_of_ocaml = lib.buildable.js_of_ocaml in
Module_compilation.build_modules sctx
~js_of_ocaml ~dynlink ~flags ~scope ~dir ~obj_dir ~dep_graphs
let dynlink = lib.dynlink in
let js_of_ocaml = lib.buildable.js_of_ocaml in
Module_compilation.build_modules sctx
~js_of_ocaml ~dynlink ~flags ~scope ~dir ~obj_dir ~dep_graphs
~modules ~requires ~alias_module;
Option.iter alias_module ~f:(fun m ->
let flags = Ocaml_flags.default () in
@ -802,12 +794,24 @@ module Gen(P : Install_rules.Params) = struct
~libname:lib.name
~objs_dirs:(Path.Set.singleton obj_dir)
let library_rules (lib : Library.t) ~modules_partitioner ~dir ~files ~scope =
let compile_info =
Lib.DB.get_compile_info (Scope.libs scope) lib.name
~allow_overlaps:lib.buildable.allow_overlapping_dependencies
in
SC.Libs.gen_select_rules sctx compile_info ~dir;
SC.Libs.with_lib_deps sctx compile_info ~dir ~has_dot_merlin:true
~f:(fun requires ->
library_rules lib ~modules_partitioner ~dir ~files ~scope
~requires ~compile_info)
(* +-----------------------------------------------------------------+
| Executables stuff |
+-----------------------------------------------------------------+ *)
let executables_rules ~dir ~all_modules
?modules_partitioner ~scope (exes : Executables.t) =
?modules_partitioner ~scope ~requires ~compile_info
(exes : Executables.t) =
let modules =
parse_modules ~all_modules ~buildable:exes.buildable
in
@ -876,19 +880,6 @@ module Gen(P : Install_rules.Params) = struct
~standard:[]
in
let compile_info =
Lib.DB.resolve_user_written_deps (Scope.libs scope)
exes.buildable.libraries
~pps:(Jbuild.Preprocess_map.pps exes.buildable.preprocess)
~allow_overlaps:exes.buildable.allow_overlapping_dependencies
in
SC.Libs.gen_select_rules sctx compile_info ~dir;
let requires =
SC.Libs.requires sctx ~dir
~has_dot_merlin:true
compile_info
in
(* Use "eobjs" rather than "objs" to avoid a potential conflict
with a library of the same name *)
let obj_dir =
@ -913,6 +904,20 @@ module Gen(P : Install_rules.Params) = struct
~preprocess:(Buildable.single_preprocess exes.buildable)
~objs_dirs:(Path.Set.singleton obj_dir)
let executables_rules ~dir ~all_modules
?modules_partitioner ~scope (exes : Executables.t) =
let compile_info =
Lib.DB.resolve_user_written_deps (Scope.libs scope)
exes.buildable.libraries
~pps:(Jbuild.Preprocess_map.pps exes.buildable.preprocess)
~allow_overlaps:exes.buildable.allow_overlapping_dependencies
in
SC.Libs.gen_select_rules sctx compile_info ~dir;
SC.Libs.with_lib_deps sctx compile_info ~dir ~has_dot_merlin:true
~f:(fun requires ->
executables_rules exes ~dir ~all_modules
?modules_partitioner ~scope ~requires ~compile_info)
(* +-----------------------------------------------------------------+
| Aliases |
+-----------------------------------------------------------------+ *)

View File

@ -196,7 +196,7 @@ include Sub_system.Register_end_point(
let runner_libs =
let open Result.O in
Lib.Compile.make
Build.of_result
(Result.concat_map backends
~f:(fun (backend : Backend.t) -> backend.runner_libraries)
>>= fun libs ->
@ -206,8 +206,8 @@ include Sub_system.Register_end_point(
(List.map info.libraries
~f:(Lib.DB.resolve (Scope.libs scope)))
>>= fun more_libs ->
Ok (lib @ libs @ more_libs))
|> Super_context.Libs.requires sctx ~dir ~has_dot_merlin:false
Lib.closure (lib @ libs @ more_libs)
>>| Build.return)
in
(* Generate the runner file *)

View File

@ -270,25 +270,27 @@ module Libs = struct
raise (Lib.Error (No_solution_found_for_select e))
}))
let requires t ~dir ~has_dot_merlin compile_info =
let with_lib_deps t compile_info ~dir ~has_dot_merlin ~f =
let requires =
Build.of_result_map (Lib.Compile.requires compile_info)
~f:Build.return
in
let requires =
let prefix =
Build.record_lib_deps (Lib.Compile.user_written_deps compile_info)
~kind:(if Lib.Compile.optional compile_info then
Optional
else
Required)
>>> requires
in
if t.context.merlin && has_dot_merlin then
Build.path (Path.relative dir ".merlin-exists")
>>>
requires
else
requires
let prefix =
if t.context.merlin && has_dot_merlin then
Build.path (Path.relative dir ".merlin-exists")
>>>
prefix
else
prefix
in
prefix_rules t prefix ~f:(fun () -> f requires)
let lib_files_alias ~dir ~name ~ext =
Alias.make (sprintf "lib-%s%s-all" name ext) ~dir

View File

@ -130,14 +130,16 @@ val resolve_program
-> Action.Prog.t
module Libs : sig
(** Returns the closed list of dependencies for a dependency list in
a stanza. *)
val requires
(** Make sure all rules produces by [f] record the library
dependencies for [jbuilder external-lib-deps] and depend on the
generation of the .merlin file. *)
val with_lib_deps
: t
-> Lib.Compile.t
-> dir:Path.t
-> has_dot_merlin:bool
-> Lib.Compile.t
-> (unit, Lib.L.t) Build.t
-> f:((unit, Lib.L.t) Build.t -> 'a)
-> 'a
(** Generate the rules for the [(select ...)] forms in library dependencies *)
val gen_select_rules : t -> dir:Path.t -> Lib.Compile.t -> unit

View File

@ -63,10 +63,12 @@ let setup sctx ~dir ~(libs : Library.t list) ~scope =
; obj_name = "" } in
let utop_exe_dir = utop_exe_dir ~dir in
let requires =
Lib.DB.find_many (Scope.libs scope)
("utop" :: List.map libs ~f:(fun (lib : Library.t) -> lib.name))
|> Lib.Compile.make
|> Super_context.Libs.requires sctx ~dir ~has_dot_merlin:false
let open Result.O in
Build.of_result
(Lib.DB.find_many (Scope.libs scope)
("utop" :: List.map libs ~f:(fun (lib : Library.t) -> lib.name))
>>= Lib.closure
>>| Build.return)
in
Exe.build_and_link sctx
~dir:utop_exe_dir