| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • Introducing Dokkio, a new service from the creators of PBworks. Find and manage the files you've stored in Dropbox, Google Drive, Gmail, Slack, and more. Try it for free today.

View
 

OcamlscriptDoc

Page history last edited by PBworks 12 years, 11 months ago

See also Ocamlscript. This page is now somewhat obsolete, although some things are explained more nicely here than in other places.

 

Documentation for Ocamlscript 2.0 (in progress)

 

Ocamlscript is a utility for compiling and running OCaml scripts. As opposed to the standard ocaml command, it compiles the program to native code instead of byte code, which usually makes the program faster. In addition to that, it recompiles the script only when an update is required by comparing the last modification date of the script and the compiled executable, so compilation is performed once, unlike scripts that use the ocaml command.

 

The scripts themselves are pure OCaml, by they are normally preceded by a dedicated header where compilation options are specified. A variety of compilation options for OCaml are supported, including support for camlp4 and ocamllex. Complex libraries may be easily loaded using the Findlib package management system.

 

Ocamlscript compilation relies on a dedicated header, whereas ocaml relies on special directives such as #load or #require which are inserted in the program but are not valid for ocamlc or ocamlopt compilers.

 

Here is a script written for the ocaml, followed by the equivalent version using ocamlscript. They both load the PCRE-OCaml library using Findlib:

 

#!/usr/bin/ocamlrun ocaml
#use "topfind"
#require "pcre"
let _ = ...

#!/usr/bin/ocamlscript
Ocaml.packs := ["pcre"]
--
let _ = ...

 

Foreword about Unix scripts in general

 

The shebang (#!) line in Unix scripts is a line which tells the operating system how to execute a given file, when it is used directly as a command. How it works is out of the scope this tutorial and varies slightly from one OS to another.

 

In our examples we will assume that the ocamlscript command resides in /usr/bin, although it could be anywhere else. Our scripts will therefore start with #!/usr/bin/ocamlscript. The location of ocamlscript can also be found automatically in the directories specified by the PATH environment variable using the /usr/bin/env command, which hopefully will be at this place on every system. In that configuration, the first line of a script would be #!/usr/bin/env ocamlscript.

 

Please note that using this mechanism is optional. Any script can be executed using ocamlscript name-of-your-script.

 

Basic usage

 

A simple program that should be compiled with no options and no libraries is a plain OCaml program, may start with a shebang line and its name can be chosen freely:

 

#!/usr/bin/ocamlscript

print_endline "Hello"

 

This program named hello will be compiled if necessary and executed by the following command:

$ ocamlscript hello

Hello

 

Run it a second time and you should notice that it is faster since it doesn't need a recompilation.

 

We are assuming a Unix-kind of OS where ocamlscript is installed in /usr/bin, so after making the file executable (chmod u+x hello), we can also execute it as a command:

$ ./hello

Hello

 

 

You can notice that in the same directory as the hello file, a file hello.exe has been created. It is the binary executable version of the hello script, automatically compiled with the native code compiler. Each time you modify the original script hello, the compiled version hello.exe is re-compiled. Ocamlscript determines if a recompilation is needed based on the last modification date of the source script.

 

 

 

Loading libraries

 

Almost any useful script will require some libraries. Such compilation options need to be specified in a dedicated section of the ocamlscript script called the header. This first section is a short, specialized OCaml program which comes before the main script:

#!/usr/bin/ocamlscript
(* this is the header *)
Ocaml.packs := ["pcre"]

(* here comes the separator *)
--
(* this is the script *)
open Pcre
let _ =
  ...

 

The recommended way of loading libraries is to use the Findlib package manager. The example above shows that Findlib packages, i.e. those which have been installed with ocamlfind, can be loaded by setting the Ocaml.packs variable. Ocaml.packs has type string list ref: it is a global variable which holds the list of Findlib packages to use. The following aspects are taken care of automatically:

  • library location: you don't have to specify where each library is located, so it makes your scripts more portable;
  • dependencies: libraries that are required by a given package are automatically loaded;
  • syntax extensions: packages which provide a Camlp4 syntax extension pass the appropriate arguments to the preprocessor, so a single package name is enough to load both syntax and runtime libraries.

 

Now, if for some reason a library was not installed with Findlib but you know where it is located (maybe it is a library file in the current directory or a wild installation in OCaml standard library's directory), you can pass it to the compiler by using the Ocaml.ocamlflags variable. Like Ocaml.packs, it is a list of strings. Those strings can be any valid option that you may want to pass directly to ocamlopt. For example, here is how I could load a native code library named mylib.cmxa:

#!/usr/bin/ocamlscript
Ocaml.ocamlflags := ["mylib.cmxa"]
--
(* the modules provided by mylib.cmxa are now available *)
let _ =
  ...

 

Several other options can be more conveniently set using dedicated variables provided by the Ocaml module.

 

Multiple source files - "includes"

 

It is possible to use several source files instead of just one. There is still a main script, which will be read directly by ocamlscript, but the header of that script can instruct the compiler to use, compile and link other files. These other files are specified by the Ocaml.sources variable:

#!/usr/bin/ocamlscript
(* this is our main script, which uses 3 other source files *)
Ocaml.sources := ["../thing1.ml"; "thing2.ml"; 
                  "/home/lib/thing3.ml"]
--
open Thing1
open Thing2
open Thing3
...

The paths to these source files can be absolute or relative to the directory of the main script.

 

However, these files must be pure OCaml source files, with the usual constraints:

  • implementation files end in .ml,
  • interface files end in .mli,
  • their name without extension must be a valid module name once capitalized (e.g. no dash or space in their name),
  • files other than implementation (.ml) or interface (.mli) units are not supported yet.

 

The same compilation options, including Camlp4 preprocessing, are applied to the main script and to those files.

 

For speed purposes, a recompilation of the sources will be triggered only by comparing the last modification date of the main script against the last modification date of the executable (.exe). None of the "included" source files will be checked for modifications. To force a recompilation while developing, use ocamlscript -f your-main-script, or even ocamlscript -c -f your-main-script if you don't want to execute the program after compiling.

 

Compilation only

Recommended uses

Using a whole different compiler than ocamlopt

 

Technicalities

 

Installation

 

You will need following software:

 

Compilation:

make

 

Installation:

make install

By default, the ocamlscript command is installed in the same directory as the ocamlfind command. In the following we assume it is /usr/bin/.

 

 

Uninstallation:

make uninstall

 

Switching from Ocamlscript 1 to Ocamlscript 2

 

For compatibility with Ocamlscript 1, libraries can still be passed directly on the command-line or on the shebang line. This is now deprecated, but it can be a quick way to make older scripts compatible with Ocamlscript 2. The rule of thumb is: if only one library is given, add the phony argument "--" at the end, otherwise no change should be necessary. For example, if you had a script like that:

#!/usr/bin/ocamlscript unix.cmxa
(* Ocamlscript1 script *)
open Unix
...

You must change it into this:

#!/usr/bin/ocamlscript unix.cmxa --
(* Ocamlscript2-compatible script *)
open Unix
...

 

 

Reference manual (in progress)

Syntax

Command-line usage

 

Ocamlscript supports the following options:

-- marks the end of ocamlscript arguments
-help displays a help message and exit
--help same as -help
-c compile only
-o EXEC_NAME specify a name for the executable (required if the program is not read from a file)
-e PROGRAM execute the code given here instead of reading it from a file
-f force recompilation which is otherwise based on modification dates
-debug print messages about what ocamlscript is doing
-version prints the version identifier to stdout and exit
- read program from stdin instead of a file
-vm VIRTUAL_MACHINE run the executable using this virtual machine (e.g. ocamlrun)

 

Those arguments can be given on the command line calling ocamlscript (ocamlscript -debug name_of_my_script) or on the shebang line of script (#!/usr/bin/ocamlscript -debug). fixme: true??

 

 

The Ocaml compilation module

 

The Ocamlscript.Ocaml module defines following global variables:

 

Type
Meaning
camlp4ostring refname of camlp4o command
camlp4rstring refname of camlp4r command
ocamllexstring refname of ocamllex command
ocamlcstring refname of ocamlc command
ocamloptstring refname of ocamlopt command
ocamlfindstring refname of ocamlfind command
packsstring list reffindlib packages
use_ocamllexbool ref(default: false) if true, preprocess with ocamllex before camlp4
use_camlp4bool ref(default: true) if true, use camlp4
use_ocamlcbool ref(default: false) if true, use ocamlc instead of ocamlopt
use_ocamlfindbool ref(default: false) if true, force the use of ocamlfind
revisedbool ref(default: false) if true, use revised syntax
ocamlflagsstring list refany options that you may want to pass to ocamlopt
ppoptstring list refny options that you may want to pass to camlp4o or camlp4r

 

"Ocaml" is a submodule of the "Ocamlscript" module.

Ocamlscript also provides a global "Common" submodule and a "Pipeline" submodule. Their purpose is to make the integration of compilers for other languages easier. These modules are fully documented.

Comments (0)

You don't have permission to comment on this page.