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
|
; "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]
|
let all = [Exe; Object; Shared_object]
|
||||||
|
|
|
@ -9,4 +9,8 @@ type t =
|
||||||
|
|
||||||
val t : t Sexp.Of_sexp.t
|
val t : t Sexp.Of_sexp.t
|
||||||
|
|
||||||
|
val sexp_of_t : t Sexp.To_sexp.t
|
||||||
|
|
||||||
val all : t list
|
val all : t list
|
||||||
|
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
|
|
@ -608,6 +608,17 @@ module Mode_conf = struct
|
||||||
; "best" , Best
|
; "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
|
module Set = struct
|
||||||
include Set.Make(T)
|
include Set.Make(T)
|
||||||
|
|
||||||
|
@ -796,15 +807,19 @@ module Executables = struct
|
||||||
let byte = byte_exe
|
let byte = byte_exe
|
||||||
let native = native_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 simple =
|
||||||
let open Sexp.Of_sexp in
|
Sexp.Of_sexp.enum simple_representations
|
||||||
enum
|
|
||||||
[ "exe" , exe
|
|
||||||
; "object" , object_
|
|
||||||
; "shared_object" , shared_object
|
|
||||||
; "byte" , byte
|
|
||||||
; "native" , native
|
|
||||||
]
|
|
||||||
|
|
||||||
let t sexp =
|
let t sexp =
|
||||||
match sexp with
|
match sexp with
|
||||||
|
@ -813,6 +828,21 @@ module Executables = struct
|
||||||
{ mode; kind }
|
{ mode; kind }
|
||||||
| _ -> simple sexp
|
| _ -> 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
|
module Set = struct
|
||||||
include Set.Make(T)
|
include Set.Make(T)
|
||||||
|
|
||||||
|
@ -837,14 +867,7 @@ module Executables = struct
|
||||||
]
|
]
|
||||||
|
|
||||||
let best_install_mode t =
|
let best_install_mode t =
|
||||||
if mem t exe then
|
List.find ~f:(mem t) installable_modes
|
||||||
Some exe
|
|
||||||
else if mem t native then
|
|
||||||
Some native
|
|
||||||
else if mem t byte then
|
|
||||||
Some byte
|
|
||||||
else
|
|
||||||
None
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -879,8 +902,21 @@ module Executables = struct
|
||||||
; buildable
|
; buildable
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
|
let has_public_name =
|
||||||
|
List.exists ~f:Option.is_some public_names
|
||||||
|
in
|
||||||
let to_install =
|
let to_install =
|
||||||
match Link_mode.Set.best_install_mode t.modes with
|
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 -> []
|
| None -> []
|
||||||
| Some mode ->
|
| Some mode ->
|
||||||
let ext =
|
let ext =
|
||||||
|
|
|
@ -171,6 +171,7 @@ module Mode_conf : sig
|
||||||
|
|
||||||
val t : t Sexp.Of_sexp.t
|
val t : t Sexp.Of_sexp.t
|
||||||
val compare : t -> t -> Ordering.t
|
val compare : t -> t -> Ordering.t
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
|
||||||
module Set : sig
|
module Set : sig
|
||||||
include Set.S with type elt = t
|
include Set.S with type elt = t
|
||||||
|
@ -240,6 +241,9 @@ module Executables : sig
|
||||||
; kind : Binary_kind.t
|
; kind : Binary_kind.t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val t : t Sexp.Of_sexp.t
|
||||||
|
val sexp_of_t : t Sexp.To_sexp.t
|
||||||
|
|
||||||
val exe : t
|
val exe : t
|
||||||
val object_ : t
|
val object_ : t
|
||||||
val shared_object : t
|
val shared_object : t
|
||||||
|
|
|
@ -372,6 +372,15 @@
|
||||||
(run ${exe:cram.exe} -skip-versions 4.02.3 -test run.t)
|
(run ${exe:cram.exe} -skip-versions 4.02.3 -test run.t)
|
||||||
(diff? run.t run.t.corrected))))))
|
(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
|
(alias
|
||||||
((name null-dep)
|
((name null-dep)
|
||||||
(deps ((package dune) (files_recursively_in test-cases/null-dep)))
|
(deps ((package dune) (files_recursively_in test-cases/null-dep)))
|
||||||
|
@ -579,6 +588,7 @@
|
||||||
(alias meta-gen)
|
(alias meta-gen)
|
||||||
(alias misc)
|
(alias misc)
|
||||||
(alias multiple-private-libs)
|
(alias multiple-private-libs)
|
||||||
|
(alias no-installable-mode)
|
||||||
(alias null-dep)
|
(alias null-dep)
|
||||||
(alias ocaml-syntax)
|
(alias ocaml-syntax)
|
||||||
(alias ocamldep-multi-stanzas)
|
(alias ocamldep-multi-stanzas)
|
||||||
|
@ -639,6 +649,7 @@
|
||||||
(alias merlin-tests)
|
(alias merlin-tests)
|
||||||
(alias meta-gen)
|
(alias meta-gen)
|
||||||
(alias misc)
|
(alias misc)
|
||||||
|
(alias no-installable-mode)
|
||||||
(alias null-dep)
|
(alias null-dep)
|
||||||
(alias ocaml-syntax)
|
(alias ocaml-syntax)
|
||||||
(alias ocamldep-multi-stanzas)
|
(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
|
(progn
|
||||||
(run ${exe:expect_test.exe} ${<})
|
(run ${exe:expect_test.exe} ${<})
|
||||||
(diff? ${<} ${<}.corrected))))))
|
(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