Skip to content

Commit

Permalink
Add Lib_archives.has_native_archive
Browse files Browse the repository at this point in the history
This function dictates whether a local library has a native archive.
Such an archive is absent when using msvc on empty libraries.

Signed-off-by: Rudi Grinberg <[email protected]>
  • Loading branch information
rgrinberg committed Oct 31, 2019
1 parent da59019 commit d1593cf
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 11 deletions.
18 changes: 15 additions & 3 deletions src/dune/lib_archives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ let lib_files t = t.lib_files

let dll_files t = t.dll_files

let has_native_archive lib config contents =
Lib_config.emit_empty_archives config
||
let name = Dune_file.Library.best_name lib in
let modules = Dir_contents.modules_of_library contents ~name in
not (Modules.is_empty modules)

module Library = Dune_file.Library

let make ~(ctx : Context.t) ~dir ~dir_contents (lib : Library.t) =
Expand Down Expand Up @@ -41,9 +48,14 @@ let make ~(ctx : Context.t) ~dir ~dir_contents (lib : Library.t) =
; if_
(native && not virtual_library)
(let files =
[ Library.archive ~dir lib ~ext:(Mode.compiled_lib_ext Native)
; Library.archive ~dir lib ~ext:ext_lib
]
if has_native_archive lib ctx.lib_config dir_contents then
[ Library.archive ~dir lib ~ext:ext_lib ]
else
[]
in
let files =
Library.archive ~dir lib ~ext:(Mode.compiled_lib_ext Native)
:: files
in
if
Dynlink_supported.get lib.dynlink
Expand Down
3 changes: 3 additions & 0 deletions src/dune/lib_archives.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ open Stdune

type t

val has_native_archive :
Dune_file.Library.t -> Lib_config.t -> Dir_contents.t -> bool

val make :
ctx:Context.t
-> dir:Path.Build.t
Expand Down
30 changes: 22 additions & 8 deletions src/dune/lib_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ let msvc_hack_cclibs =
Option.value ~default:lib (String.drop_prefix ~prefix:"-l" lib))

(* Build an OCaml library. *)
let build_lib (lib : Library.t) ~sctx ~expander ~flags ~dir ~mode ~cm_files =
let build_lib (lib : Library.t) ~sctx ~dir_contents ~expander ~flags ~dir ~mode
~cm_files =
let ctx = Super_context.context sctx in
let { Lib_config.ext_lib; _ } = ctx.lib_config in
Option.iter (Context.compiler ctx mode) ~f:(fun compiler ->
Expand Down Expand Up @@ -75,7 +76,14 @@ let build_lib (lib : Library.t) ~sctx ~expander ~flags ~dir ~mode ~cm_files =
; Hidden_targets
( match mode with
| Byte -> []
| Native -> [ Library.archive lib ~dir ~ext:ext_lib ] )
| Native ->
if
Lib_archives.has_native_archive lib ctx.lib_config
dir_contents
then
[ Library.archive lib ~dir ~ext:ext_lib ]
else
[] )
] ))

let gen_wrapped_compat_modules (lib : Library.t) cctx =
Expand Down Expand Up @@ -212,7 +220,7 @@ let build_stubs lib ~cctx ~dir ~expander ~requires ~dir_contents
ocamlmklib ~archive_name ~loc:lib.buildable.loc ~sctx ~expander ~dir
~o_files ~c_library_flags:lib.c_library_flags ~build_targets_together

let build_shared lib ~sctx ~dir ~flags =
let build_shared lib ~dir_contents ~sctx ~dir ~flags =
let ctx = Super_context.context sctx in
Option.iter ctx.ocamlopt ~f:(fun ocamlopt ->
let ext_lib = ctx.lib_config.ext_lib in
Expand All @@ -227,7 +235,6 @@ let build_shared lib ~sctx ~dir ~flags =
let build =
Build.paths
(Library.foreign_archives lib ~dir ~ext_lib |> List.map ~f:Path.build)
>>> Build.path (Path.build (Library.archive lib ~dir ~ext:ext_lib))
>>> Command.run ~dir:(Path.build ctx.build_dir) (Ok ocamlopt)
[ Command.Args.dyn (Ocaml_flags.get flags Native)
; A "-shared"
Expand All @@ -239,9 +246,16 @@ let build_shared lib ~sctx ~dir ~flags =
; Dep src
]
in
let build =
if Lib_archives.has_native_archive lib ctx.lib_config dir_contents then
Build.path (Path.build (Library.archive lib ~dir ~ext:ext_lib))
>>> build
else
build
in
Super_context.add_rule sctx build ~dir)

let setup_build_archives (lib : Dune_file.Library.t) ~cctx
let setup_build_archives (lib : Dune_file.Library.t) ~dir_contents ~cctx
~(dep_graphs : Dep_graph.Ml_kind.t) ~expander =
let dir = Compilation_context.dir cctx in
let obj_dir = Compilation_context.obj_dir cctx in
Expand Down Expand Up @@ -274,7 +288,7 @@ let setup_build_archives (lib : Dune_file.Library.t) ~cctx
Cm_files.make ~obj_dir ~ext_obj ~modules ~top_sorted_modules
in
Mode.Dict.Set.iter modes ~f:(fun mode ->
build_lib lib ~sctx ~expander ~flags ~dir ~mode ~cm_files));
build_lib lib ~dir_contents ~sctx ~expander ~flags ~dir ~mode ~cm_files));
(* Build *.cma.js *)
if modes.byte then
Super_context.add_rules sctx ~dir
Expand All @@ -288,7 +302,7 @@ let setup_build_archives (lib : Dune_file.Library.t) ~cctx
in
Js_of_ocaml_rules.build_cm cctx ~js_of_ocaml ~src ~target);
if Dynlink_supported.By_the_os.get natdynlink_supported && modes.native then
build_shared ~sctx lib ~dir ~flags
build_shared ~dir_contents ~sctx lib ~dir ~flags

let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope
~compile_info =
Expand Down Expand Up @@ -352,7 +366,7 @@ let library_rules (lib : Library.t) ~cctx ~source_modules ~dir_contents
Module_compilation.build_all cctx ~dep_graphs;
let expander = Super_context.expander sctx ~dir in
if not (Library.is_virtual lib) then
setup_build_archives lib ~cctx ~dep_graphs ~expander;
setup_build_archives lib ~dir_contents ~cctx ~dep_graphs ~expander;
let () =
let vlib_stubs_o_files = Vimpl.vlib_stubs_o_files vimpl in
if Library.has_foreign lib || List.is_non_empty vlib_stubs_o_files then
Expand Down
10 changes: 10 additions & 0 deletions src/dune/modules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ module Wrapped = struct
; wrapped : Mode.t
}

let empty t = Module_name.Map.is_empty t.modules

let encode
{ modules; wrapped_compat; alias_module; main_module_name; wrapped } =
let open Dune_lang.Encoder in
Expand Down Expand Up @@ -752,3 +754,11 @@ let relocate_alias_module t ~src_dir =
match t with
| Wrapped t -> Wrapped (Wrapped.relocate_alias_module t ~src_dir)
| s -> s

let is_empty = function
| Stdlib _
| Impl _
| Singleton _ ->
false
| Unwrapped w -> Module_name.Map.is_empty w
| Wrapped w -> Wrapped.empty w
2 changes: 2 additions & 0 deletions src/dune/modules.mli
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,5 @@ val exit_module : t -> Module.t option
(** [relcoate_alias_module t ~src_dir] sets the source directory of the alias
module to [src_dir]. Only works if [t] is wrapped. *)
val relocate_alias_module : t -> src_dir:Path.t -> t

val is_empty : t -> bool

0 comments on commit d1593cf

Please sign in to comment.