From 826cbed8ee112822b76d842a0aba5b09c998dd62 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Tue, 21 Aug 2018 17:35:56 +0100 Subject: [PATCH 1/4] Do not build and install shared libs when not supported Read `ocamlc -where`/Makefile.config to determine whether this is supported. Signed-off-by: Jeremie Dimino --- CHANGES.md | 3 +++ src/context.ml | 30 ++++++++++++++++++++++++++++++ src/context.mli | 2 ++ src/install_rules.ml | 3 ++- src/lib_rules.ml | 5 +++-- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 44356bf5ab0..7db7b136719 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,9 @@ next - Highlight multi-line errors (#1131, @anuragsoni) +- Do no try to generate shared libraries when this is not supported by + the OS (#1165, fix #1051, @diml) + 1.1.1 (08/08/2018) ------------------ diff --git a/src/context.ml b/src/context.ml index f5864736508..a0247c32cf0 100644 --- a/src/context.ml +++ b/src/context.ml @@ -81,6 +81,7 @@ type t = ; ast_intf_magic_number : string ; cmxs_magic_number : string ; cmt_magic_number : string + ; supports_shared_libraries : bool ; which_cache : (string, Path.t option) Hashtbl.t } @@ -105,6 +106,7 @@ let sexp_of_t t = ; "findlib_path", list path (Findlib.path t.findlib) ; "arch_sixtyfour", bool t.arch_sixtyfour ; "natdynlink_supported", bool t.natdynlink_supported + ; "supports_shared_libraries", bool t.supports_shared_libraries ; "opam_vars", string_hashtbl string t.opam_var_cache ; "ocaml_config", Ocaml_config.sexp_of_t t.ocaml_config ; "which", string_hashtbl (option path) t.which_cache @@ -112,6 +114,31 @@ let sexp_of_t t = let compare a b = compare a.name b.name +(* Parse the [`ocamlc -where`/makefile_config] file *) +module Makefile_config = struct + type t = + { supports_shared_libraries : bool + } + + let load ~stdlib_dir = + let file = Path.relative stdlib_dir "Makefile.config" in + let lines = Io.lines_of_file file in + let vars = + List.filter_map lines ~f:(fun line -> + let line = String.trim line in + if line = "" || line.[0] = '#' then + None + else + String.lsplit2 line ~on:'=') + |> String.Map.of_list_reduce ~f:(fun _ x -> x) + in + { supports_shared_libraries = + (match String.Map.find vars "SUPPORTS_SHARED_LIBRARIES" with + | Some "false" -> false + | _ -> true) + } +end + let opam_config_var ~env ~cache var = match Hashtbl.find cache var with | Some _ as x -> Fiber.return x @@ -340,6 +367,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets let version_string = Ocaml_config.version_string ocfg in let version = Ocaml_version.of_ocaml_config ocfg in let arch_sixtyfour = Ocaml_config.word_size ocfg = 64 in + let makefile_config = Makefile_config.load ~stdlib_dir in Fiber.return { name ; implicit @@ -404,6 +432,8 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets ; cmxs_magic_number = Ocaml_config.cmxs_magic_number ocfg ; cmt_magic_number = Ocaml_config.cmt_magic_number ocfg + ; supports_shared_libraries = makefile_config.supports_shared_libraries + ; which_cache } in diff --git a/src/context.mli b/src/context.mli index a3ac39d2393..e9e476716c2 100644 --- a/src/context.mli +++ b/src/context.mli @@ -122,6 +122,8 @@ type t = ; cmxs_magic_number : string ; cmt_magic_number : string + ; supports_shared_libraries : bool + ; which_cache : (string, Path.t option) Hashtbl.t } diff --git a/src/install_rules.ml b/src/install_rules.ml index 2d64eff292b..de68d952498 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -178,7 +178,8 @@ module Gen(P : Params) = struct ] in let dlls = - if_ (byte && Library.has_stubs lib && lib.dynlink) + if_ (byte && Library.has_stubs lib && lib.dynlink && + ctx.supports_shared_libraries) [Library.dll ~dir lib ~ext_dll:ctx.ext_dll] in let execs = diff --git a/src/lib_rules.ml b/src/lib_rules.ml index 1808fcd1c81..a36929791e7 100644 --- a/src/lib_rules.ml +++ b/src/lib_rules.ml @@ -196,7 +196,8 @@ module Gen (P : Install_rules.Params) = struct let ocamlmklib = ocamlmklib lib ~scope ~dir ~o_files in if modes.native && modes.byte && - lib.dynlink + lib.dynlink && + ctx.supports_shared_libraries then begin (* If we build for both modes and support dynlink, use a single invocation to build both the static and dynamic @@ -340,7 +341,7 @@ module Gen (P : Install_rules.Params) = struct let dep_graphs = Ocamldep.rules cctx in - let dynlink = lib.dynlink in + let dynlink = lib.dynlink && ctx.supports_shared_libraries in let js_of_ocaml = lib.buildable.js_of_ocaml in Module_compilation.build_modules cctx ~js_of_ocaml ~dynlink ~dep_graphs; From ba516c1263ad22a11e147b4dc87c7a870e31e748 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Wed, 22 Aug 2018 10:41:55 +0100 Subject: [PATCH 2/4] Move Makefile.config parsing to Ocaml_config Signed-off-by: Jeremie Dimino --- src/context.ml | 38 ++------- src/ocaml-config/ocaml_config.ml | 123 +++++++++++++++++++----------- src/ocaml-config/ocaml_config.mli | 20 +++-- 3 files changed, 101 insertions(+), 80 deletions(-) diff --git a/src/context.ml b/src/context.ml index a0247c32cf0..e37e739c98e 100644 --- a/src/context.ml +++ b/src/context.ml @@ -114,31 +114,6 @@ let sexp_of_t t = let compare a b = compare a.name b.name -(* Parse the [`ocamlc -where`/makefile_config] file *) -module Makefile_config = struct - type t = - { supports_shared_libraries : bool - } - - let load ~stdlib_dir = - let file = Path.relative stdlib_dir "Makefile.config" in - let lines = Io.lines_of_file file in - let vars = - List.filter_map lines ~f:(fun line -> - let line = String.trim line in - if line = "" || line.[0] = '#' then - None - else - String.lsplit2 line ~on:'=') - |> String.Map.of_list_reduce ~f:(fun _ x -> x) - in - { supports_shared_libraries = - (match String.Map.find vars "SUPPORTS_SHARED_LIBRARIES" with - | Some "false" -> false - | _ -> true) - } -end - let opam_config_var ~env ~cache var = match Hashtbl.find cache var with | Some _ as x -> Fiber.return x @@ -287,19 +262,22 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets in let ocaml_config_ok_exn = function | Ok x -> x - | Error msg -> + | Error (Ocaml_config.Origin.Ocamlc_config, msg) -> die "Failed to parse the output of '%s -config':@\n\ %s" (Path.to_string ocamlc) msg + | Error (Makefile_config file, msg) -> + Loc.fail (Loc.in_file (Path.to_string file)) "%s" msg in Fiber.fork_and_join findlib_path (fun () -> Process.run_capture_lines ~env Strict ocamlc ["-config"] >>| fun lines -> - let open Result.O in ocaml_config_ok_exn - (Ocaml_config.Vars.of_lines lines >>= Ocaml_config.make)) + (match Ocaml_config.Vars.of_lines lines with + | Ok vars -> Ocaml_config.make vars + | Error msg -> Error (Ocamlc_config, msg))) >>= fun (findlib_path, ocfg) -> let version = Ocaml_version.of_ocaml_config ocfg in let env = @@ -367,7 +345,6 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets let version_string = Ocaml_config.version_string ocfg in let version = Ocaml_version.of_ocaml_config ocfg in let arch_sixtyfour = Ocaml_config.word_size ocfg = 64 in - let makefile_config = Makefile_config.load ~stdlib_dir in Fiber.return { name ; implicit @@ -431,8 +408,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets ; ast_intf_magic_number = Ocaml_config.ast_intf_magic_number ocfg ; cmxs_magic_number = Ocaml_config.cmxs_magic_number ocfg ; cmt_magic_number = Ocaml_config.cmt_magic_number ocfg - - ; supports_shared_libraries = makefile_config.supports_shared_libraries + ; supports_shared_libraries = Ocaml_config.supports_shared_libraries ocfg ; which_cache } diff --git a/src/ocaml-config/ocaml_config.ml b/src/ocaml-config/ocaml_config.ml index c5aa56d1670..140274fe2f6 100644 --- a/src/ocaml-config/ocaml_config.ml +++ b/src/ocaml-config/ocaml_config.ml @@ -82,6 +82,7 @@ type t = ; cmxs_magic_number : string ; cmt_magic_number : string ; natdynlink_supported : bool + ; supports_shared_libraries : bool } let version t = t.version @@ -131,6 +132,7 @@ let ast_intf_magic_number t = t.ast_intf_magic_number let cmxs_magic_number t = t.cmxs_magic_number let cmt_magic_number t = t.cmt_magic_number let natdynlink_supported t = t.natdynlink_supported +let supports_shared_libraries t = t.supports_shared_libraries let to_list t : (string * Value.t) list = [ "version" , String t.version_string @@ -179,6 +181,7 @@ let to_list t : (string * Value.t) list = ; "cmxs_magic_number" , String t.cmxs_magic_number ; "cmt_magic_number" , String t.cmt_magic_number ; "natdynlink_supported" , Bool t.natdynlink_supported + ; "supports_shared_libraries", Bool t.supports_shared_libraries ] let sexp_of_t t = @@ -189,9 +192,11 @@ let sexp_of_t t = ; Value.sexp_of_t v ])) -exception E of string -let fail fmt = - Printf.ksprintf (fun msg -> raise (E msg)) fmt +module Origin = struct + type t = + | Ocamlc_config + | Makefile_config of Path.t +end let split_prog s = match String.extract_blank_separated_words s with @@ -219,51 +224,71 @@ module Vars = struct Result.map_error (String.Map.of_list vars) ~f:(fun (var, _, _) -> Printf.sprintf "Variable %S present twice." var) - let get_opt t var = String.Map.find t var + let load_makefile_config file = + let lines = Io.lines_of_file file in + List.filter_map lines ~f:(fun line -> + let line = String.trim line in + if line = "" || line.[0] = '#' then + None + else + String.lsplit2 line ~on:'=') + |> String.Map.of_list_reduce ~f:(fun _ x -> x) + + exception E of Origin.t * string - let get t var = - match get_opt t var with - | Some s -> s - | None -> fail "Variable %S not found." var + module Getters(Origin : sig val origin : Origin.t end) = struct + let fail fmt = + Printf.ksprintf (fun msg -> raise (E (Origin.origin, msg))) fmt - let get_bool t var = - match get_opt t var with - | None -> false - | Some s -> - match s with - | "true" -> true - | "false" -> false - | s -> - fail "Value of %S is neither 'true' neither 'false': %s." var s + let get_opt t var = String.Map.find t var - let get_int_opt t var = - match get_opt t var with - | None -> None - | Some s -> - match int_of_string s with - | x -> Some x - | exception _ -> - fail "Value of %S is not an integer: %s." var s + let get t var = + match get_opt t var with + | Some s -> s + | None -> fail "Variable %S not found." var - let get_words t var = - match get_opt t var with - | None -> [] - | Some s -> String.extract_blank_separated_words s + let get_bool t ?(default=false) var = + match get_opt t var with + | None -> default + | Some s -> + match s with + | "true" -> true + | "false" -> false + | s -> + fail "Value of %S is neither 'true' neither 'false': %s." var s - let get_prog_or_dummy t var = - Option.map (get_opt t var) ~f:(fun v -> - match split_prog v with - | None -> - { prog = Printf.sprintf "%s-not-found-in-ocaml-config" var - ; args = [] - } + let get_int_opt t var = + match get_opt t var with + | None -> None + | Some s -> + match int_of_string s with + | x -> Some x + | exception _ -> + fail "Value of %S is not an integer: %s." var s + + let get_words t var = + match get_opt t var with + | None -> [] + | Some s -> String.extract_blank_separated_words s + + let get_prog_or_dummy t var = + Option.map (get_opt t var) ~f:(fun v -> + match split_prog v with + | None -> + { prog = Printf.sprintf "%s-not-found-in-ocaml-config" var + ; args = [] + } + | Some s -> s + ) + + let get_prog_or_dummy_exn t var = + match get_prog_or_dummy t var with + | None -> fail "Variable %S not found." var | Some s -> s - ) + end - let get_prog_or_dummy_exn t var = - match get_prog_or_dummy t var with - | None -> fail "Variable %S not found." var - | Some s -> s + module Ocamlc_config_getters = + Getters(struct let origin = Origin.Ocamlc_config end) end let get_arch_sixtyfour stdlib_dir = @@ -287,7 +312,7 @@ let get_arch_sixtyfour stdlib_dir = let make vars = match - let open Vars in + let open Vars.Ocamlc_config_getters in let bytecomp_c_compiler = get_prog_or_dummy_exn vars "bytecomp_c_compiler" in let native_c_compiler = @@ -369,6 +394,15 @@ let make vars = let natdynlink_supported = Sys.file_exists (Filename.concat standard_library "dynlink.cmxa") in + + let file = + Path.relative (Path.of_string standard_library) "Makefile.config" + in + let vars = Vars.load_makefile_config file in + let module Getters = + Vars.Getters(struct let origin = Origin.Makefile_config file end) + in + let supports_shared_libraries = get_bool vars "SUPPORTS_SHARED_LIBRARIES" in { version ; version_string ; standard_library_default @@ -416,7 +450,8 @@ let make vars = ; cmxs_magic_number ; cmt_magic_number ; natdynlink_supported + ; supports_shared_libraries } with - | t -> Ok t - | exception (E msg) -> Error msg + | t -> Ok t + | exception (Vars.E (origin, msg)) -> Error (origin, msg) diff --git a/src/ocaml-config/ocaml_config.mli b/src/ocaml-config/ocaml_config.mli index 52ca6f4836c..7662ead492a 100644 --- a/src/ocaml-config/ocaml_config.mli +++ b/src/ocaml-config/ocaml_config.mli @@ -1,10 +1,11 @@ -(** Represent the output of [ocamlc -config]. +(** Represent the output of [ocamlc -config] and contents of [Makefile.config]. This library is internal to jbuilder and guarantees no API stability. *) open Stdune -(** Represent a parsed and interpreted output of [ocamlc -config] *) +(** Represent a parsed and interpreted output of [ocamlc -config] and + contents of [Makefile.config]. *) type t val sexp_of_t : t -> Usexp.t @@ -18,7 +19,8 @@ end (** {1 Raw bindings} *) -(** Represent the parsed but uninterpreted output of [ocamlc -config] *) +(** Represent the parsed but uninterpreted output of [ocamlc -config] + or contents of [Makefile.config]. *) module Vars : sig type t = string String.Map.t @@ -28,8 +30,15 @@ end (** {1 Creation} *) -(** Interpret raw bindings *) -val make : Vars.t -> (t, string) Result.t +module Origin : sig + type t = + | Ocamlc_config + | Makefile_config of Path.t +end + +(** Interpret raw bindings (this function also loads the + [Makefile.config] file in the stdlib directory). *) +val make : Vars.t -> (t, Origin.t * string) Result.t (** {1 Query} *) @@ -83,6 +92,7 @@ val ast_intf_magic_number : t -> string val cmxs_magic_number : t -> string val cmt_magic_number : t -> string val natdynlink_supported : t -> bool +val supports_shared_libraries : t -> bool (** {1 Values} *) From 19c4784efb3bb017fe3047285ac2d1b0082e1989 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Wed, 22 Aug 2018 11:28:41 +0100 Subject: [PATCH 3/4] Fix ocaml-config tests Signed-off-by: Jeremie Dimino --- src/ocaml-config/ocaml_config.ml | 6 ++++- test/unit-tests/ocaml-config/Makefile.config | 1 + test/unit-tests/ocaml-config/dune | 3 ++- test/unit-tests/ocaml-config/gh637.ml | 27 ++++++++++++-------- 4 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 test/unit-tests/ocaml-config/Makefile.config diff --git a/src/ocaml-config/ocaml_config.ml b/src/ocaml-config/ocaml_config.ml index 140274fe2f6..7157b20430e 100644 --- a/src/ocaml-config/ocaml_config.ml +++ b/src/ocaml-config/ocaml_config.ml @@ -214,7 +214,11 @@ module Vars = struct | Some i -> let x = (String.sub line ~pos:0 ~len:i, - String.sub line ~pos:(i + 2) ~len:(String.length line - i - 2)) + let len = String.length line - i - 2 in + if len < 0 then + "" + else + String.sub line ~pos:(i + 2) ~len) in loop (x :: acc) lines | None -> diff --git a/test/unit-tests/ocaml-config/Makefile.config b/test/unit-tests/ocaml-config/Makefile.config new file mode 100644 index 00000000000..34bf67199eb --- /dev/null +++ b/test/unit-tests/ocaml-config/Makefile.config @@ -0,0 +1 @@ +SUPPORTS_SHARED_LIBRARIES=true diff --git a/test/unit-tests/ocaml-config/dune b/test/unit-tests/ocaml-config/dune index cb4d4096bb8..233c647cc77 100644 --- a/test/unit-tests/ocaml-config/dune +++ b/test/unit-tests/ocaml-config/dune @@ -1,3 +1,4 @@ (test (name gh637) - (libraries ocaml_config)) + (libraries ocaml_config) + (deps Makefile.config)) diff --git a/test/unit-tests/ocaml-config/gh637.ml b/test/unit-tests/ocaml-config/gh637.ml index dbb7783d0b0..d99396b732e 100644 --- a/test/unit-tests/ocaml-config/gh637.ml +++ b/test/unit-tests/ocaml-config/gh637.ml @@ -1,22 +1,24 @@ open Stdune -let valid_ocaml_config = +let pwd = Sys.getcwd () + +let valid_ocaml_config = Printf.sprintf {|version: 4.02.3 -standard_library_default: /usr/lib/ocaml -standard_library: /usr/lib/ocaml +standard_library_default: %s +standard_library: %s standard_runtime: /usr/bin/ocamlrun ccomp_type: cc bytecomp_c_compiler: gcc -O -fno-defer-pop -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT -O -fPIC bytecomp_c_libraries: -lm -ldl -lcurses -lpthread native_c_compiler: gcc -O -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT native_c_libraries: -lm -ldl -native_pack_linker: ld -r -o +native_pack_linker: ld -r -o ranlib: ranlib cc_profile: -pg architecture: none model: default system: unknown -asm: +asm: asm_cfi_supported: false with_frame_pointers: false ext_obj: .o @@ -38,14 +40,17 @@ ast_impl_magic_number: Caml1999M016 ast_intf_magic_number: Caml1999N015 cmxs_magic_number: Caml2007D002 cmt_magic_number: Caml2012T004|} +pwd pwd let () = - let open Result.O in match - valid_ocaml_config - |> String.split_lines - |> Ocaml_config.Vars.of_lines - >>= Ocaml_config.make + match + valid_ocaml_config + |> String.split_lines + |> Ocaml_config.Vars.of_lines + with + | Ok x -> Ocaml_config.make x + | Error msg -> Error (Ocamlc_config, msg) with - | Error e -> failwith e + | Error (_, e) -> failwith e | Ok (_ : Ocaml_config.t) -> () From 382189c88a4a80a643a35e08c8246e7a6e0b43f1 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Wed, 22 Aug 2018 11:44:33 +0100 Subject: [PATCH 4/4] Make sure we can't use lib.dynlink directly Signed-off-by: Jeremie Dimino --- src/context.ml | 17 +++++++++++------ src/context.mli | 4 ++-- src/dune_file.ml | 4 ++-- src/dune_file.mli | 2 +- src/dynlink_supported.ml | 9 +++++++++ src/dynlink_supported.mli | 11 +++++++++++ src/install_rules.ml | 6 +++--- src/lib_rules.ml | 9 +++++---- 8 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 src/dynlink_supported.ml create mode 100644 src/dynlink_supported.mli diff --git a/src/context.ml b/src/context.ml index e37e739c98e..6d55ae46690 100644 --- a/src/context.ml +++ b/src/context.ml @@ -47,7 +47,7 @@ type t = ; findlib_toolchain : string option ; arch_sixtyfour : bool ; opam_var_cache : (string, string) Hashtbl.t - ; natdynlink_supported : bool + ; natdynlink_supported : Dynlink_supported.By_the_os.t ; ocaml_config : Ocaml_config.t ; version_string : string ; version : Ocaml_version.t @@ -81,7 +81,7 @@ type t = ; ast_intf_magic_number : string ; cmxs_magic_number : string ; cmt_magic_number : string - ; supports_shared_libraries : bool + ; supports_shared_libraries : Dynlink_supported.By_the_os.t ; which_cache : (string, Path.t option) Hashtbl.t } @@ -105,8 +105,10 @@ let sexp_of_t t = ; "env", Env.sexp_of_t (Env.diff t.env Env.initial) ; "findlib_path", list path (Findlib.path t.findlib) ; "arch_sixtyfour", bool t.arch_sixtyfour - ; "natdynlink_supported", bool t.natdynlink_supported - ; "supports_shared_libraries", bool t.supports_shared_libraries + ; "natdynlink_supported", + bool (Dynlink_supported.By_the_os.get t.natdynlink_supported) + ; "supports_shared_libraries", + bool (Dynlink_supported.By_the_os.get t.supports_shared_libraries) ; "opam_vars", string_hashtbl string t.opam_var_cache ; "ocaml_config", Ocaml_config.sexp_of_t t.ocaml_config ; "which", string_hashtbl (option path) t.which_cache @@ -373,7 +375,8 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets ; opam_var_cache - ; natdynlink_supported + ; natdynlink_supported = + Dynlink_supported.By_the_os.of_bool natdynlink_supported ; stdlib_dir ; ocaml_config = ocfg @@ -408,7 +411,9 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets ; ast_intf_magic_number = Ocaml_config.ast_intf_magic_number ocfg ; cmxs_magic_number = Ocaml_config.cmxs_magic_number ocfg ; cmt_magic_number = Ocaml_config.cmt_magic_number ocfg - ; supports_shared_libraries = Ocaml_config.supports_shared_libraries ocfg + ; supports_shared_libraries = + Dynlink_supported.By_the_os.of_bool + (Ocaml_config.supports_shared_libraries ocfg) ; which_cache } diff --git a/src/context.mli b/src/context.mli index e9e476716c2..93e0fb28b50 100644 --- a/src/context.mli +++ b/src/context.mli @@ -86,7 +86,7 @@ type t = ; opam_var_cache : (string, string) Hashtbl.t ; (** Native dynlink *) - natdynlink_supported : bool + natdynlink_supported : Dynlink_supported.By_the_os.t ; ocaml_config : Ocaml_config.t ; version_string : string @@ -122,7 +122,7 @@ type t = ; cmxs_magic_number : string ; cmt_magic_number : string - ; supports_shared_libraries : bool + ; supports_shared_libraries : Dynlink_supported.By_the_os.t ; which_cache : (string, Path.t option) Hashtbl.t } diff --git a/src/dune_file.ml b/src/dune_file.ml index 38d6cda26a3..951d6222e1b 100644 --- a/src/dune_file.ml +++ b/src/dune_file.ml @@ -913,7 +913,7 @@ module Library = struct ; wrapped : bool ; optional : bool ; buildable : Buildable.t - ; dynlink : bool + ; dynlink : Dynlink_supported.t ; project : Dune_project.t ; sub_systems : Sub_system_info.t Sub_system_name.Map.t ; no_keep_locs : bool @@ -999,7 +999,7 @@ module Library = struct ; wrapped ; optional ; buildable - ; dynlink = not no_dynlink + ; dynlink = Dynlink_supported.of_bool (not no_dynlink) ; project ; sub_systems ; no_keep_locs diff --git a/src/dune_file.mli b/src/dune_file.mli index 83720cd38bb..742f1d2c97d 100644 --- a/src/dune_file.mli +++ b/src/dune_file.mli @@ -226,7 +226,7 @@ module Library : sig ; wrapped : bool ; optional : bool ; buildable : Buildable.t - ; dynlink : bool + ; dynlink : Dynlink_supported.t ; project : Dune_project.t ; sub_systems : Sub_system_info.t Sub_system_name.Map.t ; no_keep_locs : bool diff --git a/src/dynlink_supported.ml b/src/dynlink_supported.ml new file mode 100644 index 00000000000..0d274ce0253 --- /dev/null +++ b/src/dynlink_supported.ml @@ -0,0 +1,9 @@ +module By_the_os = struct + type t = bool + let of_bool t = t + let get t = t +end + +type t = bool +let of_bool t = t +let get x y = x && y diff --git a/src/dynlink_supported.mli b/src/dynlink_supported.mli new file mode 100644 index 00000000000..4ce04d2f65c --- /dev/null +++ b/src/dynlink_supported.mli @@ -0,0 +1,11 @@ +(** Track whether dynamic loading of code is supported *) + +module By_the_os : sig + type t + val of_bool : bool -> t + val get : t -> bool +end + +type t +val of_bool : bool -> t +val get : t -> By_the_os.t -> bool diff --git a/src/install_rules.ml b/src/install_rules.ml index de68d952498..d5886fad372 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -168,7 +168,7 @@ module Gen(P : Params) = struct ; Library.archive ~dir lib ~ext:ctx.ext_lib ] in - if ctx.natdynlink_supported && lib.dynlink then + if Dynlink_supported.get lib.dynlink ctx.natdynlink_supported then files @ [ Library.archive ~dir lib ~ext:".cmxs" ] else files) @@ -178,8 +178,8 @@ module Gen(P : Params) = struct ] in let dlls = - if_ (byte && Library.has_stubs lib && lib.dynlink && - ctx.supports_shared_libraries) + if_ (byte && Library.has_stubs lib && + Dynlink_supported.get lib.dynlink ctx.supports_shared_libraries) [Library.dll ~dir lib ~ext_dll:ctx.ext_dll] in let execs = diff --git a/src/lib_rules.ml b/src/lib_rules.ml index a36929791e7..bb013af9c61 100644 --- a/src/lib_rules.ml +++ b/src/lib_rules.ml @@ -196,8 +196,7 @@ module Gen (P : Install_rules.Params) = struct let ocamlmklib = ocamlmklib lib ~scope ~dir ~o_files in if modes.native && modes.byte && - lib.dynlink && - ctx.supports_shared_libraries + Dynlink_supported.get lib.dynlink ctx.supports_shared_libraries then begin (* If we build for both modes and support dynlink, use a single invocation to build both the static and dynamic @@ -341,7 +340,9 @@ module Gen (P : Install_rules.Params) = struct let dep_graphs = Ocamldep.rules cctx in - let dynlink = lib.dynlink && ctx.supports_shared_libraries in + let dynlink = + Dynlink_supported.get lib.dynlink ctx.supports_shared_libraries + in let js_of_ocaml = lib.buildable.js_of_ocaml in Module_compilation.build_modules cctx ~js_of_ocaml ~dynlink ~dep_graphs; @@ -386,7 +387,7 @@ module Gen (P : Install_rules.Params) = struct let target = Path.extend_basename src ~suffix:".js" in Js_of_ocaml_rules.build_cm cctx ~js_of_ocaml ~src ~target); - if ctx.natdynlink_supported then + if Dynlink_supported.By_the_os.get ctx.natdynlink_supported then build_shared lib ~dir ~flags ~ctx; Odoc.setup_library_odoc_rules lib ~requires ~modules ~dep_graphs ~scope;