Last active
October 15, 2019 16:33
-
-
Save dbuenzli/0b773f4a4dd9f7a35f30cd9b671e48c5 to your computer and use it in GitHub Desktop.
Read cma/cmxa/cmxs link metadata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
ocamlfind ocamlopt -o readmeta -linkpkg \ | |
-package dynlink,compiler-libs.optcomp,compiler-libs.bytecomp readmeta.ml | |
*) | |
let read_cma ic = | |
let lib = | |
let toc_pos = input_binary_int ic in | |
seek_in ic toc_pos; | |
(input_value ic : Cmo_format.library) | |
in | |
Printf.printf "ccobjs: %s\nccopts: %s\ndllibs: %s\n%!" | |
(String.concat " " lib.Cmo_format.lib_ccobjs) | |
(String.concat " " lib.Cmo_format.lib_ccopts) | |
(String.concat " " lib.Cmo_format.lib_dllibs) | |
let read_cmxa ic = | |
let lib = (input_value ic : Cmx_format.library_infos) in | |
Printf.printf "ccobjs: %s\nccopts: %s\n" | |
(String.concat " " lib.Cmx_format.lib_ccobjs) | |
(String.concat " " lib.Cmx_format.lib_ccopts) | |
type handle | |
external ndl_open : string -> bool -> handle * Cmxs_format.dynheader | |
= "caml_natdynlink_open" | |
let read_cmxs file = | |
let _, dynh = ndl_open file false in | |
let unit_name d = d.Cmxs_format.dynu_name in | |
let units = List.map unit_name dynh.Cmxs_format.dynu_units in | |
Printf.printf "units: %s" (String.concat " " units) | |
let read_meta file = | |
if Filename.extension file = ".cmxs" then read_cmxs file else | |
let ic = open_in_bin file in | |
try | |
let len = String.length Config.cma_magic_number in | |
let magic = really_input_string ic len in | |
begin match magic with | |
| m when String.equal m Config.cma_magic_number -> read_cma ic | |
| m when String.equal m Config.cmxa_magic_number -> read_cmxa ic | |
| m -> raise (Sys_error ("unknown magic number " ^ m)) | |
end; | |
close_in ic | |
with | |
| e -> close_in_noerr ic; raise e | |
let main () = | |
try | |
if Array.length Sys.argv <> 2 | |
then (Printf.eprintf "Usage: readmeta CM[X]A\n"; exit 1) | |
else (read_meta Sys.argv.(1); exit 0) | |
with | |
| Sys_error e -> Printf.eprintf "%s: %s" Sys.argv.(1) e; exit 1 | |
let () = if !Sys.interactive then () else main () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment