This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
11
unikernel/duniverse/dune_/otherlibs/dune-site/src/dune
Normal file
11
unikernel/duniverse/dune_/otherlibs/dune-site/src/dune
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
(library
|
||||
(name dune_site)
|
||||
(public_name dune-site)
|
||||
(modules_without_implementation dune_site_data)
|
||||
; (private_modules dune_site_data)
|
||||
(special_builtin_support
|
||||
(dune_site
|
||||
(data_module dune_site_data)))
|
||||
(libraries
|
||||
(re_export dune-private-libs.dune-section)
|
||||
dune-site.private))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module Private_ = struct
|
||||
module Helpers = Helpers
|
||||
end
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(** {2 encoded} *)
|
||||
|
||||
val hardcoded_ocamlpath : string
|
||||
val stdlib_dir : string
|
||||
127
unikernel/duniverse/dune_/otherlibs/dune-site/src/helpers.ml
Normal file
127
unikernel/duniverse/dune_/otherlibs/dune-site/src/helpers.ml
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
open Dune_site_private
|
||||
|
||||
let path_sep = path_sep
|
||||
|
||||
module Location = struct
|
||||
type t = string
|
||||
end
|
||||
|
||||
let dirs : (string * Dune_section.t, string) Hashtbl.t = Hashtbl.create 10
|
||||
|
||||
(* multi-bindings first is the one with least priority *)
|
||||
|
||||
let () =
|
||||
match Sys.getenv_opt dune_dir_locations_env_var with
|
||||
| None -> ()
|
||||
| Some s ->
|
||||
(match decode_dune_dir_locations s with
|
||||
| None ->
|
||||
invalid_arg (Printf.sprintf "Invalid value %s=%S" dune_dir_locations_env_var s)
|
||||
| Some entries ->
|
||||
List.iter
|
||||
(fun { package; section; dir } -> Hashtbl.add dirs (package, section) dir)
|
||||
entries)
|
||||
;;
|
||||
|
||||
(* Parse the replacement format described in [artifact_substitution.ml]. *)
|
||||
let eval s =
|
||||
let len = String.length s in
|
||||
if s.[0] = '='
|
||||
then (
|
||||
let colon_pos = String.index_from s 1 ':' in
|
||||
let vlen = int_of_string (String.sub s 1 (colon_pos - 1)) in
|
||||
(* This [min] is because the value might have been truncated if it was too
|
||||
large *)
|
||||
let vlen = min vlen (len - colon_pos - 1) in
|
||||
Some (String.sub s (colon_pos + 1) vlen))
|
||||
else None
|
||||
[@@inline never]
|
||||
;;
|
||||
|
||||
let get_dir ~package ~section = Hashtbl.find_all dirs (package, section)
|
||||
|
||||
module Hardcoded_ocaml_path = struct
|
||||
type t =
|
||||
| None
|
||||
| Relocatable
|
||||
| Hardcoded of string list
|
||||
| Findlib_config of string
|
||||
|
||||
let t =
|
||||
lazy
|
||||
(match eval Dune_site_data.hardcoded_ocamlpath with
|
||||
| None -> None
|
||||
| Some "relocatable" -> Relocatable
|
||||
| Some s ->
|
||||
let l = String.split_on_char '\000' s in
|
||||
(match l with
|
||||
| "hardcoded" :: l -> Hardcoded l
|
||||
| [ "findlibconfig"; p ] -> Findlib_config p
|
||||
| _ -> invalid_arg "dune error: hardcoded_ocamlpath parsing error"))
|
||||
;;
|
||||
end
|
||||
|
||||
let relocatable =
|
||||
lazy
|
||||
(match Lazy.force Hardcoded_ocaml_path.t with
|
||||
| Relocatable -> true
|
||||
| _ -> false)
|
||||
;;
|
||||
|
||||
let prefix =
|
||||
lazy
|
||||
(let path = Sys.executable_name in
|
||||
let bin = Filename.dirname path in
|
||||
let prefix = Filename.dirname bin in
|
||||
prefix)
|
||||
;;
|
||||
|
||||
let relocate_if_needed path =
|
||||
if Lazy.force relocatable then Filename.concat (Lazy.force prefix) path else path
|
||||
;;
|
||||
|
||||
let site ~package ~section ~suffix ~encoded =
|
||||
let dirs = get_dir ~package ~section in
|
||||
let dirs =
|
||||
match eval encoded with
|
||||
| None -> dirs
|
||||
| Some d -> relocate_if_needed d :: dirs
|
||||
in
|
||||
List.rev_map (fun dir -> Filename.concat dir suffix) dirs
|
||||
[@@inline never]
|
||||
;;
|
||||
|
||||
let sourceroot local =
|
||||
match eval local with
|
||||
| Some "" -> None
|
||||
| Some _ as x -> x
|
||||
| None ->
|
||||
(* None if the binary is executed from _build but not by dune, which should
|
||||
not happen *)
|
||||
Sys.getenv_opt dune_sourceroot_env_var
|
||||
;;
|
||||
|
||||
let ocamlpath =
|
||||
lazy
|
||||
(let env =
|
||||
match Sys.getenv_opt "OCAMLPATH" with
|
||||
| None -> []
|
||||
| Some x -> String.split_on_char path_sep x
|
||||
in
|
||||
let static =
|
||||
match Lazy.force Hardcoded_ocaml_path.t with
|
||||
| Hardcoded_ocaml_path.None ->
|
||||
String.split_on_char path_sep (Sys.getenv dune_ocaml_hardcoded_env_var)
|
||||
| Hardcoded_ocaml_path.Relocatable -> [ Filename.concat (Lazy.force prefix) "lib" ]
|
||||
| Hardcoded_ocaml_path.Hardcoded l -> l
|
||||
| Hardcoded_ocaml_path.Findlib_config _ -> assert false
|
||||
in
|
||||
env @ static)
|
||||
;;
|
||||
|
||||
let stdlib =
|
||||
lazy
|
||||
(match eval Dune_site_data.stdlib_dir with
|
||||
| None -> Sys.getenv dune_ocaml_stdlib_env_var
|
||||
| Some s -> s)
|
||||
;;
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
(** Provide locations information *)
|
||||
|
||||
module Location : sig
|
||||
type t = string
|
||||
end
|
||||
|
||||
val site
|
||||
: package:string
|
||||
-> section:Dune_section.t
|
||||
-> suffix:string
|
||||
-> encoded:string
|
||||
-> Location.t list
|
||||
|
||||
val relocatable : bool Lazy.t
|
||||
val ocamlpath : string list Lazy.t
|
||||
val sourceroot : string -> string option
|
||||
val stdlib : string Lazy.t
|
||||
val path_sep : char
|
||||
|
||||
module Hardcoded_ocaml_path : sig
|
||||
type t =
|
||||
| None
|
||||
| Relocatable
|
||||
| Hardcoded of string list
|
||||
| Findlib_config of string
|
||||
|
||||
val t : t Lazy.t
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(library
|
||||
(name dune_site_plugins)
|
||||
(public_name dune-site.plugins)
|
||||
(modules_without_implementation dune_site_plugins_data)
|
||||
(special_builtin_support
|
||||
(dune_site
|
||||
(plugins)
|
||||
(data_module dune_site_plugins_data)))
|
||||
(libraries dune-site dune-private-libs.meta_parser dune-site.linker))
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
module Private_ = struct
|
||||
module Plugins = Plugins
|
||||
module Meta_parser = Meta_parser
|
||||
end
|
||||
|
||||
module V1 = struct
|
||||
let load = Plugins.load
|
||||
let available = Plugins.available
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
module V1 : sig
|
||||
(** [load name] loads the given library *)
|
||||
val load : string -> unit
|
||||
|
||||
(** [available name] tests if a library is available for loading. The loading
|
||||
can still fail if a dependency of the library is unavailable or if the
|
||||
loading of the modules fails. *)
|
||||
val available : string -> bool
|
||||
end
|
||||
|
||||
(** **/ *)
|
||||
|
||||
module Private_ : sig
|
||||
module Plugins : module type of Plugins
|
||||
module Meta_parser : module type of Meta_parser
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
(** {2 Data for the plugin system} *)
|
||||
|
||||
(** At link time dune create the implementation of the module. *)
|
||||
|
||||
(** Findlib predicates set true by dune. It is used during the interpretation of
|
||||
the metafile *)
|
||||
val findlib_predicates_set_by_dune : string -> bool
|
||||
|
||||
(** Library statically linked in the executable *)
|
||||
val already_linked_libraries : string list
|
||||
|
||||
(** Information about builtin libraries, such as the one installed by the OCaml
|
||||
compiler. The META file are not always present, so version reduced to the
|
||||
needed information are included here. *)
|
||||
val builtin_library : (string * Meta_parser.t) list
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(library
|
||||
(name dune_site_backend)
|
||||
(public_name dune-site.linker)
|
||||
; The linker module is virtual because it has two implementations
|
||||
; for load.
|
||||
; dune-site.dynlink implements it using Dynlink.loadfile
|
||||
; dune-site.toplevel implements it using
|
||||
; Topdirs.loadfile (before 4.13.0) or Toploop.loadfile (otherwise).
|
||||
; dune-site.toplevel is needed for OCaml toplevels with plugins.
|
||||
(virtual_modules linker)
|
||||
(default_implementation dune-site.dynlink))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(name dune_site_dynlink_linker)
|
||||
(public_name dune-site.dynlink)
|
||||
(implements dune-site.linker)
|
||||
(libraries dynlink))
|
||||
|
|
@ -0,0 +1 @@
|
|||
let load = Dynlink.loadfile
|
||||
|
|
@ -0,0 +1 @@
|
|||
val load : string -> unit
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(library
|
||||
(name dune_site_toplevel_linker)
|
||||
(modes byte)
|
||||
(public_name dune-site.toplevel)
|
||||
(implements dune-site.linker)
|
||||
(libraries compiler-libs.toplevel))
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
(*
|
||||
Prior to OCaml 4.13.0, [load_file] was in the Topdirs module.
|
||||
Beginning with OCaml 4.13.0, load_file is in the Toploop module.
|
||||
In order to be able to compile with OCaml versions either
|
||||
before or after, open both modules and let the compiler
|
||||
find [load_file] where it is defined.
|
||||
*)
|
||||
open Topdirs [@@ocaml.warning "-33"]
|
||||
open Toploop [@@ocaml.warning "-33"]
|
||||
|
||||
let load filename =
|
||||
let buf = Buffer.create 16 in
|
||||
let ppf = Format.formatter_of_buffer buf in
|
||||
match load_file ppf filename with
|
||||
| true -> ()
|
||||
| false ->
|
||||
Format.pp_print_flush ppf ();
|
||||
failwith
|
||||
@@ Format.asprintf "Failed to load file `%s': %s" filename (Buffer.contents buf)
|
||||
;;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
module Meta_parser = Dune_meta_parser.Meta_parser.Make (struct
|
||||
module Loc = struct
|
||||
type t = unit
|
||||
|
||||
let of_lexbuf _ = ()
|
||||
end
|
||||
|
||||
module Lib_name = struct
|
||||
type t = string
|
||||
|
||||
let parse_string_exn (_, n) = n
|
||||
end
|
||||
|
||||
module Pp = struct
|
||||
type 'tag t = string
|
||||
|
||||
let text s = s
|
||||
end
|
||||
|
||||
module User_message = struct
|
||||
module Style = struct
|
||||
type t = unit
|
||||
end
|
||||
|
||||
module Annots = struct
|
||||
type t = unit
|
||||
end
|
||||
end
|
||||
|
||||
module User_error = struct
|
||||
let raise ?loc:_ ?hints:_ ?annots:_ texts = invalid_arg (String.concat " " texts)
|
||||
end
|
||||
end)
|
||||
|
||||
include Meta_parser
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
type t =
|
||||
{ name : string option
|
||||
; entries : entry list
|
||||
}
|
||||
|
||||
and entry =
|
||||
| Comment of string
|
||||
| Rule of rule
|
||||
| Package of t
|
||||
|
||||
and rule =
|
||||
{ var : string
|
||||
; predicates : predicate list
|
||||
; action : action
|
||||
; value : string
|
||||
}
|
||||
|
||||
and action =
|
||||
| Set
|
||||
| Add
|
||||
|
||||
and predicate =
|
||||
| Pos of string
|
||||
| Neg of string
|
||||
|
||||
module Parse : sig
|
||||
val entries : Lexing.lexbuf -> int -> entry list -> entry list
|
||||
end
|
||||
|
|
@ -0,0 +1,317 @@
|
|||
open Dune_site.Private_
|
||||
module Data = Dune_site_plugins_data
|
||||
|
||||
let meta_fn = "META"
|
||||
|
||||
let readdir =
|
||||
let ( / ) = Filename.concat in
|
||||
let readdir_noexn dir =
|
||||
try Sys.readdir dir with
|
||||
| Sys_error _ -> [||]
|
||||
in
|
||||
fun dirs ->
|
||||
List.concat
|
||||
(List.map
|
||||
(fun dir ->
|
||||
List.filter
|
||||
(fun entry -> Sys.file_exists (dir / entry / meta_fn))
|
||||
(Array.to_list (readdir_noexn dir)))
|
||||
dirs)
|
||||
;;
|
||||
|
||||
let rec lookup dirs file =
|
||||
match dirs with
|
||||
| [] -> None
|
||||
| dir :: dirs ->
|
||||
let file' = Filename.concat dir file in
|
||||
if Sys.file_exists file' then Some file' else lookup dirs file
|
||||
;;
|
||||
|
||||
module type S = sig
|
||||
val paths : string list
|
||||
val list : unit -> string list
|
||||
val load_all : unit -> unit
|
||||
val load : string -> unit
|
||||
end
|
||||
|
||||
let rec check_predicates predicates =
|
||||
match Sys.backend_type, predicates with
|
||||
| _, [] -> true
|
||||
| Sys.Native, Meta_parser.Pos "byte" :: _ -> false
|
||||
| Sys.Bytecode, Meta_parser.Pos "native" :: _ -> false
|
||||
| Sys.Native, Meta_parser.Pos "native" :: predicates -> check_predicates predicates
|
||||
| Sys.Bytecode, Meta_parser.Pos "byte" :: predicates -> check_predicates predicates
|
||||
| Sys.Native, Meta_parser.Neg "native" :: _ -> false
|
||||
| Sys.Bytecode, Meta_parser.Neg "byte" :: _ -> false
|
||||
| Sys.Native, Meta_parser.Neg "byte" :: predicates -> check_predicates predicates
|
||||
| Sys.Bytecode, Meta_parser.Neg "native" :: predicates -> check_predicates predicates
|
||||
| _, Meta_parser.Pos pred :: predicates ->
|
||||
Data.findlib_predicates_set_by_dune pred && check_predicates predicates
|
||||
| _, Meta_parser.Neg pred :: predicates ->
|
||||
(not (Data.findlib_predicates_set_by_dune pred)) && check_predicates predicates
|
||||
;;
|
||||
|
||||
let check_predicates_with_plugin predicates =
|
||||
let rec aux predicates has_plugin acc =
|
||||
match predicates with
|
||||
| [] -> has_plugin && check_predicates acc
|
||||
| Meta_parser.Pos "plugin" :: predicates -> aux predicates true acc
|
||||
| predicate :: predicates -> aux predicates has_plugin (predicate :: acc)
|
||||
in
|
||||
aux predicates false []
|
||||
;;
|
||||
|
||||
let rec get_plugin plugins requires entries =
|
||||
match entries with
|
||||
| [] -> List.rev plugins, List.rev requires
|
||||
| Meta_parser.Comment _ :: entries -> get_plugin plugins requires entries
|
||||
| Package _ :: entries -> get_plugin plugins requires entries
|
||||
| Rule { var = "plugin"; predicates; action = Set; value } :: entries
|
||||
when check_predicates predicates -> get_plugin [ value ] requires entries
|
||||
| Rule { var = "plugin"; predicates; action = Add; value } :: entries
|
||||
when check_predicates predicates -> get_plugin (value :: plugins) requires entries
|
||||
(* archive(native|byte,plugin) is the way used in the wild before findlib
|
||||
supported plugins *)
|
||||
| Rule { var = "archive"; predicates; action = Set; value } :: entries
|
||||
when check_predicates_with_plugin predicates -> get_plugin [ value ] requires entries
|
||||
| Rule { var = "archive"; predicates; action = Add; value } :: entries
|
||||
when check_predicates_with_plugin predicates ->
|
||||
get_plugin (value :: plugins) requires entries
|
||||
| Rule { var = "requires"; predicates; action = Set; value } :: entries
|
||||
when check_predicates predicates -> get_plugin plugins [ value ] entries
|
||||
| Rule { var = "requires"; predicates; action = Add; value } :: entries
|
||||
when check_predicates predicates -> get_plugin plugins (value :: requires) entries
|
||||
| Rule _ :: entries -> get_plugin plugins requires entries
|
||||
;;
|
||||
|
||||
exception Thread_library_required_by_plugin_but_not_required_by_main_executable
|
||||
|
||||
exception
|
||||
Library_not_found of
|
||||
{ search_paths : string list
|
||||
; prefix : string list
|
||||
; name : string
|
||||
}
|
||||
|
||||
exception
|
||||
Plugin_not_found of
|
||||
{ search_paths : string list
|
||||
; name : string
|
||||
}
|
||||
|
||||
let () =
|
||||
Printexc.register_printer (function
|
||||
| Thread_library_required_by_plugin_but_not_required_by_main_executable ->
|
||||
Some
|
||||
(Format.asprintf
|
||||
"%a"
|
||||
Format.pp_print_text
|
||||
"It is not possible to dynamically link a plugin which uses the thread \
|
||||
library with an executable not already linked with the thread library.")
|
||||
| Plugin_not_found { search_paths; name } ->
|
||||
Some
|
||||
(Format.sprintf
|
||||
"The plugin %S can't be found in the search paths %S."
|
||||
name
|
||||
(String.concat ":" search_paths))
|
||||
| Library_not_found { search_paths; prefix = []; name } ->
|
||||
Some
|
||||
(Format.sprintf
|
||||
"The library %S can't be found in the search paths %S."
|
||||
name
|
||||
(String.concat ":" search_paths))
|
||||
| Library_not_found { search_paths; prefix; name } ->
|
||||
Some
|
||||
(Format.sprintf
|
||||
"The sub-library %S can't be found in the library %s in the search paths %S."
|
||||
name
|
||||
(String.concat "." prefix)
|
||||
(String.concat ":" search_paths))
|
||||
| _ -> None)
|
||||
;;
|
||||
|
||||
let rec find_library ~dirs ~prefix ~suffix directory meta =
|
||||
let rec find_directory directory = function
|
||||
| [] -> directory
|
||||
| Meta_parser.Rule { var = "directory"; predicates = []; action = Set; value } :: _ ->
|
||||
(match directory with
|
||||
| None -> Some value
|
||||
| Some old -> Some (Filename.concat old value))
|
||||
| _ :: entries -> find_directory directory entries
|
||||
in
|
||||
match suffix with
|
||||
| [] -> find_directory directory meta, meta
|
||||
| pkg :: suffix ->
|
||||
let directory = find_directory directory meta in
|
||||
let rec aux pkg = function
|
||||
| [] ->
|
||||
raise
|
||||
(Library_not_found { search_paths = dirs; prefix = List.rev prefix; name = pkg })
|
||||
| Meta_parser.Package { name = Some name; entries } :: _ when String.equal name pkg
|
||||
-> find_library ~dirs ~prefix:(pkg :: prefix) ~suffix directory entries
|
||||
| _ :: entries -> aux pkg entries
|
||||
in
|
||||
aux pkg meta
|
||||
;;
|
||||
|
||||
let extract_words s ~is_word_char =
|
||||
let rec skip_blanks i =
|
||||
if i = String.length s
|
||||
then []
|
||||
else if is_word_char s.[i]
|
||||
then parse_word i (i + 1)
|
||||
else skip_blanks (i + 1)
|
||||
and parse_word i j =
|
||||
if j = String.length s
|
||||
then [ StringLabels.sub s ~pos:i ~len:(j - i) ]
|
||||
else if is_word_char s.[j]
|
||||
then parse_word i (j + 1)
|
||||
else StringLabels.sub s ~pos:i ~len:(j - i) :: skip_blanks (j + 1)
|
||||
in
|
||||
skip_blanks 0
|
||||
;;
|
||||
|
||||
let extract_comma_space_separated_words s =
|
||||
extract_words s ~is_word_char:(function
|
||||
| ',' | ' ' | '\t' | '\n' -> false
|
||||
| _ -> true)
|
||||
;;
|
||||
|
||||
let split_all l = List.concat (List.map extract_comma_space_separated_words l)
|
||||
|
||||
let find_plugin ~dirs ~dir ~suffix (meta : Meta_parser.t) =
|
||||
let directory, meta =
|
||||
find_library ~dirs ~prefix:(Option.to_list meta.name) ~suffix None meta.entries
|
||||
in
|
||||
let plugins, requires = get_plugin [] [] meta in
|
||||
let directory =
|
||||
match directory with
|
||||
| None -> dir
|
||||
| Some pkg_dir ->
|
||||
if pkg_dir.[0] = '+' || pkg_dir.[0] = '^'
|
||||
then
|
||||
Filename.concat
|
||||
(Lazy.force Helpers.stdlib)
|
||||
(String.sub pkg_dir 1 (String.length pkg_dir - 1))
|
||||
else if Filename.is_relative pkg_dir
|
||||
then Filename.concat dir pkg_dir
|
||||
else pkg_dir
|
||||
in
|
||||
let plugins = split_all plugins in
|
||||
let requires = split_all requires in
|
||||
directory, plugins, requires
|
||||
;;
|
||||
|
||||
let load file ~pkg =
|
||||
let entries =
|
||||
let ic = open_in file in
|
||||
try
|
||||
let lb = Lexing.from_channel ic in
|
||||
lb.lex_curr_p <- { pos_fname = file; pos_lnum = 1; pos_bol = 0; pos_cnum = 0 };
|
||||
let r = Meta_parser.Parse.entries lb 0 [] in
|
||||
close_in ic;
|
||||
r
|
||||
with
|
||||
| exn ->
|
||||
close_in ic;
|
||||
raise exn
|
||||
in
|
||||
{ Meta_parser.name = Some pkg; entries }
|
||||
;;
|
||||
|
||||
let lookup_and_load_one_dir ~dir ~pkg =
|
||||
let meta_file = Filename.concat dir meta_fn in
|
||||
if Sys.file_exists meta_file
|
||||
then Some (load meta_file ~pkg)
|
||||
else (
|
||||
(* Alternative layout *)
|
||||
let dir = Filename.dirname dir in
|
||||
let meta_file = Filename.concat dir (meta_fn ^ "." ^ pkg) in
|
||||
if Sys.file_exists meta_file then Some (load meta_file ~pkg) else None)
|
||||
;;
|
||||
|
||||
let split ~dirs name =
|
||||
match String.split_on_char '.' name with
|
||||
| [] -> raise (Library_not_found { search_paths = dirs; prefix = []; name })
|
||||
| pkg :: rest -> pkg, rest
|
||||
;;
|
||||
|
||||
let lookup_and_summarize alldirs name =
|
||||
let pkg, suffix = split ~dirs:alldirs name in
|
||||
let rec loop dirs =
|
||||
match dirs with
|
||||
| [] ->
|
||||
List.assoc_opt pkg Data.builtin_library
|
||||
|> (function
|
||||
| None -> raise (Library_not_found { search_paths = alldirs; prefix = []; name })
|
||||
| Some meta ->
|
||||
find_plugin ~dirs:alldirs ~dir:(Lazy.force Helpers.stdlib) ~suffix meta)
|
||||
| dir :: dirs ->
|
||||
let dir = Filename.concat dir pkg in
|
||||
(match lookup_and_load_one_dir ~dir ~pkg with
|
||||
| None -> loop dirs
|
||||
| Some p -> find_plugin ~dirs:alldirs ~dir ~suffix p)
|
||||
in
|
||||
loop alldirs
|
||||
;;
|
||||
|
||||
let loaded_libraries =
|
||||
lazy
|
||||
(let h = Hashtbl.create 10 in
|
||||
List.iter (fun s -> Hashtbl.add h s ()) Data.already_linked_libraries;
|
||||
h)
|
||||
;;
|
||||
|
||||
let load_gen ~load_requires dirs name =
|
||||
let loaded_libraries = Lazy.force loaded_libraries in
|
||||
if not (Hashtbl.mem loaded_libraries name)
|
||||
then (
|
||||
if name = "threads"
|
||||
then raise Thread_library_required_by_plugin_but_not_required_by_main_executable;
|
||||
Hashtbl.add loaded_libraries name ();
|
||||
let directory, plugins, requires = lookup_and_summarize dirs name in
|
||||
List.iter load_requires requires;
|
||||
List.iter
|
||||
(fun p ->
|
||||
let file = Filename.concat directory p in
|
||||
Dune_site_backend.Linker.load file)
|
||||
plugins)
|
||||
;;
|
||||
|
||||
let rec load_requires name = load_gen ~load_requires (Lazy.force Helpers.ocamlpath) name
|
||||
|
||||
let load_plugin plugin_paths name =
|
||||
match lookup plugin_paths (Filename.concat name meta_fn) with
|
||||
| None -> raise (Plugin_not_found { search_paths = plugin_paths; name })
|
||||
| Some meta_file ->
|
||||
let meta = load meta_file ~pkg:name in
|
||||
let plugins, requires = get_plugin [] [] meta.entries in
|
||||
assert (plugins = []);
|
||||
let requires = split_all requires in
|
||||
List.iter load_requires requires
|
||||
;;
|
||||
|
||||
module Make (X : sig
|
||||
val paths : string list
|
||||
end) : S = struct
|
||||
include X
|
||||
|
||||
let list () = List.sort String.compare (readdir paths)
|
||||
let load name = load_plugin paths name
|
||||
let load_all () = List.iter load (list ())
|
||||
end
|
||||
|
||||
let load = load_requires
|
||||
|
||||
let available name =
|
||||
Hashtbl.mem (Lazy.force loaded_libraries) name
|
||||
||
|
||||
let ocamlpath = Lazy.force Helpers.ocamlpath in
|
||||
try
|
||||
ignore (lookup_and_summarize ocamlpath name);
|
||||
true
|
||||
with
|
||||
| _ ->
|
||||
(* CR - What exceptions are being swallowed here? *)
|
||||
false
|
||||
;;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
module type S = sig
|
||||
(** The signature of the modules present in the module generated by the stanza
|
||||
generate_sites_module *)
|
||||
|
||||
val paths : string list
|
||||
val list : unit -> string list
|
||||
val load_all : unit -> unit
|
||||
val load : string -> unit
|
||||
end
|
||||
|
||||
(** The functor applied in the generated module *)
|
||||
module Make (_ : sig
|
||||
val paths : string list
|
||||
end) : S
|
||||
|
||||
(** Load a library *)
|
||||
val load : string -> unit
|
||||
|
||||
(** Indicates if a library exists in the search path *)
|
||||
val available : string -> bool
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(library
|
||||
(name dune_site_private)
|
||||
(libraries dune-private-libs.dune-section)
|
||||
(public_name dune-site.private))
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
(* TODO already exists in stdune/bin.ml *)
|
||||
let path_sep = if Sys.win32 then ';' else ':'
|
||||
let dune_dir_locations_env_var = "DUNE_DIR_LOCATIONS"
|
||||
let dune_ocaml_stdlib_env_var = "DUNE_OCAML_STDLIB"
|
||||
let dune_ocaml_hardcoded_env_var = "DUNE_OCAML_HARDCODED"
|
||||
let dune_sourceroot_env_var = "DUNE_SOURCEROOT"
|
||||
|
||||
type entry =
|
||||
{ package : string
|
||||
; section : Dune_section.t
|
||||
; dir : string
|
||||
}
|
||||
|
||||
let decode_dune_dir_locations =
|
||||
let rec aux acc = function
|
||||
| [] -> Some (List.rev acc)
|
||||
| package :: section :: dir :: l ->
|
||||
let section =
|
||||
match Dune_section.of_string section with
|
||||
| None -> invalid_arg ("Dune-site: Unknown section " ^ section)
|
||||
| Some s -> s
|
||||
in
|
||||
aux ({ package; section; dir } :: acc) l
|
||||
| _ -> None
|
||||
in
|
||||
fun s ->
|
||||
let l = String.split_on_char path_sep s in
|
||||
aux [] l
|
||||
;;
|
||||
|
||||
let encode_dune_dir_locations =
|
||||
let add b { package; section; dir } =
|
||||
Buffer.add_string b package;
|
||||
Buffer.add_char b path_sep;
|
||||
Buffer.add_string b (Dune_section.to_string section);
|
||||
Buffer.add_char b path_sep;
|
||||
Buffer.add_string b dir
|
||||
in
|
||||
let rec loop b = function
|
||||
| [] -> ()
|
||||
| [ x ] -> add b x
|
||||
| x :: xs ->
|
||||
add b x;
|
||||
Buffer.add_char b path_sep;
|
||||
loop b xs
|
||||
in
|
||||
fun s ->
|
||||
let b = Buffer.create 16 in
|
||||
loop b s;
|
||||
Buffer.contents b
|
||||
;;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
val path_sep : char
|
||||
val dune_dir_locations_env_var : string
|
||||
val dune_ocaml_stdlib_env_var : string
|
||||
val dune_ocaml_hardcoded_env_var : string
|
||||
val dune_sourceroot_env_var : string
|
||||
|
||||
type entry =
|
||||
{ package : string
|
||||
; section : Dune_section.t
|
||||
; dir : string
|
||||
}
|
||||
|
||||
val decode_dune_dir_locations : string -> entry list option
|
||||
val encode_dune_dir_locations : entry list -> string
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
Test when sites name which are ocaml keyword
|
||||
---------------------------------
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 2.9)
|
||||
> (using dune_site 0.1)
|
||||
> (package
|
||||
> (name my-package)
|
||||
> (sites (lib include)))
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (library (name lib) (libraries dune-site dune-site.plugins))
|
||||
>
|
||||
> (generate_sites_module
|
||||
> (module sites)
|
||||
> (plugins (my-package include)))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
16
unikernel/duniverse/dune_/otherlibs/dune-site/test/dune
Normal file
16
unikernel/duniverse/dune_/otherlibs/dune-site/test/dune
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(cram
|
||||
(applies_to :whole_subtree)
|
||||
(deps
|
||||
(package dune)
|
||||
(package dune-site)))
|
||||
|
||||
; The test being broken on CI, we deactivate it when
|
||||
; we detect that the CI environment variable is not
|
||||
; set. Most CI systems set it.
|
||||
|
||||
(cram
|
||||
(applies_to run_2_9 run)
|
||||
(enabled_if
|
||||
(and
|
||||
(not %{env:CI=false})
|
||||
(not %{env:INSIDE_NIX=false}))))
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(executable
|
||||
(name main)
|
||||
(public_name main)
|
||||
(promote (until-clean))
|
||||
(libraries dune-build-info dune-site))
|
||||
|
||||
(generate_sites_module
|
||||
(module SitesModule)
|
||||
(sites github4389))
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(lang dune 2.9)
|
||||
(using dune_site 0.1)
|
||||
|
||||
(package
|
||||
(name github4389)
|
||||
(sites (share github4389)))
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
let version =
|
||||
match Build_info.V1.version () with
|
||||
| None -> "n/a"
|
||||
| Some v -> Build_info.V1.Version.to_string v
|
||||
|
||||
let () =
|
||||
Format.eprintf "%s@." version;
|
||||
List.iter
|
||||
(fun x -> Format.eprintf "%s@." x)
|
||||
SitesModule.Sites.github4389
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
$ dune build @install
|
||||
$ dune install --prefix _install --display short
|
||||
Installing _install/lib/github4389/META
|
||||
Installing _install/lib/github4389/dune-package
|
||||
Installing _install/bin/main
|
||||
$ grep sites _install/lib/github4389/dune-package
|
||||
(sites (github4389 share))
|
||||
$ grep -o '[^ ]*/_install/share/github4389' _install/lib/github4389/dune-package
|
||||
$TESTCASE_ROOT/_install/share/github4389
|
||||
$ _install/bin/main
|
||||
n/a
|
||||
$TESTCASE_ROOT/_install/share/github4389/github4389
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(executable
|
||||
(name main)
|
||||
(public_name main)
|
||||
(promote (until-clean))
|
||||
(libraries dune-site))
|
||||
|
||||
(generate_sites_module
|
||||
(module SitesModule)
|
||||
(sites github4389))
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(lang dune 2.9)
|
||||
(using dune_site 0.1)
|
||||
|
||||
(package
|
||||
(name github4389)
|
||||
(sites (share github4389)))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
let () =
|
||||
List.iter
|
||||
(fun x -> Format.eprintf "%s@." x)
|
||||
SitesModule.Sites.github4389
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
$ dune build @install
|
||||
$ dune install --prefix _install --display short
|
||||
Installing _install/lib/github4389/META
|
||||
Installing _install/lib/github4389/dune-package
|
||||
Installing _install/bin/main
|
||||
$ grep sites _install/lib/github4389/dune-package
|
||||
(sites (github4389 share))
|
||||
$ grep -o '[^ ]*/_install/share/github4389' _install/lib/github4389/dune-package
|
||||
$TESTCASE_ROOT/_install/share/github4389
|
||||
$ _install/bin/main
|
||||
$TESTCASE_ROOT/_install/share/github4389/github4389
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
This checks that generated sites files correctly substituted with `dune install`.
|
||||
|
||||
See #10317.
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.0)
|
||||
> (using dune_site 0.1)
|
||||
> (package
|
||||
> (name a)
|
||||
> (sites (share data)))
|
||||
> EOF
|
||||
|
||||
$ cat > dune << EOF
|
||||
> (library
|
||||
> (public_name a)
|
||||
> (libraries dune-site))
|
||||
> (generate_sites_module
|
||||
> (module s)
|
||||
> (sites a))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
|
||||
$ check_placeholder() {
|
||||
> name=$1;
|
||||
> if grep -q DUNE_PLACEHOLDER "$name"; then
|
||||
> echo placeholder found in $name
|
||||
> fi
|
||||
> }
|
||||
|
||||
The generated module has placeholders.
|
||||
|
||||
$ check_placeholder _build/default/S.ml
|
||||
placeholder found in _build/default/S.ml
|
||||
|
||||
$ dune install a --prefix out/ --datadir /nonexistent/data
|
||||
|
||||
We expect no placeholders to be present after installation.
|
||||
|
||||
$ find out -type f | sort | while read f ; do check_placeholder $f ; done
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
Test an approximation of an OPAM install / uninstall of a plugin package
|
||||
|
||||
This takes the sites-plugin.t blackbox test extracted from the manual and
|
||||
changes its end to cover:
|
||||
- dune install of both the application and its plugin,
|
||||
- dune uninstall of the plugin, leaving an empty directory as OPAM would.
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.8)
|
||||
> (using dune_site 0.1)
|
||||
> (name app)
|
||||
>
|
||||
> (package
|
||||
> (name app)
|
||||
> (sites (lib plugins)))
|
||||
> EOF
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (executable
|
||||
> (public_name app)
|
||||
> (modules sites app)
|
||||
> (libraries app.register dune-site dune-site.plugins))
|
||||
>
|
||||
> (library
|
||||
> (public_name app.register)
|
||||
> (name registration)
|
||||
> (modules registration))
|
||||
>
|
||||
> (generate_sites_module
|
||||
> (module sites)
|
||||
> (plugins (app plugins)))
|
||||
> EOF
|
||||
|
||||
$ cat > registration.ml <<EOF
|
||||
> let todo : (unit -> unit) Queue.t = Queue.create ()
|
||||
> EOF
|
||||
|
||||
$ cat > app.ml <<EOF
|
||||
> (* load all the available plugins *)
|
||||
> let () = Sites.Plugins.Plugins.load_all ()
|
||||
>
|
||||
> let () = print_endline "Main app starts..."
|
||||
> (* Execute the code registered by the plugins *)
|
||||
> let () = Queue.iter (fun f -> f ()) Registration.todo
|
||||
> EOF
|
||||
|
||||
|
||||
$ mkdir plugin
|
||||
$ cat > plugin/dune-project <<EOF
|
||||
> (lang dune 3.8)
|
||||
> (using dune_site 0.1)
|
||||
>
|
||||
> (generate_opam_files true)
|
||||
>
|
||||
> (package
|
||||
> (name plugin1))
|
||||
> EOF
|
||||
|
||||
$ cat > plugin/dune <<EOF
|
||||
> (library
|
||||
> (public_name plugin1.plugin1_impl)
|
||||
> (name plugin1_impl)
|
||||
> (modules plugin1_impl)
|
||||
> (libraries app.register))
|
||||
>
|
||||
> (plugin
|
||||
> (name plugin1)
|
||||
> (libraries plugin1.plugin1_impl)
|
||||
> (site (app plugins)))
|
||||
> EOF
|
||||
|
||||
$ cat > plugin/plugin1_impl.ml <<EOF
|
||||
> let () =
|
||||
> print_endline "Registration of Plugin1";
|
||||
> Queue.add (fun () -> print_endline "Plugin1 is doing something...") Registration.todo
|
||||
> EOF
|
||||
|
||||
$ dune build @install
|
||||
$ dune install --prefix _install
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH _install/bin/app
|
||||
Registration of Plugin1
|
||||
Main app starts...
|
||||
Plugin1 is doing something...
|
||||
|
||||
$ dune uninstall --prefix _install plugin1
|
||||
|
||||
Unfortunately, the fact that the `lib/app/plugins/plugin1` directory should be
|
||||
removed along with plugin1 is lost in the OPAM metadata, so we simulate this
|
||||
issue by recreating this empty directory.
|
||||
|
||||
$ mkdir -p _install/lib/app/plugins/plugin1
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH _install/bin/app
|
||||
Main app starts...
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
(* load all the available plugins *)
|
||||
let () =
|
||||
try
|
||||
Sites.Plugins.Plugins.load_all ()
|
||||
with exn ->
|
||||
Printf.printf "Error during dynamic linking: %s" (Printexc.to_string exn)
|
||||
|
||||
let () = print_endline "Main app starts..."
|
||||
(* Execute the code registered by the plugins *)
|
||||
let () = Queue.iter (fun f -> f ()) Registration.todo
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
(executable
|
||||
(public_name app)
|
||||
(modules sites app)
|
||||
(libraries
|
||||
app.register
|
||||
dune-site
|
||||
dune-site.plugins
|
||||
;TOREMOVE threads
|
||||
))
|
||||
|
||||
(library
|
||||
(public_name app.register)
|
||||
(name registration)
|
||||
(modules registration))
|
||||
|
||||
(generate_sites_module
|
||||
(module sites)
|
||||
(plugins
|
||||
(app plugins)))
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(lang dune 2.8)
|
||||
(using dune_site 0.1)
|
||||
|
||||
(name app)
|
||||
|
||||
(package
|
||||
(name app)
|
||||
(sites (lib plugins)))
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(env (_ (flags -w -33)))
|
||||
|
||||
(library
|
||||
(public_name plugin1.plugin1_impl)
|
||||
(name plugin1_impl)
|
||||
(modules plugin1_impl)
|
||||
(libraries app.MyControls app.register result threads))
|
||||
|
||||
(plugin
|
||||
(name plugin1)
|
||||
(libraries threads plugin1.plugin1_impl)
|
||||
(site (app plugins)))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(lang dune 2.8)
|
||||
(using dune_site 0.1)
|
||||
|
||||
(generate_opam_files true)
|
||||
|
||||
(package
|
||||
(name plugin1))
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
depends: [
|
||||
"dune" {>= "2.8"}
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
]
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
let () =
|
||||
let open Result in
|
||||
print_endline "Registration of Plugin1";
|
||||
Queue.add (fun () ->
|
||||
let th = Thread.create (fun () ->
|
||||
print_endline "Plugin1 is doing something...") () in
|
||||
Thread.join th
|
||||
) Registration.todo
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
(env
|
||||
(_
|
||||
(flags -w -33)))
|
||||
|
||||
(library
|
||||
(public_name plugin2.plugin2_impl)
|
||||
(name plugin2_impl)
|
||||
(modules plugin2_impl)
|
||||
(libraries app.MyControls app.register result threads))
|
||||
|
||||
(plugin
|
||||
(name plugin2)
|
||||
(libraries threads plugin2.plugin2_impl)
|
||||
(site
|
||||
(app plugins)))
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(lang dune 2.8)
|
||||
|
||||
(using dune_site 0.1)
|
||||
|
||||
(generate_opam_files true)
|
||||
|
||||
(package
|
||||
(name plugin2))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
let () =
|
||||
print_endline "Registration of Plugin2";
|
||||
Queue.add (fun () -> print_endline "Plugin2 is doing something...") Registration.todo
|
||||
|
|
@ -0,0 +1 @@
|
|||
let todo : (unit -> unit) Queue.t = Queue.create ()
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
$ dune build ./app.exe @install
|
||||
$ dune exec ./app.exe
|
||||
The library is being used by two plugins finished initialization
|
||||
Error during dynamic linking: It is not possible to dynamically link a plugin which uses the thread library
|
||||
with an executable not already linked with the thread
|
||||
library.Main app starts...
|
||||
|
||||
$ sed -e "s/;TOREMOVE//" dune > dune.tmp
|
||||
$ mv -f dune.tmp dune
|
||||
|
||||
$ dune build ./app.exe @install
|
||||
$ dune exec ./app.exe
|
||||
The library is being used by two plugins finished initialization
|
||||
Registration of Plugin1
|
||||
Registration of Plugin2
|
||||
Main app starts...
|
||||
Plugin1 is doing something...
|
||||
Plugin2 is doing something...
|
||||
|
|
@ -0,0 +1 @@
|
|||
let () = print_endline "The library is being used by two plugins finished initialization"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(public_name app.MyControls)
|
||||
(name MyControls)
|
||||
(modules MyControls)
|
||||
(libraries))
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
$ mkdir -p b c
|
||||
|
||||
$ for i in b; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (package (name $i) (depends c))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ for i in c; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (package (name $i) (sites (share data) (lib plugins)))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ cat >b/dune <<EOF
|
||||
> (library
|
||||
> (public_name b.b.b)
|
||||
> (name b)
|
||||
> (libraries c.register dune-site))
|
||||
> (generate_sites_module (module sites) (sites b))
|
||||
> (plugin (name c-plugins-b.b) (libraries b.b.b) (site (c plugins)))
|
||||
> EOF
|
||||
|
||||
$ cat >b/b.ml <<EOF
|
||||
> let v = "b"
|
||||
> let () = Printf.printf "run b\n%!"
|
||||
> let () = C_register.registered := "b"::!C_register.registered
|
||||
> EOF
|
||||
|
||||
$ cat >c/dune <<EOF
|
||||
> (executable
|
||||
> (public_name c)
|
||||
> (promote (until-clean))
|
||||
> (modules c sites)
|
||||
> (libraries c.register dune-site dune-site.plugins))
|
||||
> (library
|
||||
> (public_name c.register)
|
||||
> (name c_register)
|
||||
> (modules c_register))
|
||||
> (generate_sites_module (module sites) (plugins (c plugins)))
|
||||
> (rule
|
||||
> (targets out.log)
|
||||
> (deps (package c))
|
||||
> (action (with-stdout-to out.log (run %{bin:c} "c-plugins-b.b"))))
|
||||
> EOF
|
||||
|
||||
$ cat >c/c_register.ml <<EOF
|
||||
> let registered : string list ref = ref []
|
||||
> EOF
|
||||
|
||||
$ cat >c/c.ml <<EOF
|
||||
> let () = try Sites.Plugins.Plugins.load Sys.argv.(1)
|
||||
> with exn -> print_endline (Printexc.to_string exn)
|
||||
> let () = Printf.printf "run c: registered:%s.\n%!" (String.concat "," !C_register.registered)
|
||||
> EOF
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 2.2)
|
||||
> EOF
|
||||
|
||||
Build everything
|
||||
----------------
|
||||
|
||||
$ dune build
|
||||
|
||||
Test with dune exec
|
||||
--------------------------------
|
||||
$ dune exec -- c/c.exe "c-plugins-b.b"
|
||||
run b
|
||||
run c: registered:b.
|
||||
|
||||
Test error messages
|
||||
--------------------------------
|
||||
$ dune exec -- c/c.exe "inexistent"
|
||||
The plugin "inexistent" can't be found in the search paths "$TESTCASE_ROOT/_build/install/default/lib/c/plugins".
|
||||
run c: registered:.
|
||||
|
||||
$ cat >c/c.ml <<EOF
|
||||
> let l = Lazy.force Dune_site.Private_.Helpers.ocamlpath
|
||||
> let l = List.map (Printf.sprintf "OCAMLPATH=%s") l
|
||||
> let () = print_string (String.concat ":" l)
|
||||
> EOF
|
||||
|
||||
$ export BUILD_PATH_PREFIX_MAP="$(dune exe -- c/c.exe):$BUILD_PATH_PREFIX_MAP"
|
||||
|
||||
$ cat >c/c.ml <<EOF
|
||||
> let () = try Dune_site_plugins.V1.load Sys.argv.(1)
|
||||
> with exn -> print_endline (Printexc.to_string exn)
|
||||
> EOF
|
||||
|
||||
$ dune exec -- c/c.exe "inexistent" 2>&1 | sed -e 's&default/lib:.*&default/lib:..."&g'
|
||||
The library "inexistent" can't be found in the search paths "$TESTCASE_ROOT/_build/install/default/lib:..."
|
||||
|
||||
$ dune exec -- c/c.exe "b.b.b"
|
||||
run b
|
||||
|
||||
$ dune exec -- c/c.exe "b.b.inexistent" 2>&1 | sed -e 's&default/lib:.*&default/lib:..."&g'
|
||||
The sub-library "inexistent" can't be found in the library b.b in the search paths "$TESTCASE_ROOT/_build/install/default/lib:..."
|
||||
481
unikernel/duniverse/dune_/otherlibs/dune-site/test/run.t
Normal file
481
unikernel/duniverse/dune_/otherlibs/dune-site/test/run.t
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
Test embedding of sites locations information
|
||||
-----------------------------------
|
||||
|
||||
$ mkdir -p a b c
|
||||
|
||||
$ mkdir -p a
|
||||
|
||||
$ cat >a/dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (generate_opam_files true)
|
||||
> (using dune_site 0.1)
|
||||
> (name a)
|
||||
> (version 0.a)
|
||||
> (package (name a) (sites (share data)))
|
||||
> EOF
|
||||
|
||||
$ for i in b d; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (generate_opam_files true)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (version 0.$i)
|
||||
> (package (name $i) (sites (share data)) (depends c))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ for i in c; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (generate_opam_files true)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (package (name $i) (sites (share data) (lib plugins)) (depends a))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ cat >a/dune <<EOF
|
||||
> (library
|
||||
> (public_name a)
|
||||
> (libraries dune-site))
|
||||
> (generate_sites_module (module sites) (sites a))
|
||||
> EOF
|
||||
|
||||
$ cat >a/a.ml <<EOF
|
||||
> let v = "a"
|
||||
> let () = Printf.printf "run a\n%!"
|
||||
> let () = List.iter (Printf.printf "a: %s\n%!") Sites.Sites.data
|
||||
> EOF
|
||||
|
||||
$ cat >b/dune <<EOF
|
||||
> (library
|
||||
> (public_name b.b.b)
|
||||
> (name b)
|
||||
> (libraries c.register dune-site))
|
||||
> (generate_sites_module (module sites) (sites b))
|
||||
> (plugin (name c-plugins-b) (libraries b.b.b) (site (c plugins)))
|
||||
> (install (section (site (b data))) (files info.txt))
|
||||
> EOF
|
||||
|
||||
$ cat >b/b.ml <<EOF
|
||||
> let v = "b"
|
||||
> let () = Printf.printf "run b\n%!"
|
||||
> let () = C_register.registered := "b"::!C_register.registered
|
||||
> let () = List.iter (Printf.printf "b: %s\n%!") Sites.Sites.data
|
||||
> let () =
|
||||
> let test d = Sys.file_exists (Filename.concat d "info.txt") in
|
||||
> let found = List.exists test Sites.Sites.data in
|
||||
> Printf.printf "info.txt is found: %b\n%!" found
|
||||
> EOF
|
||||
|
||||
$ cat >b/info.txt <<EOF
|
||||
> Lorem
|
||||
> EOF
|
||||
|
||||
$ cat >d/dune <<EOF
|
||||
> (library
|
||||
> (public_name d)
|
||||
> (libraries c.register dune-site non-existent-library)
|
||||
> (optional))
|
||||
> (generate_sites_module (module sites) (sites d))
|
||||
> (plugin (name c-plugins-d) (libraries d) (site (c plugins)) (optional))
|
||||
> (install (section (site (d data))) (files info.txt))
|
||||
> EOF
|
||||
|
||||
$ cat >d/d.ml <<EOF
|
||||
> let v = "d"
|
||||
> let () = Printf.printf "run d\n%!"
|
||||
> let () = C_register.registered := "d"::!C_register.registered
|
||||
> let () = List.iter (Printf.printf "d: %s\n%!") Sites.Sites.data
|
||||
> let () =
|
||||
> let test d = Sys.file_exists (Filename.concat d "info.txt") in
|
||||
> let found = List.exists test Sites.Sites.data in
|
||||
> Printf.printf "info.txt is found: %d\n%!" found
|
||||
> EOF
|
||||
|
||||
$ cat >d/info.txt <<EOF
|
||||
> Lorem
|
||||
> EOF
|
||||
|
||||
|
||||
$ cat >c/dune <<EOF
|
||||
> (executable
|
||||
> (public_name c)
|
||||
> (promote (until-clean))
|
||||
> (modules c sites)
|
||||
> (libraries a c.register dune-site dune-site.plugins))
|
||||
> (library
|
||||
> (public_name c.register)
|
||||
> (name c_register)
|
||||
> (modules c_register))
|
||||
> (generate_sites_module (module sites) (sourceroot) (plugins (c plugins)))
|
||||
> (rule
|
||||
> (targets out.log)
|
||||
> (deps (package c))
|
||||
> (action (with-stdout-to out.log (run %{bin:c}))))
|
||||
> EOF
|
||||
|
||||
$ cat >c/c_register.ml <<EOF
|
||||
> let registered : string list ref = ref []
|
||||
> EOF
|
||||
|
||||
$ cat >c/c.ml <<EOF
|
||||
> let () = Printf.printf "run c: %s linked registered:%s.\n%!"
|
||||
> A.v (String.concat "," !C_register.registered)
|
||||
> let () = match Sites.sourceroot with
|
||||
> | Some d -> Printf.printf "sourceroot is %S\n%!" d
|
||||
> | None -> Printf.printf "no sourceroot\n%!"
|
||||
> let () = List.iter (Printf.printf "c: %s\n%!") Sites.Sites.data
|
||||
> let () = Printf.printf "b is available: %b\n%!" (Dune_site_plugins.V1.available "b")
|
||||
> let () = Sites.Plugins.Plugins.load_all ()
|
||||
> let () = Printf.printf "run c: registered:%s.\n%!" (String.concat "," !C_register.registered)
|
||||
> EOF
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 2.2)
|
||||
> EOF
|
||||
|
||||
|
||||
Test with an opam like installation
|
||||
--------------------------------
|
||||
|
||||
$ dune build a/a.opam
|
||||
|
||||
#We print the generated file in order to update the following tests
|
||||
$ cat a/a.opam
|
||||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
version: "0.a"
|
||||
depends: [
|
||||
"dune" {>= "3.0"}
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"--promote-install-files=false"
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
["dune" "install" "-p" name "--create-install-files" name]
|
||||
]
|
||||
|
||||
$ dune build -p a --promote-install-files=false @install
|
||||
|
||||
$ test -e a/a.install
|
||||
[1]
|
||||
|
||||
$ dune install -p a --create-install-files a --prefix "_destdir"
|
||||
|
||||
$ cat a/a.install
|
||||
lib: [
|
||||
"_destdir/_destdir/lib/a/META"
|
||||
"_destdir/_destdir/lib/a/Sites.ml"
|
||||
"_destdir/_destdir/lib/a/a.a"
|
||||
"_destdir/_destdir/lib/a/a.cma"
|
||||
"_build/install/default/lib/a/a.cmi"
|
||||
"_build/install/default/lib/a/a.cmt"
|
||||
"_build/install/default/lib/a/a.cmx"
|
||||
"_build/install/default/lib/a/a.cmxa"
|
||||
"_build/install/default/lib/a/a.ml"
|
||||
"_build/install/default/lib/a/a__.cmi"
|
||||
"_build/install/default/lib/a/a__.cmt"
|
||||
"_build/install/default/lib/a/a__.cmx"
|
||||
"_build/install/default/lib/a/a__.ml"
|
||||
"_build/install/default/lib/a/a__Sites.cmi"
|
||||
"_build/install/default/lib/a/a__Sites.cmt"
|
||||
"_build/install/default/lib/a/a__Sites.cmx"
|
||||
"_destdir/_destdir/lib/a/dune-package"
|
||||
"_build/install/default/lib/a/opam"
|
||||
]
|
||||
libexec: [
|
||||
"_destdir/_destdir/lib/a/a.cmxs"
|
||||
]
|
||||
|
||||
Build everything
|
||||
----------------
|
||||
|
||||
$ dune build
|
||||
|
||||
Test with a normal installation
|
||||
--------------------------------
|
||||
|
||||
$ dune install --prefix _install
|
||||
|
||||
Once installed, we have the sites information:
|
||||
|
||||
$ grep share/a _install/lib/a/dune-package
|
||||
$TESTCASE_ROOT/_install/share/a))
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH _install/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
Test with a relocatable installation
|
||||
--------------------------------
|
||||
|
||||
$ dune install --prefix _install_relocatable --relocatable
|
||||
|
||||
Once installed, we have the sites information:
|
||||
|
||||
$ _install_relocatable/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install_relocatable/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install_relocatable/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install_relocatable/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
Test after moving a relocatable installation
|
||||
--------------------------------
|
||||
|
||||
$ mv _install_relocatable _install_relocatable2
|
||||
|
||||
Once installed, we have the sites information:
|
||||
|
||||
$ _install_relocatable2/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install_relocatable2/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install_relocatable2/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install_relocatable2/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
Test substitution when promoting
|
||||
--------------------------------
|
||||
|
||||
It is wrong that info.txt is not found, but to make it work it is an important
|
||||
development because b is not promoted
|
||||
|
||||
$ c/c.exe
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
info.txt is found: false
|
||||
run c: registered:b.
|
||||
|
||||
Test within dune rules
|
||||
--------------------------------
|
||||
$ dune build c/out.log
|
||||
|
||||
$ cat _build/default/c/out.log
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_build/install/default/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
|
||||
Test with dune exec
|
||||
--------------------------------
|
||||
$ dune exec -- c/c.exe
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_build/install/default/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
|
||||
Test compiling an external plugin
|
||||
---------------------------------
|
||||
$ mkdir e
|
||||
$ cat >e/dune-project <<EOF
|
||||
> (lang dune 2.8)
|
||||
> (using dune_site 0.1)
|
||||
> (name e)
|
||||
> (package (name e) (sites (share data)))
|
||||
> EOF
|
||||
|
||||
$ cat >e/dune <<EOF
|
||||
> (library
|
||||
> (public_name e)
|
||||
> (libraries c.register dune-site))
|
||||
> (generate_sites_module (module sites) (sites e))
|
||||
> (plugin (name c-plugins-e) (libraries e) (site (c plugins)))
|
||||
> (install (section (site (e data))) (files info.txt))
|
||||
> (rule (alias runtest) (deps (package a) (package b) (package c) (package d) (package e))
|
||||
> (action (run %{bin:c})))
|
||||
> EOF
|
||||
|
||||
$ cat >e/e.ml <<EOF
|
||||
> let v = "e"
|
||||
> let () = Printf.printf "run e\n%!"
|
||||
> let () = C_register.registered := "e"::!C_register.registered
|
||||
> let () = List.iter (Printf.printf "e: %s\n%!") Sites.Sites.data
|
||||
> let () =
|
||||
> let test d = Sys.file_exists (Filename.concat d "info.txt") in
|
||||
> let found = List.exists test Sites.Sites.data in
|
||||
> Printf.printf "info.txt is found: %b\n%!" found
|
||||
> EOF
|
||||
|
||||
$ cat >e/info.txt <<EOF
|
||||
> Lorem
|
||||
> EOF
|
||||
|
||||
$ OCAMLPATH=$(pwd)/_install/lib:$OCAMLPATH dune build --root=e
|
||||
Entering directory 'e'
|
||||
Leaving directory 'e'
|
||||
|
||||
$ OCAMLPATH=$(pwd)/_install/lib:$OCAMLPATH PATH=$(pwd)/_install/bin:$PATH dune exec --root=e -- c
|
||||
Entering directory 'e'
|
||||
Leaving directory 'e'
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install/share/b/data
|
||||
info.txt is found: true
|
||||
run e
|
||||
e: $TESTCASE_ROOT/e/_build/install/default/share/e/data
|
||||
info.txt is found: true
|
||||
run c: registered:e,b.
|
||||
|
||||
$ OCAMLPATH=$(pwd)/_install/lib:$OCAMLPATH dune install --root=e --prefix $(pwd)/_install
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH _install/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install/share/b/data
|
||||
info.txt is found: true
|
||||
run e
|
||||
e: $TESTCASE_ROOT/_install/share/e/data
|
||||
info.txt is found: true
|
||||
run c: registered:e,b.
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH dune build @runtest
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_build/install/default/share/b/data
|
||||
info.txt is found: true
|
||||
run e
|
||||
e: $TESTCASE_ROOT/_build/install/default/share/e/data
|
||||
info.txt is found: true
|
||||
run c: registered:e,b.
|
||||
|
||||
Test %{version:installed-pkg}
|
||||
-----------------------------
|
||||
|
||||
$ for i in f; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (version 0.$i)
|
||||
> (package (name $i) (sites (share data) (lib plugins)) (allow_empty))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ cat >f/dune <<EOF
|
||||
> (rule
|
||||
> (target test.target)
|
||||
> (action
|
||||
> (with-stdout-to %{target}
|
||||
> (progn
|
||||
> (echo "a = %{version:a}\n")
|
||||
> (echo "e = %{version:e}\n")))))
|
||||
> EOF
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH dune build --root=f
|
||||
Entering directory 'f'
|
||||
Leaving directory 'f'
|
||||
$ cat $(pwd)/f/_build/default/test.target
|
||||
a = 0.a
|
||||
e =
|
||||
|
||||
$ cat f/dune | sed 's/version:a/version:a.test/' > f/dune.tmp && mv f/dune.tmp f/dune
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH dune build --root=f
|
||||
Entering directory 'f'
|
||||
File "dune", line 6, characters 15-32:
|
||||
6 | (echo "a = %{version:a.test}\n")
|
||||
^^^^^^^^^^^^^^^^^
|
||||
Error: Library names are not allowed in this position. Only package names are
|
||||
allowed
|
||||
Leaving directory 'f'
|
||||
[1]
|
||||
|
||||
$ rm f/dune
|
||||
|
||||
Test error location
|
||||
---------------------------------
|
||||
|
||||
$ cat >>a/dune <<EOF
|
||||
> (install
|
||||
> (section (site (non-existent foo)))
|
||||
> (files a.ml)
|
||||
> )
|
||||
> EOF
|
||||
|
||||
$ dune build @install
|
||||
File "a/dune", line 6, characters 16-34:
|
||||
6 | (section (site (non-existent foo)))
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Error: The package non-existent is not found
|
||||
[1]
|
||||
|
||||
$ cat >a/dune <<EOF
|
||||
> (library
|
||||
> (public_name a)
|
||||
> (libraries dune-site))
|
||||
> (generate_sites_module (module sites) (sites non-existent))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
File "a/dune", line 4, characters 45-57:
|
||||
4 | (generate_sites_module (module sites) (sites non-existent))
|
||||
^^^^^^^^^^^^
|
||||
Error: Unknown package
|
||||
[1]
|
||||
466
unikernel/duniverse/dune_/otherlibs/dune-site/test/run_2_9.t
Normal file
466
unikernel/duniverse/dune_/otherlibs/dune-site/test/run_2_9.t
Normal file
|
|
@ -0,0 +1,466 @@
|
|||
Test embedding of sites locations information
|
||||
-----------------------------------
|
||||
|
||||
$ mkdir -p a b c
|
||||
|
||||
$ for i in a b d; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 2.9)
|
||||
> (generate_opam_files true)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (version 0.$i)
|
||||
> (package (name $i) (sites (share data)))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ for i in c; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 2.9)
|
||||
> (generate_opam_files true)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (package (name $i) (sites (share data) (lib plugins)))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ cat >a/dune <<EOF
|
||||
> (library
|
||||
> (public_name a)
|
||||
> (libraries dune-site))
|
||||
> (generate_sites_module (module sites) (sites a))
|
||||
> EOF
|
||||
|
||||
$ cat >a/a.ml <<EOF
|
||||
> let v = "a"
|
||||
> let () = Printf.printf "run a\n%!"
|
||||
> let () = List.iter (Printf.printf "a: %s\n%!") Sites.Sites.data
|
||||
> EOF
|
||||
|
||||
$ cat >b/dune <<EOF
|
||||
> (library
|
||||
> (public_name b.b.b)
|
||||
> (name b)
|
||||
> (libraries c.register dune-site))
|
||||
> (generate_sites_module (module sites) (sites b))
|
||||
> (plugin (name c-plugins-b) (libraries b.b.b) (site (c plugins)))
|
||||
> (install (section (site (b data))) (files info.txt))
|
||||
> EOF
|
||||
|
||||
$ cat >b/b.ml <<EOF
|
||||
> let v = "b"
|
||||
> let () = Printf.printf "run b\n%!"
|
||||
> let () = C_register.registered := "b"::!C_register.registered
|
||||
> let () = List.iter (Printf.printf "b: %s\n%!") Sites.Sites.data
|
||||
> let () =
|
||||
> let test d = Sys.file_exists (Filename.concat d "info.txt") in
|
||||
> let found = List.exists test Sites.Sites.data in
|
||||
> Printf.printf "info.txt is found: %b\n%!" found
|
||||
> EOF
|
||||
|
||||
$ cat >b/info.txt <<EOF
|
||||
> Lorem
|
||||
> EOF
|
||||
|
||||
$ cat >d/dune <<EOF
|
||||
> (library
|
||||
> (public_name d)
|
||||
> (libraries c.register dune-site non-existent-library)
|
||||
> (optional))
|
||||
> (generate_sites_module (module sites) (sites d))
|
||||
> (plugin (name c-plugins-d) (libraries d) (site (c plugins)) (optional))
|
||||
> (install (section (site (d data))) (files info.txt))
|
||||
> EOF
|
||||
|
||||
$ cat >d/d.ml <<EOF
|
||||
> let v = "d"
|
||||
> let () = Printf.printf "run d\n%!"
|
||||
> let () = C_register.registered := "d"::!C_register.registered
|
||||
> let () = List.iter (Printf.printf "d: %s\n%!") Sites.Sites.data
|
||||
> let () =
|
||||
> let test d = Sys.file_exists (Filename.concat d "info.txt") in
|
||||
> let found = List.exists test Sites.Sites.data in
|
||||
> Printf.printf "info.txt is found: %d\n%!" found
|
||||
> EOF
|
||||
|
||||
$ cat >d/info.txt <<EOF
|
||||
> Lorem
|
||||
> EOF
|
||||
|
||||
|
||||
$ cat >c/dune <<EOF
|
||||
> (executable
|
||||
> (public_name c)
|
||||
> (promote (until-clean))
|
||||
> (modules c sites)
|
||||
> (libraries a c.register dune-site dune-site.plugins))
|
||||
> (library
|
||||
> (public_name c.register)
|
||||
> (name c_register)
|
||||
> (modules c_register))
|
||||
> (generate_sites_module (module sites) (sourceroot) (plugins (c plugins)))
|
||||
> (rule
|
||||
> (targets out.log)
|
||||
> (deps (package c))
|
||||
> (action (with-stdout-to out.log (run %{bin:c}))))
|
||||
> EOF
|
||||
|
||||
$ cat >c/c_register.ml <<EOF
|
||||
> let registered : string list ref = ref []
|
||||
> EOF
|
||||
|
||||
$ cat >c/c.ml <<EOF
|
||||
> let () = Printf.printf "run c: %s linked registered:%s.\n%!"
|
||||
> A.v (String.concat "," !C_register.registered)
|
||||
> let () = match Sites.sourceroot with
|
||||
> | Some d -> Printf.printf "sourceroot is %S\n%!" d
|
||||
> | None -> Printf.printf "no sourceroot\n%!"
|
||||
> let () = List.iter (Printf.printf "c: %s\n%!") Sites.Sites.data
|
||||
> let () = Printf.printf "b is available: %b\n%!" (Dune_site_plugins.V1.available "b")
|
||||
> let () = Sites.Plugins.Plugins.load_all ()
|
||||
> let () = Printf.printf "run c: registered:%s.\n%!" (String.concat "," !C_register.registered)
|
||||
> EOF
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 2.2)
|
||||
> EOF
|
||||
|
||||
|
||||
Test with an opam like installation
|
||||
--------------------------------
|
||||
|
||||
$ dune build a/a.opam
|
||||
|
||||
$ cat a/a.opam
|
||||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
version: "0.a"
|
||||
depends: [
|
||||
"dune" {>= "2.9"}
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"--promote-install-files=false"
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
["dune" "install" "-p" name "--create-install-files" name]
|
||||
]
|
||||
|
||||
$ dune build -p a --promote-install-files="false" @install
|
||||
|
||||
$ test -e a/a.install
|
||||
[1]
|
||||
|
||||
$ dune install -p a --create-install-files a --prefix "_destdir"
|
||||
|
||||
$ cat a/a.install
|
||||
lib: [
|
||||
"_destdir/_destdir/lib/a/META"
|
||||
"_destdir/_destdir/lib/a/Sites.ml"
|
||||
"_destdir/_destdir/lib/a/a.a"
|
||||
"_destdir/_destdir/lib/a/a.cma"
|
||||
"_build/install/default/lib/a/a.cmi"
|
||||
"_build/install/default/lib/a/a.cmt"
|
||||
"_build/install/default/lib/a/a.cmx"
|
||||
"_build/install/default/lib/a/a.cmxa"
|
||||
"_build/install/default/lib/a/a.ml"
|
||||
"_build/install/default/lib/a/a__.cmi"
|
||||
"_build/install/default/lib/a/a__.cmt"
|
||||
"_build/install/default/lib/a/a__.cmx"
|
||||
"_build/install/default/lib/a/a__.ml"
|
||||
"_build/install/default/lib/a/a__Sites.cmi"
|
||||
"_build/install/default/lib/a/a__Sites.cmt"
|
||||
"_build/install/default/lib/a/a__Sites.cmx"
|
||||
"_destdir/_destdir/lib/a/dune-package"
|
||||
"_build/install/default/lib/a/opam"
|
||||
]
|
||||
libexec: [
|
||||
"_destdir/_destdir/lib/a/a.cmxs"
|
||||
]
|
||||
|
||||
Build everything
|
||||
----------------
|
||||
|
||||
$ dune build
|
||||
|
||||
Test with a normal installation
|
||||
--------------------------------
|
||||
|
||||
$ dune install --prefix _install
|
||||
|
||||
Once installed, we have the sites information:
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH _install/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
Test with a relocatable installation
|
||||
--------------------------------
|
||||
|
||||
$ dune install --prefix _install_relocatable --relocatable
|
||||
|
||||
Once installed, we have the sites information:
|
||||
|
||||
$ _install_relocatable/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install_relocatable/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install_relocatable/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install_relocatable/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
Test after moving a relocatable installation
|
||||
--------------------------------
|
||||
|
||||
$ mv _install_relocatable _install_relocatable2
|
||||
|
||||
Once installed, we have the sites information:
|
||||
|
||||
$ _install_relocatable2/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install_relocatable2/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install_relocatable2/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install_relocatable2/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
Test substitution when promoting
|
||||
--------------------------------
|
||||
|
||||
It is wrong that info.txt is not found, but to make it work it is an important
|
||||
development because b is not promoted
|
||||
|
||||
$ c/c.exe
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
info.txt is found: false
|
||||
run c: registered:b.
|
||||
|
||||
Test within dune rules
|
||||
--------------------------------
|
||||
$ dune build c/out.log
|
||||
|
||||
$ cat _build/default/c/out.log
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_build/install/default/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
|
||||
Test with dune exec
|
||||
--------------------------------
|
||||
$ dune exec -- c/c.exe
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_build/install/default/share/b/data
|
||||
info.txt is found: true
|
||||
run c: registered:b.
|
||||
|
||||
|
||||
Test compiling an external plugin
|
||||
---------------------------------
|
||||
$ mkdir e
|
||||
$ cat >e/dune-project <<EOF
|
||||
> (lang dune 2.8)
|
||||
> (using dune_site 0.1)
|
||||
> (name e)
|
||||
> (package (name e) (sites (share data)))
|
||||
> EOF
|
||||
|
||||
$ cat >e/dune <<EOF
|
||||
> (library
|
||||
> (public_name e)
|
||||
> (libraries c.register dune-site))
|
||||
> (generate_sites_module (module sites) (sites e))
|
||||
> (plugin (name c-plugins-e) (libraries e) (site (c plugins)))
|
||||
> (install (section (site (e data))) (files info.txt))
|
||||
> (rule (alias runtest) (deps (package a) (package b) (package c) (package d) (package e))
|
||||
> (action (run %{bin:c})))
|
||||
> EOF
|
||||
|
||||
$ cat >e/e.ml <<EOF
|
||||
> let v = "e"
|
||||
> let () = Printf.printf "run e\n%!"
|
||||
> let () = C_register.registered := "e"::!C_register.registered
|
||||
> let () = List.iter (Printf.printf "e: %s\n%!") Sites.Sites.data
|
||||
> let () =
|
||||
> let test d = Sys.file_exists (Filename.concat d "info.txt") in
|
||||
> let found = List.exists test Sites.Sites.data in
|
||||
> Printf.printf "info.txt is found: %b\n%!" found
|
||||
> EOF
|
||||
|
||||
$ cat >e/info.txt <<EOF
|
||||
> Lorem
|
||||
> EOF
|
||||
|
||||
$ OCAMLPATH=$PWD/_install/lib:$OCAMLPATH dune build --root=e
|
||||
Entering directory 'e'
|
||||
Leaving directory 'e'
|
||||
|
||||
$ OCAMLPATH=$PWD/_install/lib:$OCAMLPATH PATH=$PWD/_install/bin:$PATH dune exec --root=e -- c
|
||||
Entering directory 'e'
|
||||
Leaving directory 'e'
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install/share/b/data
|
||||
info.txt is found: true
|
||||
run e
|
||||
e: $TESTCASE_ROOT/e/_build/install/default/share/e/data
|
||||
info.txt is found: true
|
||||
run c: registered:e,b.
|
||||
|
||||
$ OCAMLPATH=$PWD/_install/lib:$OCAMLPATH dune install --root=e --prefix $PWD/_install
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH _install/bin/c
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_install/share/a/data
|
||||
run c: a linked registered:.
|
||||
no sourceroot
|
||||
c: $TESTCASE_ROOT/_install/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_install/share/b/data
|
||||
info.txt is found: true
|
||||
run e
|
||||
e: $TESTCASE_ROOT/_install/share/e/data
|
||||
info.txt is found: true
|
||||
run c: registered:e,b.
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH dune build @runtest
|
||||
run a
|
||||
a: $TESTCASE_ROOT/_build/install/default/share/a/data
|
||||
run c: a linked registered:.
|
||||
sourceroot is "$TESTCASE_ROOT"
|
||||
c: $TESTCASE_ROOT/_build/install/default/share/c/data
|
||||
b is available: true
|
||||
run b
|
||||
b: $TESTCASE_ROOT/_build/install/default/share/b/data
|
||||
info.txt is found: true
|
||||
run e
|
||||
e: $TESTCASE_ROOT/_build/install/default/share/e/data
|
||||
info.txt is found: true
|
||||
run c: registered:e,b.
|
||||
|
||||
Test %{version:installed-pkg}
|
||||
-----------------------------
|
||||
|
||||
$ for i in f; do
|
||||
> mkdir -p $i
|
||||
> cat >$i/dune-project <<EOF
|
||||
> (lang dune 2.9)
|
||||
> (using dune_site 0.1)
|
||||
> (name $i)
|
||||
> (version 0.$i)
|
||||
> (package (name $i) (sites (share data) (lib plugins)))
|
||||
> EOF
|
||||
> done
|
||||
|
||||
$ cat >f/dune <<EOF
|
||||
> (rule
|
||||
> (target test.target)
|
||||
> (action
|
||||
> (with-stdout-to %{target}
|
||||
> (progn
|
||||
> (echo "a = %{version:a}\n")
|
||||
> (echo "e = %{version:e}\n")))))
|
||||
> EOF
|
||||
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH dune build --root=f
|
||||
Entering directory 'f'
|
||||
Leaving directory 'f'
|
||||
$ cat $PWD/f/_build/default/test.target
|
||||
a = 0.a
|
||||
e =
|
||||
|
||||
$ cat f/dune | sed 's/version:a/version:a.test/' > f/dune.tmp && mv f/dune.tmp f/dune
|
||||
$ OCAMLPATH=_install/lib:$OCAMLPATH dune build --root=f
|
||||
Entering directory 'f'
|
||||
File "dune", line 6, characters 15-32:
|
||||
6 | (echo "a = %{version:a.test}\n")
|
||||
^^^^^^^^^^^^^^^^^
|
||||
Error: Library names are not allowed in this position. Only package names are
|
||||
allowed
|
||||
Leaving directory 'f'
|
||||
[1]
|
||||
|
||||
$ rm f/dune
|
||||
|
||||
Test error location
|
||||
---------------------------------
|
||||
|
||||
$ cat >>a/dune <<EOF
|
||||
> (install
|
||||
> (section (site (non-existent foo)))
|
||||
> (files a.ml)
|
||||
> )
|
||||
> EOF
|
||||
|
||||
$ dune build @install
|
||||
File "a/dune", line 6, characters 16-34:
|
||||
6 | (section (site (non-existent foo)))
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Error: The package non-existent is not found
|
||||
[1]
|
||||
|
||||
$ cat >a/dune <<EOF
|
||||
> (library
|
||||
> (public_name a)
|
||||
> (libraries dune-site))
|
||||
> (generate_sites_module (module sites) (sites non-existent))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
File "a/dune", line 4, characters 45-57:
|
||||
4 | (generate_sites_module (module sites) (sites non-existent))
|
||||
^^^^^^^^^^^^
|
||||
Error: Unknown package
|
||||
[1]
|
||||
Loading…
Add table
Add a link
Reference in a new issue