Install by specifying libdir for opam-installer

- change default findlib directory (ocamlc -where)
This commit is contained in:
François Bobot 2017-07-05 15:10:41 +02:00 committed by Jeremie Dimino
parent c7e67d49b8
commit 747cf220c6
4 changed files with 74 additions and 35 deletions

View File

@ -685,12 +685,20 @@ let get_prefix context ~from_command_line =
| Some p -> Future.return (Path.of_string p)
| None -> Context.install_prefix context
let get_libdir context ~libdir_from_command_line ~prefix_from_command_line =
match libdir_from_command_line with
| Some p -> Future.return (Path.of_string p)
| None ->
match prefix_from_command_line with
| Some p -> Future.return (Path.relative (Path.of_string p) "lib")
| None -> Context.install_ocaml_libdir context
let install_uninstall ~what =
let doc =
sprintf "%s packages using opam-installer." (String.capitalize_ascii what)
in
let name_ = Arg.info [] ~docv:"PACKAGE" in
let go common prefix pkgs =
let go common prefix_from_command_line libdir_from_command_line pkgs =
set_common common ~targets:[];
let opam_installer = opam_installer () in
let log = Log.create () in
@ -720,15 +728,16 @@ let install_uninstall ~what =
(List.map missing_install_files
~f:(fun p -> sprintf "- %s" (Path.to_string p))))
end;
(match setup.contexts, prefix with
| _ :: _ :: _, Some _ ->
die "Cannot specify --prefix when installing into multiple contexts!"
(match setup.contexts, prefix_from_command_line, libdir_from_command_line with
| _ :: _ :: _, Some _, _ | _ :: _ :: _, _, Some _ ->
die "Cannot specify --prefix or --libdir when installing into multiple contexts!"
| _ -> ());
let module CMap = Map.Make(Context) in
let install_files_by_context = CMap.of_alist_multi install_files |> CMap.bindings in
Future.all_unit
(List.map install_files_by_context ~f:(fun (context, install_files) ->
get_prefix context ~from_command_line:prefix >>= fun prefix ->
get_prefix context ~from_command_line:prefix_from_command_line >>= fun prefix ->
get_libdir context ~libdir_from_command_line ~prefix_from_command_line >>= fun libdir ->
Future.all_unit
(List.map install_files ~f:(fun path ->
let purpose = Future.Build_job install_files in
@ -736,12 +745,15 @@ let install_uninstall ~what =
[ sprintf "-%c" what.[0]
; "--prefix"
; Path.to_string prefix
; "--libdir"
; Path.to_string libdir
; Path.to_string path
])))))
in
( Term.(const go
$ common
$ Arg.(value & opt (some dir) None & info ["prefix"])
$ Arg.(value & opt (some dir) None & info ["libdir"])
$ Arg.(value & pos_all string [] name_))
, Term.info what ~doc ~man:help_secs)

View File

@ -248,17 +248,27 @@ to be able to use ``jbuilder install``.
Destination
-----------
The place where the build artifacts are copied, usually referred as
The place where the build artifacts (except ocaml libraries) are copied, usually referred as
**prefix**, is determined as follow for a given build context:
#. if an explicit ``--prefix <path>`` argument is passed, use this path
#. if ``opam`` is present in the ``PATH``, use the output of ``opam config var
prefix``
#. otherwise, take the directory where ``ocamlc`` was found, and append
``../lib`` to it. For instance if ``ocamlc`` is found in ``/usr/bin``, use
``/usr``
#. otherwise, take the parent of the directory where ``ocamlc`` was found.
Note that ``--prefix`` is only supported if a single build context is in
The ocaml libraries build artifacts are copied, referred as
**libdir**, is determined as follow for a given build context:
#. if an explicit ``--libdir <path>`` argument is passed, use this path
#. if ``ocamlfind`` is present in the ``PATH``, use the output of
``ocamlfind printconf destdir``
#. if ``opam`` is present in the ``PATH``, use the output of ``opam config var
lib``
#. otherwise, take the directory of the ocaml standard library
Note that ``--prefix`` and ``--libdir`` are only supported if a single build context is in
use.
Workspace configuration

View File

@ -198,31 +198,8 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findli
Path.of_string (sprintf "_build/%s" name)
in
let ocamlc_config_cmd = sprintf "%s -config" (Path.to_string ocamlc) in
let findlib_path =
if use_findlib then
(* If ocamlfind is present, it has precedence over everything else. *)
match which "ocamlfind" with
| Some fn ->
(Future.run_capture_lines ~env Strict
(Path.to_string fn) ["printconf"; "path"]
>>| List.map ~f:Path.absolute)
| None ->
(* If there no ocamlfind in the PATH, check if we have opam and assume a standard
opam setup *)
opam_config_var ~env ~cache:opam_var_cache "lib"
>>| function
| Some s -> [Path.absolute s]
| None ->
(* If neither opam neither ocamlfind are present, assume that libraries are in
[dir ^ "/../lib"] *)
[Path.relative (Path.parent dir) "lib"]
else
return []
in
both
findlib_path
(Future.run_capture_lines ~env Strict (Path.to_string ocamlc) ["-config"])
>>= fun (findlib_path, ocamlc_config) ->
Future.run_capture_lines ~env Strict (Path.to_string ocamlc) ["-config"]
>>= fun ocamlc_config ->
let ocamlc_config =
List.map ocamlc_config ~f:(fun line ->
match String.index line ':' with
@ -301,6 +278,28 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findli
let _, ocamlopt_cflags = split_prog (get "native_c_compiler") in
(c_compiler, ocamlc_cflags, ocamlopt_cflags)
in
let findlib_path =
if use_findlib then
(* If ocamlfind is present, it has precedence over everything else. *)
match which "ocamlfind" with
| Some fn ->
(Future.run_capture_lines ~env Strict
(Path.to_string fn) ["printconf"; "path"]
>>| List.map ~f:Path.absolute)
| None ->
(* If there no ocamlfind in the PATH, check if we have opam and assume a standard
opam setup *)
opam_config_var ~env ~cache:opam_var_cache "lib"
>>| function
| Some s -> [Path.absolute s]
| None ->
(* If neither opam neither ocamlfind are present, assume that libraries are in
the stdlib directory *)
[stdlib_dir]
else
return []
in
findlib_path >>= fun findlib_path ->
return
{ name
; kind
@ -426,6 +425,23 @@ let install_prefix t =
| Some x -> Path.absolute x
| None -> Path.parent t.ocaml_bin
let install_ocaml_libdir t =
(* If ocamlfind is present, it has precedence over everything else. *)
match which t "ocamlfind" with
| Some fn ->
(Future.run_capture_line ~env:t.env Strict
(Path.to_string fn) ["printconf"; "destdir"]
>>| Path.absolute)
| None ->
(* If there no ocamlfind in the PATH, check if we have opam and assume a standard
opam setup *)
opam_config_var t "lib"
>>| function
| Some s -> Path.absolute s
| None ->
(* If neither opam neither ocamlfind are present use stdlib dir *)
t.stdlib_dir
(* CR-someday jdimino: maybe we should just do this for [t.env] directly? *)
let env_for_exec t =

View File

@ -144,6 +144,7 @@ val extend_env : vars:string Env_var_map.t -> env:string array -> string array
val opam_config_var : t -> string -> string option Future.t
val install_prefix : t -> Path.t Future.t
val install_ocaml_libdir : t -> Path.t Future.t
val env_for_exec : t -> string array