1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
open Fugue
open Filepath
open Printf
open Project
open Types
open Target
open Helper
open Gconf
let list_target_files_pred target pred =
let build_dir = Dist.get_build_exn (Dist.Target target.Target.target_name) in
Build.sanity_check build_dir target;
(* don't play with matches *)
let matches = Filesystem.list_dir_pred pred build_dir in
(build_dir, matches)
let list_lib_files lib build_dir =
list_target_files_pred lib (fun f ->
if fn_to_string f = "META" then
true
else
match Filetype.of_filepath (build_dir </> f) with
| Filetype.FileCMX
| Filetype.FileCMI
| Filetype.FileA
| Filetype.FileCMXS
| Filetype.FileCMXA
| Filetype.FileCMA
| Filetype.FileCMT
| Filetype.FileCMTI -> true
| _ -> false)
let list_exe_files lib build_dir =
list_target_files_pred lib (fun f ->
match Filetype.of_filepath (build_dir </> f) with
| Filetype.FileEXE -> true
| _ -> false)
let opam_install_file proj_file flags =
let install_path = fp (proj_file.name ^ ".install") in
Utils.generateFile install_path (fun add ->
let all_targets = Project.get_all_installable_targets proj_file flags in
let print_target_files target list_files_fun =
let build_dir = Dist.get_build_exn (Dist.Target target.Target.target_name) in
let _, files = list_files_fun target build_dir in
List.iter
(fun file ->
let file_str = fn_to_string file in
add (sprintf " \"%s/%s\" {\"%s\"}\n" (fp_to_string build_dir) file_str file_str))
files
in
add (sprintf "%s: [\n" "lib");
List.iter
(fun target ->
match target.target_name with
| Name.Lib _ -> print_target_files target list_lib_files
| _ -> ())
all_targets;
add "]\n";
add (sprintf "%s: [\n" "bin");
List.iter
(fun target ->
match target.target_name with
| Name.Exe _ -> print_target_files target list_exe_files
| _ -> ())
all_targets;
add "]\n")
let lib_to_meta proj_file lib =
let requires_of_lib lib =
let deps = lib.Library.target.target_obits.target_builddeps in
[ ([], List.map (fun d -> fst d) deps) ]
in
let set_meta_field_from_lib pkg lib =
let linkopts_of_lib lib =
match lib.Library.target.Target.target_cstubs with
| Some _ ->
(* The installed stubs library is named libstubs_<library_name>.a *)
(* Use -cclib to wrap C linker flags for ocamlfind/ocamlopt compatibility *)
let lib_name = Libname.to_string lib.Library.name in
[(None, "-cclib -lstubs_" ^ lib_name)]
| None -> []
in
{
pkg with
Meta.Pkg.requires = requires_of_lib lib;
Meta.Pkg.description =
(if lib.Library.description <> "" then lib.Library.description else proj_file.description);
Meta.Pkg.linkopts = linkopts_of_lib lib;
Meta.Pkg.archives =
([
([ Meta.Predicate.Byte ], fn_to_string (Libname.to_cmca ByteCode Normal lib.Library.name));
( [ Meta.Predicate.Byte; Meta.Predicate.Plugin ],
fn_to_string (Libname.to_cmca ByteCode Normal lib.Library.name) );
([ Meta.Predicate.Native ], fn_to_string (Libname.to_cmca Native Normal lib.Library.name));
]
@
if Gconf.get_target_option_typed Gconf.Library_plugin then
[
( [ Meta.Predicate.Native; Meta.Predicate.Plugin ],
fn_to_string (Libname.to_cmxs Normal lib.Library.name) );
]
else
[]);
}
in
let subPkgs =
List.map
(fun sub ->
let npkg = Meta.Pkg.make (list_last (Libname.to_string_nodes sub.Library.name)) in
set_meta_field_from_lib npkg sub)
lib.Library.subs
in
let pkg = set_meta_field_from_lib (Meta.Pkg.make "") lib in
{ pkg with Meta.Pkg.version = proj_file.version; Meta.Pkg.subs = subPkgs }
let write_lib_meta projFile lib =
let dir = Dist.get_build_exn (Dist.Target lib.Library.target.target_name) in
let metadir_path = dir </> fn "META" in
let pkg = lib_to_meta projFile lib in
Meta.Pkg.write metadir_path pkg
let copy_files files dest_dir dir_name =
List.iter
(fun (build_dir, build_files) ->
List.iter
(fun build_file ->
Filesystem.copy_file (build_dir </> build_file) (dest_dir </> dir_name </> build_file))
build_files)
files
let install_lib proj_file lib dest_dir =
write_lib_meta proj_file lib;
let all_files =
List.map
(fun target ->
let build_dir = Dist.get_build_exn (Dist.Target target.Target.target_name) in
Build.sanity_check build_dir target;
list_lib_files target build_dir)
(Project.Library.to_targets lib)
in
let dir_name = fn (Libname.to_string lib.Project.Library.name) in
log Report "installing library %s\n" (Libname.to_string lib.Project.Library.name);
log Debug "installing files: %s\n"
(Utils.showList "," fn_to_string (List.concat (List.map snd all_files)));
copy_files all_files dest_dir dir_name
let install_libs proj_file destdir opam =
if not opam then
List.iter (fun lib -> install_lib proj_file lib destdir) proj_file.Project.libs
else
List.iter (fun lib -> write_lib_meta proj_file lib) proj_file.Project.libs
|