Merge pull request #831 from emillon/shared-object-package
Improve error message when attempting to install a shared object
This commit is contained in:
commit
28991eb6b0
|
@ -13,4 +13,15 @@ let t =
|
|||
; "shared_object" , Shared_object
|
||||
]
|
||||
|
||||
let to_string = function
|
||||
| Exe -> "exe"
|
||||
| Object -> "object"
|
||||
| Shared_object -> "shared_object"
|
||||
|
||||
let pp fmt t =
|
||||
Format.pp_print_string fmt (to_string t)
|
||||
|
||||
let sexp_of_t t =
|
||||
Sexp.unsafe_atom_of_string (to_string t)
|
||||
|
||||
let all = [Exe; Object; Shared_object]
|
||||
|
|
|
@ -9,4 +9,8 @@ type t =
|
|||
|
||||
val t : t Sexp.Of_sexp.t
|
||||
|
||||
val sexp_of_t : t Sexp.To_sexp.t
|
||||
|
||||
val all : t list
|
||||
|
||||
val pp : Format.formatter -> t -> unit
|
||||
|
|
|
@ -608,6 +608,17 @@ module Mode_conf = struct
|
|||
; "best" , Best
|
||||
]
|
||||
|
||||
let to_string = function
|
||||
| Byte -> "byte"
|
||||
| Native -> "native"
|
||||
| Best -> "best"
|
||||
|
||||
let pp fmt t =
|
||||
Format.pp_print_string fmt (to_string t)
|
||||
|
||||
let sexp_of_t t =
|
||||
Sexp.unsafe_atom_of_string (to_string t)
|
||||
|
||||
module Set = struct
|
||||
include Set.Make(T)
|
||||
|
||||
|
@ -796,15 +807,19 @@ module Executables = struct
|
|||
let byte = byte_exe
|
||||
let native = native_exe
|
||||
|
||||
let installable_modes =
|
||||
[exe; native; byte]
|
||||
|
||||
let simple_representations =
|
||||
[ "exe" , exe
|
||||
; "object" , object_
|
||||
; "shared_object" , shared_object
|
||||
; "byte" , byte
|
||||
; "native" , native
|
||||
]
|
||||
|
||||
let simple =
|
||||
let open Sexp.Of_sexp in
|
||||
enum
|
||||
[ "exe" , exe
|
||||
; "object" , object_
|
||||
; "shared_object" , shared_object
|
||||
; "byte" , byte
|
||||
; "native" , native
|
||||
]
|
||||
Sexp.Of_sexp.enum simple_representations
|
||||
|
||||
let t sexp =
|
||||
match sexp with
|
||||
|
@ -813,6 +828,21 @@ module Executables = struct
|
|||
{ mode; kind }
|
||||
| _ -> simple sexp
|
||||
|
||||
let simple_sexp_of_t link_mode =
|
||||
let is_ok (_, candidate) =
|
||||
compare candidate link_mode = Eq
|
||||
in
|
||||
match List.find ~f:is_ok simple_representations with
|
||||
| Some (s, _) -> Some (Sexp.unsafe_atom_of_string s)
|
||||
| None -> None
|
||||
|
||||
let sexp_of_t link_mode =
|
||||
match simple_sexp_of_t link_mode with
|
||||
| Some s -> s
|
||||
| None ->
|
||||
let { mode; kind } = link_mode in
|
||||
Sexp.To_sexp.pair Mode_conf.sexp_of_t Binary_kind.sexp_of_t (mode, kind)
|
||||
|
||||
module Set = struct
|
||||
include Set.Make(T)
|
||||
|
||||
|
@ -837,14 +867,7 @@ module Executables = struct
|
|||
]
|
||||
|
||||
let best_install_mode t =
|
||||
if mem t exe then
|
||||
Some exe
|
||||
else if mem t native then
|
||||
Some native
|
||||
else if mem t byte then
|
||||
Some byte
|
||||
else
|
||||
None
|
||||
List.find ~f:(mem t) installable_modes
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -879,8 +902,21 @@ module Executables = struct
|
|||
; buildable
|
||||
}
|
||||
in
|
||||
let has_public_name =
|
||||
List.exists ~f:Option.is_some public_names
|
||||
in
|
||||
let to_install =
|
||||
match Link_mode.Set.best_install_mode t.modes with
|
||||
| None when has_public_name ->
|
||||
let mode_to_string mode = " - " ^ Sexp.to_string (Link_mode.sexp_of_t mode) in
|
||||
let mode_strings = List.map ~f:mode_to_string Link_mode.installable_modes in
|
||||
Loc.fail
|
||||
buildable.loc
|
||||
"No installable mode found for %s.\n\
|
||||
One of the following modes is required:\n\
|
||||
%s"
|
||||
(if multi then "these executables" else "this executable")
|
||||
(String.concat ~sep:"\n" mode_strings)
|
||||
| None -> []
|
||||
| Some mode ->
|
||||
let ext =
|
||||
|
|
|
@ -171,6 +171,7 @@ module Mode_conf : sig
|
|||
|
||||
val t : t Sexp.Of_sexp.t
|
||||
val compare : t -> t -> Ordering.t
|
||||
val pp : Format.formatter -> t -> unit
|
||||
|
||||
module Set : sig
|
||||
include Set.S with type elt = t
|
||||
|
@ -240,6 +241,9 @@ module Executables : sig
|
|||
; kind : Binary_kind.t
|
||||
}
|
||||
|
||||
val t : t Sexp.Of_sexp.t
|
||||
val sexp_of_t : t Sexp.To_sexp.t
|
||||
|
||||
val exe : t
|
||||
val object_ : t
|
||||
val shared_object : t
|
||||
|
|
|
@ -372,6 +372,15 @@
|
|||
(run ${exe:cram.exe} -skip-versions 4.02.3 -test run.t)
|
||||
(diff? run.t run.t.corrected))))))
|
||||
|
||||
(alias
|
||||
((name no-installable-mode)
|
||||
(deps
|
||||
((package dune) (files_recursively_in test-cases/no-installable-mode)))
|
||||
(action
|
||||
(chdir
|
||||
test-cases/no-installable-mode
|
||||
(progn (run ${exe:cram.exe} -test run.t) (diff? run.t run.t.corrected))))))
|
||||
|
||||
(alias
|
||||
((name null-dep)
|
||||
(deps ((package dune) (files_recursively_in test-cases/null-dep)))
|
||||
|
@ -579,6 +588,7 @@
|
|||
(alias meta-gen)
|
||||
(alias misc)
|
||||
(alias multiple-private-libs)
|
||||
(alias no-installable-mode)
|
||||
(alias null-dep)
|
||||
(alias ocaml-syntax)
|
||||
(alias ocamldep-multi-stanzas)
|
||||
|
@ -639,6 +649,7 @@
|
|||
(alias merlin-tests)
|
||||
(alias meta-gen)
|
||||
(alias misc)
|
||||
(alias no-installable-mode)
|
||||
(alias null-dep)
|
||||
(alias ocaml-syntax)
|
||||
(alias ocamldep-multi-stanzas)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
(jbuild_version 1)
|
||||
|
||||
(executable
|
||||
(
|
||||
(name myprivatelib)
|
||||
(modes (shared_object))
|
||||
)
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
(jbuild_version 1)
|
||||
|
||||
(executable
|
||||
(
|
||||
(name mylib)
|
||||
(public_name mylib)
|
||||
(modes (shared_object))
|
||||
)
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
When a public executable is built in shared_object mode, a specific error
|
||||
message is displayed:
|
||||
|
||||
$ dune build --root=public --display=short
|
||||
File "jbuild", line 4, characters 2-74:
|
||||
Error: No installable mode found for this executable.
|
||||
One of the following modes is required:
|
||||
- exe
|
||||
- native
|
||||
- byte
|
||||
[1]
|
||||
|
||||
However, it is possible to build a private one explicitly.
|
||||
|
||||
$ dune build --root=private --display=short myprivatelib.so
|
||||
Entering directory 'private'
|
||||
ocamldep myprivatelib.ml.d
|
||||
ocamlc .myprivatelib.eobjs/myprivatelib.{cmi,cmo,cmt}
|
||||
ocamlopt .myprivatelib.eobjs/myprivatelib.{cmx,o}
|
||||
ocamlopt myprivatelib$ext_dll
|
|
@ -79,3 +79,13 @@
|
|||
(progn
|
||||
(run ${exe:expect_test.exe} ${<})
|
||||
(diff? ${<} ${<}.corrected))))))
|
||||
|
||||
(alias
|
||||
((name runtest)
|
||||
(deps (jbuild.mlt
|
||||
(glob_files ${SCOPE_ROOT}/src/.dune.objs/*.cmi)
|
||||
(glob_files ${SCOPE_ROOT}/src/stdune/.stdune.objs/*.cmi)))
|
||||
(action (chdir ${SCOPE_ROOT}
|
||||
(progn
|
||||
(run ${exe:expect_test.exe} ${<})
|
||||
(diff? ${<} ${<}.corrected))))))
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
open Dune;;
|
||||
open Stdune;;
|
||||
|
||||
#install_printer Jbuild.Mode_conf.pp;;
|
||||
#install_printer Binary_kind.pp;;
|
||||
#install_printer Sexp.pp;;
|
||||
|
||||
(* Jbuild.Executables.Link_mode.t *)
|
||||
let test s =
|
||||
Jbuild.Executables.Link_mode.t
|
||||
(Sexp.parse_string ~fname:"" ~mode:Sexp.Parser.Mode.Single s)
|
||||
[%%expect{|
|
||||
val test : string -> Dune.Jbuild.Executables.Link_mode.t = <fun>
|
||||
|}]
|
||||
|
||||
(* Link modes can be read as a (<mode> <kind>) list *)
|
||||
test "(best exe)"
|
||||
[%%expect{|
|
||||
- : Dune.Jbuild.Executables.Link_mode.t =
|
||||
{Dune.Jbuild.Executables.Link_mode.mode = best; kind = exe}
|
||||
|}]
|
||||
|
||||
(* Some shortcuts also exist *)
|
||||
test "exe"
|
||||
[%%expect{|
|
||||
- : Dune.Jbuild.Executables.Link_mode.t =
|
||||
{Dune.Jbuild.Executables.Link_mode.mode = best; kind = exe}
|
||||
|}]
|
||||
test "object"
|
||||
[%%expect{|
|
||||
- : Dune.Jbuild.Executables.Link_mode.t =
|
||||
{Dune.Jbuild.Executables.Link_mode.mode = best; kind = object}
|
||||
|}]
|
||||
test "shared_object"
|
||||
[%%expect{|
|
||||
- : Dune.Jbuild.Executables.Link_mode.t =
|
||||
{Dune.Jbuild.Executables.Link_mode.mode = best; kind = shared_object}
|
||||
|}]
|
||||
test "byte"
|
||||
[%%expect{|
|
||||
- : Dune.Jbuild.Executables.Link_mode.t =
|
||||
{Dune.Jbuild.Executables.Link_mode.mode = byte; kind = exe}
|
||||
|}]
|
||||
test "native"
|
||||
[%%expect{|
|
||||
- : Dune.Jbuild.Executables.Link_mode.t =
|
||||
{Dune.Jbuild.Executables.Link_mode.mode = native; kind = exe}
|
||||
|}]
|
||||
|
||||
(* Jbuild.Executables.Link_mode.sexp_of_t *)
|
||||
let test l =
|
||||
Jbuild.Executables.Link_mode.sexp_of_t l
|
||||
[%%expect{|
|
||||
val test : Dune.Jbuild.Executables.Link_mode.t -> Stdune__Sexp.t = <fun>
|
||||
|}]
|
||||
|
||||
(* In the general case, modes are serialized as a list *)
|
||||
test {Jbuild.Executables.Link_mode.kind = Shared_object; mode = Byte }
|
||||
[%%expect{|
|
||||
- : Stdune__Sexp.t = (byte shared_object)
|
||||
|}]
|
||||
|
||||
(* But the specialized ones are serialized in the minimal version *)
|
||||
test Jbuild.Executables.Link_mode.exe
|
||||
[%%expect{|
|
||||
- : Stdune__Sexp.t = exe
|
||||
|}]
|
Loading…
Reference in New Issue