Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
Re: [Caml-list] ocamlmktop and includes
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2001-04-28 (21:50)
From: Chris Hecker <checker@d...>
Subject: Re: [Caml-list] ocamlmktop and includes

>Alternatively, it would be really nice to make stand-alone byte code
>interpreters which have the .cmo files builtin.

Do you just mean a standalone executable (with no need for ocamlrun)?  If so, use the "-custom" flag to ocamlc and it'll put the intepreter inside the output file (and it appears the file is still recognized as a bytecode file by ocamlrun, so it's still portable as long as you don't link any C objects into it).  Maybe that's not what you meant...

Putting the include paths in the generated toplevel sounds like a good idea to me.  I decided to implement this.  I've attached the new tools/ below.  You should be able to build this by itself with "ocamlc -o ocamlmktop ocamlmktop", without building the compiler or even having the compiler source installed.

Random Notes & Issues:

- I need to build a temp .ml file and compile it, which assumes the ocamlc compiler is around.  Of course, ocamlmktop already assumes this.

- Filename.temp_file does not seem safe to me since it doesn't return an open handle, but I'm not a security expert.  I play kind of fast and loose with the temp files.  I create the *.ml file with temp_file, but I don't check for *.cmi or *.cmo before compiling it.  I wouldn't run this setuid root.  :)

- I use Topdirs.dir_directory to add the include directories...I doubt it's supposed to be an exposed API.

- It expands directories at runtime, so if you add -I +foo it'll work even if you move CAMLLIB.

- What you probably really want here is a new command line parm so you can differentiate betwen include dirs that should be added to the toplevel and those that shouldn't.

Let me know if anybody has problems with this.


------- tools/ --------

(*                                                                     *)
(*                           Objective Caml                            *)
(*                                                                     *)
(*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         *)
(*                                                                     *)
(*  Copyright 1996 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  under the terms of the Q Public License version 1.0.               *)
(*                                                                     *)

(* $Id:,v 1.3 1999/11/17 18:58:48 xleroy Exp $ *)

(* stolen from Misc so we don't have to modify the tools/ makefile *)
let remove_file filename =
    Sys.remove filename
  with Sys_error msg ->
let _ =
  let args =
    String.concat " " ( (Array.to_list Sys.argv)) in

  (* capture all the -I include dirs, ignoring everything else *)
  (* I can't use Arg.parse because we don't know all the parms *)
  let dirs = ref [] in
  for i = 1 to Array.length Sys.argv - 1 do
    if Sys.argv.(i) = "-I" then
      dirs := Sys.argv.(i+1) :: !dirs;  (* this throws on ending -I *)

  (* make a temporary .ml file and have it include the directories *)
  let ml_ext = ".ml" and cmo_ext = ".cmo" and cmi_ext = ".cmi" in
  let tmp_ml = Filename.temp_file "mktopinc" ml_ext in
  let tmp_oc = open_out tmp_ml in
  output_string tmp_oc "let _ = \n";
  output_string tmp_oc "List.iter Topdirs.dir_directory [\n";
  List.iter (fun dir -> output_string tmp_oc
      ("\"" ^ (String.escaped dir) ^ "\"; ")) !dirs;
  output_string tmp_oc "\n]";
  close_out tmp_oc;

  (* compile the temp file *)
  let tmp_root = String.sub tmp_ml 0
      (String.length tmp_ml - String.length ml_ext) in 
  let tmp_cmo = tmp_root ^ cmo_ext in
  let ec = ref (Sys.command ("ocamlc -c " ^ tmp_ml)) in
  if !ec = 0 then
    (* link the new toplevel *)
    ec := Sys.command("ocamlc -linkall toplevellib.cma "
                     ^ args ^ " " ^ tmp_cmo ^ " topmain.cmo");
  remove_file tmp_ml;
  remove_file tmp_cmo;
  remove_file (tmp_root ^ cmi_ext);
  exit !ec

To unsubscribe, mail  Archives: