Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to place a shared utility module in OCaml?

Tags:

module

ocaml

I have a file Tools.ml which contains some common utility functions I write myself. Under .../Code/ I have several folders which each contains a project. My question is where I should place this Tools.ml such that all the folders and files under .../Code/ could share this module by Open Tools.

Hope my question is clear... Does anyone have a good solution?

Edit1: Following @gasche's answer, I have written tools.ml as follows:

module Tools =
  struct
    let a_function = ...
    ...
  end

Then I compiled it, and done ocamlfind install tools META tools.cmo tools.cmx tools.ml as suggested, which looks going well. Then I have written test.ml as follows:

open Tools

let f = Tools.a_function

then I compiled it with ocamlc test.ml -o test, then I got an error:

File "test.ml", line 1, characters 0-1:
Error: Error while linking test.cmo:
Reference to undefined global `Tools'

Could anyone tell me what happened?

like image 691
SoftTimur Avatar asked Dec 29 '11 04:12

SoftTimur


People also ask

How do I load a module in OCaml?

You must compile the module you wish to include first, provide the location of the compiled files to compilation commands of modules depending on it, then provide it in the final compilation command line. The commands: $ cd foo $ ocamlc -c moduleA.ml $ cd .. will produce moduleA.


1 Answers

You could package it as an independent library, install it with other OCaml libraries, and access to it, from your project, as a library.

A very simple way to do this is to write a META file for ocamlfind. Create a directory somewhere you're comfortable to hold you "personal library" project. Suppose you have tools.ml and tools.mli, and your code depends on some findlib package (eg. unix and bigarray). You META would look like this:

name="tools"
description="personal collection of utilities"
version="0.1"
requires="unix,bigarray"
archive(byte)="tools.cmo"
archive(native)="tools.cmx"

Once you have written this META file, it is easy to ask ocamlfind to "install" the library (and remove it if you want to), and use it in your other projects. To install, the syntax is ocamlfind install <name> <meta-file> <file1> <file2> ... where <file1>, <file2>.. are the file you wish to see included in the installation directory. You must at least have tools.cmi tools.cmo (and tools.o and tools.cmx for native compilation), but it is good practice to also have tools.mli for example (and, if you want to provide the code, tools.ml).

ocamlfind install tools META tools.cmi tools.cmo tools.o tools.cmx tools.mli

(Of course tools.cmo etc. have to exist, that is you must install after you have compiled your package. If you have used ocamlbuild, they are likely to be in a _build subdirectory, so ocamlfind install ... _build/tools.cmo ....)

From your numerous projects, you can use your library easily, either using the ocamlfind toold directly if this is what you already do to compile your programs

ocamlfind ocamlc -package tools ....

or through the facilities provided by ocamlbuild for example, adding package(tools) to your tags.

To reinstall your library if you made a change to it and want it accessible from your projects

ocamlfind remove tools
ocamlfind install tools META ...

You could also handle all this through oasis, which is a layer on top of ocamlfind/ocamlbuild to automate this process. I'm not familiar enough with oasis to give such examples off the top of my head, but it should be equally simple for such a restricted case (one-file library), and scale better if you wish later to extend your library (eg. it can also handle documentation generation, pre-compilation configuration...).

like image 153
gasche Avatar answered Nov 14 '22 20:11

gasche