diff --git a/src/gen_rules.ml b/src/gen_rules.ml index b47e4119..6456e8c3 100644 --- a/src/gen_rules.ml +++ b/src/gen_rules.ml @@ -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 | +-----------------------------------------------------------------+ *) diff --git a/src/inline_tests.ml b/src/inline_tests.ml index a4e75529..acdeb188 100644 --- a/src/inline_tests.ml +++ b/src/inline_tests.ml @@ -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 *) diff --git a/src/super_context.ml b/src/super_context.ml index 8f43e473..c2bd80cd 100644 --- a/src/super_context.ml +++ b/src/super_context.ml @@ -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 diff --git a/src/super_context.mli b/src/super_context.mli index 66da0091..5038079b 100644 --- a/src/super_context.mli +++ b/src/super_context.mli @@ -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 diff --git a/src/utop.ml b/src/utop.ml index e39f3193..333f06e8 100644 --- a/src/utop.ml +++ b/src/utop.ml @@ -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