1995-08-09 08:06:35 -07:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
2011-07-27 07:17:02 -07:00
|
|
|
(* OCaml *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the Q Public License version 1.0. *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
1995-07-11 11:05:47 -07:00
|
|
|
(* Build libraries of .cmo files *)
|
|
|
|
|
|
|
|
open Misc
|
|
|
|
open Config
|
2006-05-11 08:50:53 -07:00
|
|
|
open Cmo_format
|
1995-07-11 11:05:47 -07:00
|
|
|
|
|
|
|
type error =
|
|
|
|
File_not_found of string
|
|
|
|
| Not_an_object_file of string
|
|
|
|
|
|
|
|
exception Error of error
|
|
|
|
|
2000-03-27 04:18:09 -08:00
|
|
|
(* Copy a compilation unit from a .cmo or .cma into the archive *)
|
1996-12-10 07:41:01 -08:00
|
|
|
let copy_compunit ic oc compunit =
|
|
|
|
seek_in ic compunit.cu_pos;
|
|
|
|
compunit.cu_pos <- pos_out oc;
|
|
|
|
compunit.cu_force_link <- !Clflags.link_everything;
|
1997-02-19 08:08:05 -08:00
|
|
|
copy_file_chunk ic oc compunit.cu_codesize;
|
|
|
|
if compunit.cu_debug > 0 then begin
|
|
|
|
seek_in ic compunit.cu_debug;
|
|
|
|
compunit.cu_debug <- pos_out oc;
|
|
|
|
copy_file_chunk ic oc compunit.cu_debugsize
|
|
|
|
end
|
1996-12-10 07:41:01 -08:00
|
|
|
|
2000-03-27 04:18:09 -08:00
|
|
|
(* Add C objects and options and "custom" info from a library descriptor *)
|
2010-01-22 04:48:24 -08:00
|
|
|
|
2000-03-27 04:18:09 -08:00
|
|
|
let lib_ccobjs = ref []
|
|
|
|
let lib_ccopts = ref []
|
2001-10-30 01:32:32 -08:00
|
|
|
let lib_dllibs = ref []
|
2000-03-27 04:18:09 -08:00
|
|
|
|
|
|
|
(* See Bytelink.add_ccobjs for explanations on how options are ordered.
|
|
|
|
Notice that here we scan .cma files given on the command line from
|
|
|
|
left to right, hence options must be added after. *)
|
|
|
|
|
|
|
|
let add_ccobjs l =
|
|
|
|
if not !Clflags.no_auto_link then begin
|
|
|
|
if l.lib_custom then Clflags.custom_runtime := true;
|
|
|
|
lib_ccobjs := !lib_ccobjs @ l.lib_ccobjs;
|
2001-10-30 01:32:32 -08:00
|
|
|
lib_ccopts := !lib_ccopts @ l.lib_ccopts;
|
|
|
|
lib_dllibs := !lib_dllibs @ l.lib_dllibs
|
2000-03-27 04:18:09 -08:00
|
|
|
end
|
|
|
|
|
2012-01-20 06:23:34 -08:00
|
|
|
let copy_object_file ppf oc name =
|
1995-07-11 11:05:47 -07:00
|
|
|
let file_name =
|
|
|
|
try
|
|
|
|
find_in_path !load_path name
|
|
|
|
with Not_found ->
|
|
|
|
raise(Error(File_not_found name)) in
|
|
|
|
let ic = open_in_bin file_name in
|
|
|
|
try
|
2014-04-29 04:56:17 -07:00
|
|
|
let buffer = really_input_string ic (String.length cmo_magic_number) in
|
1996-12-10 07:41:01 -08:00
|
|
|
if buffer = cmo_magic_number then begin
|
|
|
|
let compunit_pos = input_binary_int ic in
|
|
|
|
seek_in ic compunit_pos;
|
|
|
|
let compunit = (input_value ic : compilation_unit) in
|
2012-01-20 06:23:34 -08:00
|
|
|
Bytelink.check_consistency ppf file_name compunit;
|
1996-12-10 07:41:01 -08:00
|
|
|
copy_compunit ic oc compunit;
|
|
|
|
close_in ic;
|
|
|
|
[compunit]
|
|
|
|
end else
|
|
|
|
if buffer = cma_magic_number then begin
|
|
|
|
let toc_pos = input_binary_int ic in
|
|
|
|
seek_in ic toc_pos;
|
2000-03-27 04:18:09 -08:00
|
|
|
let toc = (input_value ic : library) in
|
2012-01-20 06:23:34 -08:00
|
|
|
List.iter (Bytelink.check_consistency ppf file_name) toc.lib_units;
|
2000-03-27 04:18:09 -08:00
|
|
|
add_ccobjs toc;
|
|
|
|
List.iter (copy_compunit ic oc) toc.lib_units;
|
1996-12-10 07:41:01 -08:00
|
|
|
close_in ic;
|
2000-03-27 04:18:09 -08:00
|
|
|
toc.lib_units
|
1996-12-10 07:41:01 -08:00
|
|
|
end else
|
|
|
|
raise(Error(Not_an_object_file file_name))
|
1998-10-01 05:38:09 -07:00
|
|
|
with
|
|
|
|
End_of_file -> close_in ic; raise(Error(Not_an_object_file file_name))
|
|
|
|
| x -> close_in ic; raise x
|
1995-07-11 11:05:47 -07:00
|
|
|
|
2012-01-20 06:23:34 -08:00
|
|
|
let create_archive ppf file_list lib_name =
|
1995-07-11 11:05:47 -07:00
|
|
|
let outchan = open_out_bin lib_name in
|
|
|
|
try
|
|
|
|
output_string outchan cma_magic_number;
|
|
|
|
let ofs_pos_toc = pos_out outchan in
|
|
|
|
output_binary_int outchan 0;
|
2013-03-09 14:38:52 -08:00
|
|
|
let units =
|
|
|
|
List.flatten(List.map (copy_object_file ppf outchan) file_list) in
|
2000-03-09 01:12:28 -08:00
|
|
|
let toc =
|
2000-03-27 04:18:09 -08:00
|
|
|
{ lib_units = units;
|
2000-03-09 01:12:28 -08:00
|
|
|
lib_custom = !Clflags.custom_runtime;
|
2000-03-27 04:18:09 -08:00
|
|
|
lib_ccobjs = !Clflags.ccobjs @ !lib_ccobjs;
|
2013-06-05 09:34:40 -07:00
|
|
|
lib_ccopts = !Clflags.all_ccopts @ !lib_ccopts;
|
2001-10-30 01:32:32 -08:00
|
|
|
lib_dllibs = !Clflags.dllibs @ !lib_dllibs } in
|
1995-07-11 11:05:47 -07:00
|
|
|
let pos_toc = pos_out outchan in
|
|
|
|
output_value outchan toc;
|
|
|
|
seek_out outchan ofs_pos_toc;
|
|
|
|
output_binary_int outchan pos_toc;
|
|
|
|
close_out outchan
|
|
|
|
with x ->
|
|
|
|
close_out outchan;
|
|
|
|
remove_file lib_name;
|
|
|
|
raise x
|
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
open Format
|
1995-07-11 11:05:47 -07:00
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
let report_error ppf = function
|
|
|
|
| File_not_found name ->
|
|
|
|
fprintf ppf "Cannot find file %s" name
|
1995-07-11 11:05:47 -07:00
|
|
|
| Not_an_object_file name ->
|
2012-03-07 09:50:17 -08:00
|
|
|
fprintf ppf "The file %a is not a bytecode object file"
|
|
|
|
Location.print_filename name
|
2013-09-12 07:34:13 -07:00
|
|
|
|
|
|
|
let () =
|
|
|
|
Location.register_error_of_exn
|
|
|
|
(function
|
|
|
|
| Error err -> Some (Location.error_of_printer_file report_error err)
|
|
|
|
| _ -> None
|
|
|
|
)
|
2014-05-09 05:01:21 -07:00
|
|
|
|
|
|
|
let reset () =
|
|
|
|
lib_ccobjs := [];
|
|
|
|
lib_ccopts := [];
|
|
|
|
lib_dllibs := []
|