Merge branch 'master' into subsystem-versioned
This commit is contained in:
commit
7a91a2b23b
|
@ -106,6 +106,8 @@ next
|
||||||
|
|
||||||
- Add `%{profile}` variable. (#938, @rgrinberg)
|
- Add `%{profile}` variable. (#938, @rgrinberg)
|
||||||
|
|
||||||
|
- Do not require opam-installer anymore (#941, @diml)
|
||||||
|
|
||||||
1.0+beta20 (10/04/2018)
|
1.0+beta20 (10/04/2018)
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
85
bin/main.ml
85
bin/main.ml
|
@ -1053,16 +1053,6 @@ let rules =
|
||||||
& Arg.info [] ~docv:"TARGET"))
|
& Arg.info [] ~docv:"TARGET"))
|
||||||
, Term.info "rules" ~doc ~man)
|
, Term.info "rules" ~doc ~man)
|
||||||
|
|
||||||
let opam_installer () =
|
|
||||||
match Bin.which "opam-installer" with
|
|
||||||
| None ->
|
|
||||||
die "\
|
|
||||||
Sorry, you need the opam-installer tool to be able to install or
|
|
||||||
uninstall packages.
|
|
||||||
|
|
||||||
I couldn't find the opam-installer binary :-("
|
|
||||||
| Some fn -> fn
|
|
||||||
|
|
||||||
let get_prefix context ~from_command_line =
|
let get_prefix context ~from_command_line =
|
||||||
match from_command_line with
|
match from_command_line with
|
||||||
| Some p -> Fiber.return (Path.of_string p)
|
| Some p -> Fiber.return (Path.of_string p)
|
||||||
|
@ -1073,6 +1063,16 @@ let get_libdir context ~libdir_from_command_line =
|
||||||
| Some p -> Fiber.return (Some (Path.of_string p))
|
| Some p -> Fiber.return (Some (Path.of_string p))
|
||||||
| None -> Context.install_ocaml_libdir context
|
| None -> Context.install_ocaml_libdir context
|
||||||
|
|
||||||
|
let print_unix_error f =
|
||||||
|
try
|
||||||
|
f ()
|
||||||
|
with Unix.Unix_error (e, _, _) ->
|
||||||
|
Format.eprintf "@{<error>Error@}: %s@."
|
||||||
|
(Unix.error_message e)
|
||||||
|
|
||||||
|
let set_executable_bits x = x lor 0o111
|
||||||
|
let clear_executable_bits x = x land (lnot 0o111)
|
||||||
|
|
||||||
let install_uninstall ~what =
|
let install_uninstall ~what =
|
||||||
let doc =
|
let doc =
|
||||||
sprintf "%s packages using opam-installer." (String.capitalize what)
|
sprintf "%s packages using opam-installer." (String.capitalize what)
|
||||||
|
@ -1080,7 +1080,6 @@ let install_uninstall ~what =
|
||||||
let name_ = Arg.info [] ~docv:"PACKAGE" in
|
let name_ = Arg.info [] ~docv:"PACKAGE" in
|
||||||
let go common prefix_from_command_line libdir_from_command_line pkgs =
|
let go common prefix_from_command_line libdir_from_command_line pkgs =
|
||||||
set_common common ~targets:[];
|
set_common common ~targets:[];
|
||||||
let opam_installer = opam_installer () in
|
|
||||||
let log = Log.create common in
|
let log = Log.create common in
|
||||||
Scheduler.go ~log ~common
|
Scheduler.go ~log ~common
|
||||||
(Main.setup ~log common >>= fun setup ->
|
(Main.setup ~log common >>= fun setup ->
|
||||||
|
@ -1095,7 +1094,7 @@ let install_uninstall ~what =
|
||||||
List.map setup.contexts ~f:(fun ctx ->
|
List.map setup.contexts ~f:(fun ctx ->
|
||||||
let fn = Path.append ctx.Context.build_dir fn in
|
let fn = Path.append ctx.Context.build_dir fn in
|
||||||
if Path.exists fn then
|
if Path.exists fn then
|
||||||
Left (ctx, fn)
|
Left (ctx, (pkg, fn))
|
||||||
else
|
else
|
||||||
Right fn))
|
Right fn))
|
||||||
|> List.partition_map ~f:(fun x -> x)
|
|> List.partition_map ~f:(fun x -> x)
|
||||||
|
@ -1121,23 +1120,57 @@ let install_uninstall ~what =
|
||||||
in
|
in
|
||||||
Fiber.parallel_iter install_files_by_context
|
Fiber.parallel_iter install_files_by_context
|
||||||
~f:(fun (context, install_files) ->
|
~f:(fun (context, install_files) ->
|
||||||
let install_files_set = Path.Set.of_list install_files in
|
|
||||||
get_prefix context ~from_command_line:prefix_from_command_line
|
get_prefix context ~from_command_line:prefix_from_command_line
|
||||||
>>= fun prefix ->
|
>>= fun prefix ->
|
||||||
get_libdir context ~libdir_from_command_line
|
get_libdir context ~libdir_from_command_line
|
||||||
>>= fun libdir ->
|
>>| fun libdir ->
|
||||||
Fiber.parallel_iter install_files ~f:(fun path ->
|
List.iter install_files ~f:(fun (package, path) ->
|
||||||
let purpose = Process.Build_job install_files_set in
|
let entries = Install.load_install_file path in
|
||||||
Process.run ~purpose ~env:setup.env Strict opam_installer
|
let paths =
|
||||||
([ sprintf "-%c" what.[0]
|
Install.Section.Paths.make
|
||||||
; Path.to_string path
|
~package
|
||||||
; "--prefix"
|
~destdir:prefix
|
||||||
; Path.to_string prefix
|
?libdir
|
||||||
] @
|
()
|
||||||
match libdir with
|
in
|
||||||
| None -> []
|
let files_deleted_in = ref Path.Set.empty in
|
||||||
| Some p -> [ "--libdir"; Path.to_string p ]
|
List.iter entries ~f:(fun { Install.Entry. src; dst; section } ->
|
||||||
))))
|
let src = src in
|
||||||
|
let dst = Option.value dst ~default:(Path.basename src) in
|
||||||
|
let dst =
|
||||||
|
Path.relative (Install.Section.Paths.get paths section) dst
|
||||||
|
in
|
||||||
|
let dir = Path.parent_exn dst in
|
||||||
|
if what = "install" then begin
|
||||||
|
Printf.eprintf "Installing %s\n%!"
|
||||||
|
(Path.to_string_maybe_quoted dst);
|
||||||
|
Path.mkdir_p dir;
|
||||||
|
Io.copy_file () ~src ~dst
|
||||||
|
~chmod:(
|
||||||
|
if Install.Section.should_set_executable_bit section then
|
||||||
|
set_executable_bits
|
||||||
|
else
|
||||||
|
clear_executable_bits)
|
||||||
|
end else begin
|
||||||
|
if Path.exists dst then begin
|
||||||
|
Printf.eprintf "Deleting %s\n%!"
|
||||||
|
(Path.to_string_maybe_quoted dst);
|
||||||
|
print_unix_error (fun () -> Path.unlink dst)
|
||||||
|
end;
|
||||||
|
files_deleted_in := Path.Set.add !files_deleted_in dir;
|
||||||
|
end;
|
||||||
|
Path.Set.to_list !files_deleted_in
|
||||||
|
(* This [List.rev] is to ensure we process children
|
||||||
|
directories before their parents *)
|
||||||
|
|> List.rev
|
||||||
|
|> List.iter ~f:(fun dir ->
|
||||||
|
if Path.exists dir then
|
||||||
|
match Path.readdir_unsorted dir with
|
||||||
|
| [] ->
|
||||||
|
Printf.eprintf "Deleting empty directory %s\n%!"
|
||||||
|
(Path.to_string_maybe_quoted dst);
|
||||||
|
print_unix_error (fun () -> Path.rmdir dir)
|
||||||
|
| _ -> ())))))
|
||||||
in
|
in
|
||||||
( Term.(const go
|
( Term.(const go
|
||||||
$ common
|
$ common
|
||||||
|
|
|
@ -637,7 +637,7 @@ module Promotion = struct
|
||||||
Format.eprintf "Promoting %s to %s.@."
|
Format.eprintf "Promoting %s to %s.@."
|
||||||
(Path.to_string_maybe_quoted src)
|
(Path.to_string_maybe_quoted src)
|
||||||
(Path.to_string_maybe_quoted dst);
|
(Path.to_string_maybe_quoted dst);
|
||||||
Io.copy_file ~src ~dst
|
Io.copy_file ~src ~dst ()
|
||||||
end
|
end
|
||||||
|
|
||||||
module P = Utils.Persistent(struct
|
module P = Utils.Persistent(struct
|
||||||
|
@ -785,11 +785,11 @@ let rec exec t ~ectx ~dir ~env ~stdout_to ~stderr_to =
|
||||||
Io.copy_channels ic oc);
|
Io.copy_channels ic oc);
|
||||||
Fiber.return ()
|
Fiber.return ()
|
||||||
| Copy (src, dst) ->
|
| Copy (src, dst) ->
|
||||||
Io.copy_file ~src ~dst;
|
Io.copy_file ~src ~dst ();
|
||||||
Fiber.return ()
|
Fiber.return ()
|
||||||
| Symlink (src, dst) ->
|
| Symlink (src, dst) ->
|
||||||
if Sys.win32 then
|
if Sys.win32 then
|
||||||
Io.copy_file ~src ~dst
|
Io.copy_file ~src ~dst ()
|
||||||
else begin
|
else begin
|
||||||
let src =
|
let src =
|
||||||
match Path.parent dst with
|
match Path.parent dst with
|
||||||
|
|
|
@ -826,7 +826,7 @@ let rec compile_rule t ?(copy_source=false) pre_rule =
|
||||||
Utils.Cached_digest.file in_source_tree) then begin
|
Utils.Cached_digest.file in_source_tree) then begin
|
||||||
if mode = Promote_but_delete_on_clean then
|
if mode = Promote_but_delete_on_clean then
|
||||||
Promoted_to_delete.add in_source_tree;
|
Promoted_to_delete.add in_source_tree;
|
||||||
Io.copy_file ~src:path ~dst:in_source_tree
|
Io.copy_file ~src:path ~dst:in_source_tree ()
|
||||||
end)
|
end)
|
||||||
end;
|
end;
|
||||||
t.hook Rule_completed
|
t.hook Rule_completed
|
||||||
|
|
175
src/install.ml
175
src/install.ml
|
@ -31,6 +31,21 @@ module Section = struct
|
||||||
| Man -> "man"
|
| Man -> "man"
|
||||||
| Misc -> "misc"
|
| Misc -> "misc"
|
||||||
|
|
||||||
|
let of_string = function
|
||||||
|
| "lib" -> Some Lib
|
||||||
|
| "libexec" -> Some Libexec
|
||||||
|
| "bin" -> Some Bin
|
||||||
|
| "sbin" -> Some Sbin
|
||||||
|
| "toplevel" -> Some Toplevel
|
||||||
|
| "share" -> Some Share
|
||||||
|
| "share_root" -> Some Share_root
|
||||||
|
| "etc" -> Some Etc
|
||||||
|
| "doc" -> Some Doc
|
||||||
|
| "stublibs" -> Some Stublibs
|
||||||
|
| "man" -> Some Man
|
||||||
|
| "misc" -> Some Misc
|
||||||
|
| _ -> None
|
||||||
|
|
||||||
let t =
|
let t =
|
||||||
let open Sexp.Of_sexp in
|
let open Sexp.Of_sexp in
|
||||||
enum
|
enum
|
||||||
|
@ -48,35 +63,65 @@ module Section = struct
|
||||||
; "misc" , Misc
|
; "misc" , Misc
|
||||||
]
|
]
|
||||||
|
|
||||||
module Paths = struct
|
let should_set_executable_bit = function
|
||||||
let lib = Path.in_source "lib"
|
| Lib -> false
|
||||||
let libexec = Path.in_source "lib"
|
| Libexec -> true
|
||||||
let bin = Path.in_source "bin"
|
| Bin -> true
|
||||||
let sbin = Path.in_source "sbin"
|
| Sbin -> true
|
||||||
let toplevel = Path.in_source "lib/toplevel"
|
| Toplevel -> false
|
||||||
let share = Path.in_source "share"
|
| Share -> false
|
||||||
let share_root = Path.in_source "share_root"
|
| Share_root -> false
|
||||||
let etc = Path.in_source "etc"
|
| Etc -> false
|
||||||
let doc = Path.in_source "doc"
|
| Doc -> false
|
||||||
let stublibs = Path.in_source "lib/stublibs"
|
| Stublibs -> true
|
||||||
let man = Path.in_source "man"
|
| Man -> false
|
||||||
end
|
| Misc -> false
|
||||||
|
|
||||||
let install_dir t ~(package : Package.Name.t) =
|
module Paths = struct
|
||||||
let package = Package.Name.to_string package in
|
type t =
|
||||||
match t with
|
{ lib : Path.t
|
||||||
| Bin -> Paths.bin
|
; libexec : Path.t
|
||||||
| Sbin -> Paths.sbin
|
; bin : Path.t
|
||||||
| Toplevel -> Paths.toplevel
|
; sbin : Path.t
|
||||||
| Share_root -> Paths.share_root
|
; toplevel : Path.t
|
||||||
| Stublibs -> Paths.stublibs
|
; share : Path.t
|
||||||
| Man -> Paths.man
|
; share_root : Path.t
|
||||||
| Lib -> Path.relative Paths.lib package
|
; etc : Path.t
|
||||||
| Libexec -> Path.relative Paths.libexec package
|
; doc : Path.t
|
||||||
| Share -> Path.relative Paths.share package
|
; stublibs : Path.t
|
||||||
| Etc -> Path.relative Paths.etc package
|
; man : Path.t
|
||||||
| Doc -> Path.relative Paths.doc package
|
}
|
||||||
| Misc -> invalid_arg "Install.Section.install_dir"
|
|
||||||
|
let make ~package ~destdir ?(libdir=Path.relative destdir "lib") () =
|
||||||
|
let package = Package.Name.to_string package in
|
||||||
|
{ bin = Path.relative destdir "bin"
|
||||||
|
; sbin = Path.relative destdir "sbin"
|
||||||
|
; toplevel = Path.relative libdir "toplevel"
|
||||||
|
; share_root = Path.relative libdir "share"
|
||||||
|
; stublibs = Path.relative libdir "lib/stublibs"
|
||||||
|
; man = Path.relative destdir "man"
|
||||||
|
; lib = Path.relative libdir package
|
||||||
|
; libexec = Path.relative libdir package
|
||||||
|
; share = Path.relative destdir ("share/" ^ package)
|
||||||
|
; etc = Path.relative destdir ("etc/" ^ package)
|
||||||
|
; doc = Path.relative destdir ("doc/" ^ package)
|
||||||
|
}
|
||||||
|
|
||||||
|
let get t section =
|
||||||
|
match section with
|
||||||
|
| Lib -> t.lib
|
||||||
|
| Libexec -> t.libexec
|
||||||
|
| Bin -> t.bin
|
||||||
|
| Sbin -> t.sbin
|
||||||
|
| Toplevel -> t.toplevel
|
||||||
|
| Share -> t.share
|
||||||
|
| Share_root -> t.share_root
|
||||||
|
| Etc -> t.etc
|
||||||
|
| Doc -> t.doc
|
||||||
|
| Stublibs -> t.stublibs
|
||||||
|
| Man -> t.man
|
||||||
|
| Misc -> invalid_arg "Install.Paths.get"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Entry = struct
|
module Entry = struct
|
||||||
|
@ -112,8 +157,8 @@ module Entry = struct
|
||||||
|
|
||||||
let set_src t src = { t with src }
|
let set_src t src = { t with src }
|
||||||
|
|
||||||
let relative_installed_path t ~package =
|
let relative_installed_path t ~paths =
|
||||||
let main_dir = Section.install_dir t.section ~package in
|
let main_dir = Section.Paths.get paths t.section in
|
||||||
let dst =
|
let dst =
|
||||||
match t.dst with
|
match t.dst with
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
|
@ -129,15 +174,14 @@ module Entry = struct
|
||||||
in
|
in
|
||||||
Path.relative main_dir dst
|
Path.relative main_dir dst
|
||||||
|
|
||||||
let add_install_prefix t ~package ~prefix =
|
let add_install_prefix t ~paths ~prefix =
|
||||||
let opam_will_install_in_this_dir =
|
let opam_will_install_in_this_dir = Section.Paths.get paths t.section in
|
||||||
Section.install_dir t.section ~package
|
|
||||||
in
|
|
||||||
let i_want_to_install_the_file_as =
|
let i_want_to_install_the_file_as =
|
||||||
Path.append prefix (relative_installed_path t ~package)
|
Path.append prefix (relative_installed_path t ~paths)
|
||||||
in
|
in
|
||||||
let dst =
|
let dst =
|
||||||
Path.reach i_want_to_install_the_file_as ~from:opam_will_install_in_this_dir
|
Path.reach i_want_to_install_the_file_as
|
||||||
|
~from:opam_will_install_in_this_dir
|
||||||
in
|
in
|
||||||
{ t with dst = Some dst }
|
{ t with dst = Some dst }
|
||||||
end
|
end
|
||||||
|
@ -165,3 +209,62 @@ let gen_install_file entries =
|
||||||
| Some dst -> pr " %S {%S}" src dst);
|
| Some dst -> pr " %S {%S}" src dst);
|
||||||
pr "]");
|
pr "]");
|
||||||
Buffer.contents buf
|
Buffer.contents buf
|
||||||
|
|
||||||
|
let pos_of_opam_value : OpamParserTypes.value -> OpamParserTypes.pos = function
|
||||||
|
| Bool (pos, _) -> pos
|
||||||
|
| Int (pos, _) -> pos
|
||||||
|
| String (pos, _) -> pos
|
||||||
|
| Relop (pos, _, _, _) -> pos
|
||||||
|
| Prefix_relop (pos, _, _) -> pos
|
||||||
|
| Logop (pos, _, _, _) -> pos
|
||||||
|
| Pfxop (pos, _, _) -> pos
|
||||||
|
| Ident (pos, _) -> pos
|
||||||
|
| List (pos, _) -> pos
|
||||||
|
| Group (pos, _) -> pos
|
||||||
|
| Option (pos, _, _) -> pos
|
||||||
|
| Env_binding (pos, _, _, _) -> pos
|
||||||
|
|
||||||
|
let load_install_file path =
|
||||||
|
let open OpamParserTypes in
|
||||||
|
let file = Opam_file.load path in
|
||||||
|
let fail (fname, line, col) fmt =
|
||||||
|
let pos : Lexing.position =
|
||||||
|
{ pos_fname = fname
|
||||||
|
; pos_lnum = line
|
||||||
|
; pos_bol = 0
|
||||||
|
; pos_cnum = col
|
||||||
|
}
|
||||||
|
in
|
||||||
|
Loc.fail { start = pos; stop = pos } fmt
|
||||||
|
in
|
||||||
|
List.concat_map file.file_contents ~f:(function
|
||||||
|
| Variable (pos, section, files) -> begin
|
||||||
|
match Section.of_string section with
|
||||||
|
| None -> fail pos "Unknown install section"
|
||||||
|
| Some section -> begin
|
||||||
|
match files with
|
||||||
|
| List (_, l) ->
|
||||||
|
List.map l ~f:(function
|
||||||
|
| String (_, src) ->
|
||||||
|
{ Entry.
|
||||||
|
src = Path.of_string src
|
||||||
|
; dst = None
|
||||||
|
; section
|
||||||
|
}
|
||||||
|
| Option (_, String (_, src),
|
||||||
|
[String (_, dst)]) ->
|
||||||
|
{ Entry.
|
||||||
|
src = Path.of_string src
|
||||||
|
; dst = Some dst
|
||||||
|
; section
|
||||||
|
}
|
||||||
|
| v ->
|
||||||
|
fail (pos_of_opam_value v)
|
||||||
|
"Invalid value in .install file")
|
||||||
|
| v ->
|
||||||
|
fail (pos_of_opam_value v)
|
||||||
|
"Invalid value for install section"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
| Section (pos, _) ->
|
||||||
|
fail pos "Sections are not allowed in .install file")
|
||||||
|
|
|
@ -18,6 +18,37 @@ module Section : sig
|
||||||
| Misc
|
| Misc
|
||||||
|
|
||||||
val t : t Sexp.Of_sexp.t
|
val t : t Sexp.Of_sexp.t
|
||||||
|
|
||||||
|
(** [true] iff the executable bit should be set for files installed
|
||||||
|
in this location. *)
|
||||||
|
val should_set_executable_bit : t -> bool
|
||||||
|
|
||||||
|
module Paths : sig
|
||||||
|
type section = t
|
||||||
|
|
||||||
|
type t =
|
||||||
|
{ lib : Path.t
|
||||||
|
; libexec : Path.t
|
||||||
|
; bin : Path.t
|
||||||
|
; sbin : Path.t
|
||||||
|
; toplevel : Path.t
|
||||||
|
; share : Path.t
|
||||||
|
; share_root : Path.t
|
||||||
|
; etc : Path.t
|
||||||
|
; doc : Path.t
|
||||||
|
; stublibs : Path.t
|
||||||
|
; man : Path.t
|
||||||
|
}
|
||||||
|
|
||||||
|
val make
|
||||||
|
: package:Package.Name.t
|
||||||
|
-> destdir:Path.t
|
||||||
|
-> ?libdir:Path.t
|
||||||
|
-> unit
|
||||||
|
-> t
|
||||||
|
|
||||||
|
val get : t -> section -> Path.t
|
||||||
|
end with type section := t
|
||||||
end
|
end
|
||||||
|
|
||||||
module Entry : sig
|
module Entry : sig
|
||||||
|
@ -30,9 +61,11 @@ module Entry : sig
|
||||||
val make : Section.t -> ?dst:string -> Path.t -> t
|
val make : Section.t -> ?dst:string -> Path.t -> t
|
||||||
val set_src : t -> Path.t -> t
|
val set_src : t -> Path.t -> t
|
||||||
|
|
||||||
val relative_installed_path : t -> package:Package.Name.t -> Path.t
|
val relative_installed_path : t -> paths:Section.Paths.t -> Path.t
|
||||||
val add_install_prefix : t -> package:Package.Name.t -> prefix:Path.t -> t
|
val add_install_prefix : t -> paths:Section.Paths.t -> prefix:Path.t -> t
|
||||||
end
|
end
|
||||||
|
|
||||||
val files : Entry.t list -> Path.Set.t
|
val files : Entry.t list -> Path.Set.t
|
||||||
val gen_install_file : Entry.t list -> string
|
val gen_install_file : Entry.t list -> string
|
||||||
|
|
||||||
|
val load_install_file : Path.t -> Entry.t list
|
||||||
|
|
|
@ -219,12 +219,13 @@ module Gen(P : Install_params) = struct
|
||||||
List.exists [ "README"; "LICENSE"; "CHANGE"; "HISTORY"]
|
List.exists [ "README"; "LICENSE"; "CHANGE"; "HISTORY"]
|
||||||
~f:(fun prefix -> String.is_prefix fn ~prefix)
|
~f:(fun prefix -> String.is_prefix fn ~prefix)
|
||||||
|
|
||||||
let local_install_rules (entries : Install.Entry.t list) ~package =
|
let local_install_rules (entries : Install.Entry.t list)
|
||||||
|
~install_paths ~package =
|
||||||
let install_dir = Config.local_install_dir ~context:ctx.name in
|
let install_dir = Config.local_install_dir ~context:ctx.name in
|
||||||
List.map entries ~f:(fun entry ->
|
List.map entries ~f:(fun entry ->
|
||||||
let dst =
|
let dst =
|
||||||
Path.append install_dir
|
Path.append install_dir
|
||||||
(Install.Entry.relative_installed_path entry ~package)
|
(Install.Entry.relative_installed_path entry ~paths:install_paths)
|
||||||
in
|
in
|
||||||
Build_system.set_package (SC.build_system sctx) entry.src package;
|
Build_system.set_package (SC.build_system sctx) entry.src package;
|
||||||
SC.add_rule sctx (Build.symlink ~src:entry.src ~dst);
|
SC.add_rule sctx (Build.symlink ~src:entry.src ~dst);
|
||||||
|
@ -258,7 +259,10 @@ module Gen(P : Install_params) = struct
|
||||||
Path.relative (Path.append ctx.build_dir package_path)
|
Path.relative (Path.append ctx.build_dir package_path)
|
||||||
(Utils.install_file ~package ~findlib_toolchain:ctx.findlib_toolchain)
|
(Utils.install_file ~package ~findlib_toolchain:ctx.findlib_toolchain)
|
||||||
in
|
in
|
||||||
let entries = local_install_rules entries ~package in
|
let install_paths =
|
||||||
|
Install.Section.Paths.make ~package ~destdir:Path.root ()
|
||||||
|
in
|
||||||
|
let entries = local_install_rules entries ~package ~install_paths in
|
||||||
let files = Install.files entries in
|
let files = Install.files entries in
|
||||||
SC.add_alias_deps sctx
|
SC.add_alias_deps sctx
|
||||||
(Alias.package_install ~context:ctx ~pkg:package)
|
(Alias.package_install ~context:ctx ~pkg:package)
|
||||||
|
@ -287,7 +291,8 @@ module Gen(P : Install_params) = struct
|
||||||
| Some toolchain ->
|
| Some toolchain ->
|
||||||
let prefix = Path.of_string (toolchain ^ "-sysroot") in
|
let prefix = Path.of_string (toolchain ^ "-sysroot") in
|
||||||
List.map entries
|
List.map entries
|
||||||
~f:(Install.Entry.add_install_prefix ~prefix ~package)
|
~f:(Install.Entry.add_install_prefix
|
||||||
|
~paths:install_paths ~prefix)
|
||||||
in
|
in
|
||||||
Install.gen_install_file entries)
|
Install.gen_install_file entries)
|
||||||
>>>
|
>>>
|
||||||
|
|
|
@ -1132,7 +1132,9 @@ module Rule = struct
|
||||||
field "deps" (list Dep_conf.t) ~default:[] >>= fun deps ->
|
field "deps" (list Dep_conf.t) ~default:[] >>= fun deps ->
|
||||||
field "locks" (list String_with_vars.t) ~default:[] >>= fun locks ->
|
field "locks" (list String_with_vars.t) ~default:[] >>= fun locks ->
|
||||||
map_validate
|
map_validate
|
||||||
(field_b "fallback" >>= fun fallback ->
|
(field_b
|
||||||
|
~check:(Syntax.renamed_in Stanza.syntax (1, 0) ~to_:"(mode fallback)")
|
||||||
|
"fallback" >>= fun fallback ->
|
||||||
field_o "mode" Mode.t >>= fun mode ->
|
field_o "mode" Mode.t >>= fun mode ->
|
||||||
return (fallback, mode))
|
return (fallback, mode))
|
||||||
~f:(function
|
~f:(function
|
||||||
|
|
|
@ -66,9 +66,9 @@ let copy_channels =
|
||||||
in
|
in
|
||||||
loop
|
loop
|
||||||
|
|
||||||
let copy_file ~src ~dst =
|
let copy_file ?(chmod=fun x -> x) ~src ~dst () =
|
||||||
with_file_in src ~f:(fun ic ->
|
with_file_in src ~f:(fun ic ->
|
||||||
let perm = (Unix.fstat (Unix.descr_of_in_channel ic)).st_perm in
|
let perm = (Unix.fstat (Unix.descr_of_in_channel ic)).st_perm |> chmod in
|
||||||
Exn.protectx (P.open_out_gen
|
Exn.protectx (P.open_out_gen
|
||||||
[Open_wronly; Open_creat; Open_trunc; Open_binary]
|
[Open_wronly; Open_creat; Open_trunc; Open_binary]
|
||||||
perm
|
perm
|
||||||
|
|
|
@ -23,7 +23,7 @@ val write_lines : Path.t -> string list -> unit
|
||||||
|
|
||||||
val copy_channels : in_channel -> out_channel -> unit
|
val copy_channels : in_channel -> out_channel -> unit
|
||||||
|
|
||||||
val copy_file : src:Path.t -> dst:Path.t -> unit
|
val copy_file : ?chmod:(int -> int) -> src:Path.t -> dst:Path.t -> unit -> unit
|
||||||
|
|
||||||
val read_all : in_channel -> string
|
val read_all : in_channel -> string
|
||||||
|
|
||||||
|
|
|
@ -874,9 +874,7 @@ let rm_rf =
|
||||||
| _ -> loop fn
|
| _ -> loop fn
|
||||||
|
|
||||||
let mkdir_p = function
|
let mkdir_p = function
|
||||||
| External s ->
|
| External s -> External.mkdir_p s
|
||||||
Exn.code_error "Path.mkdir_p cannot create external path"
|
|
||||||
["s", External.sexp_of_t s]
|
|
||||||
| In_source_tree s ->
|
| In_source_tree s ->
|
||||||
Exn.code_error "Path.mkdir_p cannot dir in source"
|
Exn.code_error "Path.mkdir_p cannot dir in source"
|
||||||
["s", Local.sexp_of_t s]
|
["s", Local.sexp_of_t s]
|
||||||
|
|
|
@ -481,9 +481,10 @@ module Of_sexp = struct
|
||||||
| None ->
|
| None ->
|
||||||
(None, add_known name state)
|
(None, add_known name state)
|
||||||
|
|
||||||
let field_b name =
|
let field_b ?check name =
|
||||||
field name ~default:false
|
field name ~default:false
|
||||||
(eos >>= function
|
(Option.value check ~default:(return ()) >>= fun () ->
|
||||||
|
eos >>= function
|
||||||
| true -> return true
|
| true -> return true
|
||||||
| _ -> bool)
|
| _ -> bool)
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ module Of_sexp : sig
|
||||||
-> 'a t
|
-> 'a t
|
||||||
-> 'a option fields_parser
|
-> 'a option fields_parser
|
||||||
|
|
||||||
val field_b : string -> bool fields_parser
|
val field_b : ?check:(unit t) -> string -> bool fields_parser
|
||||||
|
|
||||||
(** A field that can appear multiple times *)
|
(** A field that can appear multiple times *)
|
||||||
val multi_field
|
val multi_field
|
||||||
|
|
|
@ -124,7 +124,7 @@ let renamed_in t ver ~to_ =
|
||||||
else begin
|
else begin
|
||||||
desc () >>= fun (loc, what) ->
|
desc () >>= fun (loc, what) ->
|
||||||
Loc.fail loc
|
Loc.fail loc
|
||||||
"%s was renamed to '%s' in %s of %s" what to_
|
"%s was renamed to '%s' in the %s version of %s" what to_
|
||||||
(Version.to_string ver) t.desc
|
(Version.to_string ver) t.desc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,14 @@
|
||||||
test-cases/exec-cmd
|
test-cases/exec-cmd
|
||||||
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
(name fallback-dune)
|
||||||
|
(deps (package dune) (source_tree test-cases/fallback-dune))
|
||||||
|
(action
|
||||||
|
(chdir
|
||||||
|
test-cases/fallback-dune
|
||||||
|
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
(name findlib)
|
(name findlib)
|
||||||
(deps (package dune) (source_tree test-cases/findlib))
|
(deps (package dune) (source_tree test-cases/findlib))
|
||||||
|
@ -606,6 +614,7 @@
|
||||||
(alias env)
|
(alias env)
|
||||||
(alias exclude-missing-module)
|
(alias exclude-missing-module)
|
||||||
(alias exec-cmd)
|
(alias exec-cmd)
|
||||||
|
(alias fallback-dune)
|
||||||
(alias findlib)
|
(alias findlib)
|
||||||
(alias findlib-error)
|
(alias findlib-error)
|
||||||
(alias force-test)
|
(alias force-test)
|
||||||
|
@ -678,6 +687,7 @@
|
||||||
(alias env)
|
(alias env)
|
||||||
(alias exclude-missing-module)
|
(alias exclude-missing-module)
|
||||||
(alias exec-cmd)
|
(alias exec-cmd)
|
||||||
|
(alias fallback-dune)
|
||||||
(alias findlib)
|
(alias findlib)
|
||||||
(alias findlib-error)
|
(alias findlib-error)
|
||||||
(alias force-test)
|
(alias force-test)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
(rule
|
||||||
|
(fallback)
|
||||||
|
(targets)
|
||||||
|
(action (with-stdout-to foo.txt (echo "testing"))))
|
|
@ -0,0 +1,4 @@
|
||||||
|
(rule
|
||||||
|
(fallback false)
|
||||||
|
(targets)
|
||||||
|
(action (with-stdout-to foo.txt (echo "testing"))))
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
(rule
|
||||||
|
((fallback)
|
||||||
|
(targets (foo.txt))
|
||||||
|
(action (with-stdout-to foo.txt (echo "testing")))))
|
|
@ -0,0 +1,20 @@
|
||||||
|
fallback isn't allowed in dune
|
||||||
|
|
||||||
|
$ dune build --root dune1
|
||||||
|
Info: creating file dune-project with this contents: (lang dune 1.0)
|
||||||
|
File "dune", line 2, characters 1-11:
|
||||||
|
Error: 'fallback' was renamed to '(mode fallback)' in the 1.0 version of the dune language
|
||||||
|
[1]
|
||||||
|
|
||||||
|
2nd fallback form isn't allowed either
|
||||||
|
|
||||||
|
$ dune build --root dune2
|
||||||
|
Info: creating file dune-project with this contents: (lang dune 1.0)
|
||||||
|
File "dune", line 2, characters 1-17:
|
||||||
|
Error: 'fallback' was renamed to '(mode fallback)' in the 1.0 version of the dune language
|
||||||
|
[1]
|
||||||
|
|
||||||
|
But it is allowed in jbuilder
|
||||||
|
|
||||||
|
$ jbuilder build --root jbuild
|
||||||
|
Entering directory 'jbuild'
|
|
@ -1,13 +1,54 @@
|
||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright 2012-2015 OCamlPro *)
|
||||||
|
(* Copyright 2012 INRIA *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. This file is distributed under the terms of the *)
|
||||||
|
(* GNU Lesser General Public License version 2.1, with the special *)
|
||||||
|
(* exception on linking described in the file LICENSE. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type relop = [ `Eq | `Neq | `Geq | `Gt | `Leq | `Lt ]
|
||||||
|
type logop = [ `And | `Or ]
|
||||||
|
type pfxop = [ `Not ]
|
||||||
|
|
||||||
|
type file_name = string
|
||||||
|
|
||||||
|
(** Source file positions: filename, line, column *)
|
||||||
|
type pos = file_name * int * int
|
||||||
|
|
||||||
|
type env_update_op = Eq | PlusEq | EqPlus | ColonEq | EqColon | EqPlusEq
|
||||||
|
|
||||||
|
(** Base values *)
|
||||||
type value =
|
type value =
|
||||||
| String of unit * string
|
| Bool of pos * bool
|
||||||
| List of unit * value list
|
| Int of pos * int
|
||||||
| Other
|
| String of pos * string
|
||||||
|
| Relop of pos * relop * value * value
|
||||||
|
| Prefix_relop of pos * relop * value
|
||||||
|
| Logop of pos * logop * value * value
|
||||||
|
| Pfxop of pos * pfxop * value
|
||||||
|
| Ident of pos * string
|
||||||
|
| List of pos * value list
|
||||||
|
| Group of pos * value list
|
||||||
|
| Option of pos * value * value list
|
||||||
|
| Env_binding of pos * value * env_update_op * value
|
||||||
|
|
||||||
type opamfile_item =
|
(** An opamfile section *)
|
||||||
| Variable of unit * string * value
|
type opamfile_section = {
|
||||||
| Other
|
section_kind : string;
|
||||||
|
section_name : string option;
|
||||||
|
section_items : opamfile_item list;
|
||||||
|
}
|
||||||
|
|
||||||
type opamfile =
|
(** An opamfile is composed of sections and variable definitions *)
|
||||||
{ file_contents : opamfile_item list
|
and opamfile_item =
|
||||||
; file_name : string
|
| Section of pos * opamfile_section
|
||||||
}
|
| Variable of pos * string * value
|
||||||
|
|
||||||
|
(** A file is a list of items and the filename *)
|
||||||
|
type opamfile = {
|
||||||
|
file_contents: opamfile_item list;
|
||||||
|
file_name : file_name;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue