Improvements to searching for libs at runtime (plugins, runtime, etc.)

This commit is contained in:
Louis Gesbert 2023-09-01 17:09:31 +02:00
parent 1dd06a2e4e
commit 9a596a48f7
6 changed files with 46 additions and 29 deletions

View File

@ -261,12 +261,8 @@ let inline_test_rule catala_exe catala_opts =
[ [
Lit Sys.argv.(0); Lit Sys.argv.(0);
Lit "runtest"; Lit "runtest";
Seq [Lit "--exe"; Lit catala_exe]; Lit ("--exe=" ^ catala_exe);
Seq Lit ("--catala-opts=\"" ^ String.escaped catala_opts ^ "\"");
[
Lit "--catala-opts";
Lit ("\"" ^ String.escaped catala_opts ^ "\"");
];
Var.tested_file; Var.tested_file;
pipe_diff_cmd; pipe_diff_cmd;
]) ])

View File

@ -174,14 +174,16 @@ module Flags = struct
let env = Cmd.Env.info "CATALA_PLUGINS" in let env = Cmd.Env.info "CATALA_PLUGINS" in
let default = let default =
let ( / ) = Filename.concat in let ( / ) = Filename.concat in
[ let exec_dir = Filename.(dirname Sys.argv.(0)) in
Filename.dirname Sys.executable_name let dev_plugin_dir = exec_dir / "plugins" in
/ Filename.parent_dir_name if Sys.file_exists dev_plugin_dir then
/ "lib" (* When running tests in place, may need to lookup in _build/default
/ "catala" besides the exec *)
/ "plugins"; [dev_plugin_dir]
"_build" / "default" / "compiler" / "plugins"; else
] (* Otherwise, assume a standard layout: "<prefix>/bin/catala" besides
"<prefix>/lib/catala" *)
[Filename.(dirname exec_dir) / "lib" / "catala" / "plugins"]
in in
value & opt_all string default & info ["plugin-dir"] ~docv:"DIR" ~env ~doc value & opt_all string default & info ["plugin-dir"] ~docv:"DIR" ~env ~doc

View File

@ -116,3 +116,5 @@ let check_directory d =
with Unix.Unix_error _ | Sys_error _ -> None with Unix.Unix_error _ | Sys_error _ -> None
let ( / ) = Filename.concat let ( / ) = Filename.concat
let dirname = Filename.dirname
let ( /../ ) a b = dirname a / b

View File

@ -87,3 +87,9 @@ val check_directory : string -> string option
val ( / ) : string -> string -> string val ( / ) : string -> string -> string
(** [Filename.concat]: Sugar to allow writing (** [Filename.concat]: Sugar to allow writing
[File.("some" / "relative" / "path")] *) [File.("some" / "relative" / "path")] *)
val dirname : string -> string
(** [Filename.dirname], re-exported for convenience *)
val ( /../ ) : string -> string -> string
(** Sugar for [Filename.dirname "a" / b] *)

View File

@ -39,17 +39,20 @@ let load_file f =
| e -> | e ->
Message.emit_warning "Could not load plugin %S: %s" f (Printexc.to_string e) Message.emit_warning "Could not load plugin %S: %s" f (Printexc.to_string e)
let rec load_dir d = let load_dir d =
Message.emit_debug "Loading plugins from %s" d; Message.emit_debug "Loading plugins from %s" d;
let dynlink_exts = let dynlink_exts =
if Dynlink.is_native then [".cmxs"] else [".cmo"; ".cma"] if Dynlink.is_native then [".cmxs"] else [".cmo"; ".cma"]
in in
Array.iter let rec aux d =
(fun f -> Array.iter
if f.[0] = '.' then () (fun f ->
else if f.[0] = '.' then ()
let f = Filename.concat d f in else
if Sys.is_directory f then load_dir f let f = Filename.concat d f in
else if List.exists (Filename.check_suffix f) dynlink_exts then if Sys.is_directory f then aux f
load_file f) else if List.exists (Filename.check_suffix f) dynlink_exts then
(Sys.readdir d) load_file f)
(Sys.readdir d)
in
aux d

View File

@ -77,7 +77,7 @@ let ocaml_libdir =
with Failure _ -> ( with Failure _ -> (
try String.trim (File.process_out "ocamlc" ["-where"]) try String.trim (File.process_out "ocamlc" ["-where"])
with Failure _ -> ( with Failure _ -> (
match File.(check_directory (Sys.executable_name / ".." / "lib")) with match File.(check_directory (dirname Sys.argv.(0) /../ "lib")) with
| Some d -> d | Some d -> d
| None -> | None ->
Message.raise_error Message.raise_error
@ -87,7 +87,7 @@ let ocaml_libdir =
let rec find_catala_project_root dir = let rec find_catala_project_root dir =
if Sys.file_exists File.(dir / "catala.opam") then Some dir if Sys.file_exists File.(dir / "catala.opam") then Some dir
else else
let dir' = Unix.realpath File.(dir / Filename.parent_dir_name) in let dir' = File.dirname dir in
if dir' = dir then None else find_catala_project_root dir' if dir' = dir then None else find_catala_project_root dir'
let runtime_dir = let runtime_dir =
@ -104,7 +104,13 @@ let runtime_dir =
/ "lib" / "lib"
/ "catala" / "catala"
/ "runtime_ocaml") / "runtime_ocaml")
| None -> File.(Lazy.force ocaml_libdir / "catala" / "runtime") | None -> (
match
File.check_directory
File.(dirname Sys.argv.(0) /../ "lib" / "catala" / "runtime_ocaml")
with
| Some d -> d
| None -> File.(Lazy.force ocaml_libdir / "catala" / "runtime"))
in in
match File.check_directory d with match File.check_directory d with
| Some dir -> | Some dir ->
@ -128,7 +134,7 @@ let compile options link_modules optimize check_invariants =
gen_ocaml options link_modules optimize check_invariants (Some modname) None gen_ocaml options link_modules optimize check_invariants (Some modname) None
in in
let flags = ["-I"; Lazy.force runtime_dir] in let flags = ["-I"; Lazy.force runtime_dir] in
let shared_out = File.((Filename.dirname ml_file / basename) ^ ".cmxs") in let shared_out = File.((ml_file /../ basename) ^ ".cmxs") in
Message.emit_debug "Compiling OCaml shared object file @{<bold>%s@}..." Message.emit_debug "Compiling OCaml shared object file @{<bold>%s@}..."
shared_out; shared_out;
run_process "ocamlopt" ("-shared" :: ml_file :: "-o" :: shared_out :: flags); run_process "ocamlopt" ("-shared" :: ml_file :: "-o" :: shared_out :: flags);
@ -176,7 +182,7 @@ let link options link_modules optimize check_invariants output ex_scope_opt =
in in
let runtime_lib = File.(runtime_dir / "runtime_ocaml.cmxa") in let runtime_lib = File.(runtime_dir / "runtime_ocaml.cmxa") in
let modules = let modules =
List.map (fun m -> Filename.remove_extension m ^ ".ml") link_modules List.map (fun m -> Filename.remove_extension m ^ ".cmx") link_modules
in in
let output = let output =
match output with match output with
@ -185,6 +191,8 @@ let link options link_modules optimize check_invariants output ex_scope_opt =
in in
let args = let args =
with_flag "-I" link_libdirs with_flag "-I" link_libdirs
@ with_flag "-I"
(List.sort_uniq compare (List.map Filename.dirname modules))
@ List.map @ List.map
(fun lib -> String.map (function '-' -> '_' | c -> c) lib ^ ".cmxa") (fun lib -> String.map (function '-' -> '_' | c -> c) lib ^ ".cmxa")
link_libs link_libs