Simplify a bit the rules for installation of library files

This commit is contained in:
Jeremie Dimino 2017-07-25 17:07:24 +01:00
parent 44a15bcd24
commit cfd43d5282
4 changed files with 76 additions and 69 deletions

View File

@ -685,13 +685,10 @@ 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 =
let get_libdir context ~libdir_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
| Some p -> Future.return (Some (Path.of_string p))
| None -> Context.install_ocaml_libdir context
let install_uninstall ~what =
let doc =
@ -730,25 +727,32 @@ let install_uninstall ~what =
end;
(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!"
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
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_from_command_line >>= fun prefix ->
get_libdir context ~libdir_from_command_line ~prefix_from_command_line >>= fun libdir ->
get_prefix context ~from_command_line:prefix_from_command_line
>>= fun prefix ->
get_libdir context ~libdir_from_command_line
>>= fun libdir ->
Future.all_unit
(List.map install_files ~f:(fun path ->
let purpose = Future.Build_job install_files in
Future.run ~purpose Strict (Path.to_string opam_installer)
[ sprintf "-%c" what.[0]
; "--prefix"
; Path.to_string prefix
; "--libdir"
; Path.to_string libdir
; Path.to_string path
])))))
let purpose = Future.Build_job install_files in
Future.run ~purpose Strict (Path.to_string opam_installer)
([ sprintf "-%c" what.[0]
; Path.to_string path
; "--prefix"
; Path.to_string prefix
] @
match libdir with
| None -> []
| Some p -> [ "--libdir"; Path.to_string p ]
))))))
in
( Term.(const go
$ common

View File

@ -248,29 +248,38 @@ to be able to use ``jbuilder install``.
Destination
-----------
The place where the build artifacts (except library files) are copied, usually referred as
The place where the build artifacts 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``
#. if ``opam`` is present in the ``PATH`` and is configured, use the
output of ``opam config var prefix``
#. otherwise, take the parent of the directory where ``ocamlc`` was found.
The place where the library files are copied, referred as
**libdir**, is determined as follow for a given build context:
As an exception to this rule, library files might be copied to a
different location. The reason for this is that they often need to be
copied to a particular location for the various build system used in
OCaml projects to find them and this location might be different from
``<prefix>/lib`` on some systems.
#. if an explicit ``--libdir <path>`` argument is passed, use this path
#. if an explicit ``--prefix <path>`` argument is passed, use ``<path>/lib``
#. 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
Historically, the location where to store OCaml library files was
configured through `findlib
<http://projects.camlcity.org/projects/findlib.html>`__ and the
``ocamlfind`` command line tool was used to both install these files
and locate them. Many Linux distributions or other packaging systems
are using this mechanism to setup where OCaml library files should be
copied.
As a result, if none of ``--libdir`` and ``--prefix`` is passed to
``jbuilder install`` and ``ocamlfind`` is present in the ``PATH``,
then library files will be copied to the directory reported by
``ocamlfind printconf destdir``. This ensures that ``jbuilder
install`` can be used without opam. When using opam, ``ocamlfind`` is
configured to point to the opam directory, so this rule makes no
difference.
Note that ``--prefix`` and ``--libdir`` are only supported if a single build context is in
use.
Note that ``--prefix`` and ``--libdir`` are only supported if a single
build context is in use.
Workspace configuration
=======================

View File

@ -200,8 +200,31 @@ 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
Future.run_capture_lines ~env Strict (Path.to_string ocamlc) ["-config"]
>>= fun ocamlc_config ->
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 stan 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
[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) ->
let ocamlc_config =
List.map ocamlc_config ~f:(fun line ->
match String.index line ':' with
@ -280,28 +303,6 @@ 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
@ -433,17 +434,10 @@ let install_ocaml_libdir t =
| Some fn ->
(Future.run_capture_line ~env:t.env Strict
(Path.to_string fn) ["printconf"; "destdir"]
>>| Path.absolute)
>>| fun s ->
Some (Path.absolute s))
| 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
return None
(* CR-someday jdimino: maybe we should just do this for [t.env] directly? *)
let env_for_exec t =

View File

@ -144,7 +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 install_ocaml_libdir : t -> Path.t option Future.t
val env_for_exec : t -> string array