How to Make Library Installed from Opam Available to Ocaml

Telling OCaml where opam packages are

You can tell the OCaml compiler where your Opam packages are by passing the location of the libraries:

ocamlopt -I /path/to/lib/base /path/to/lib/base/base.cmxa helloword.ml

In the case of a library like base, finding all the parameters might become tedious due to the various dependencies. So, you can instead use the ocamlfind wrapper to pass the parameters for you:

ocamlfind ocamlopt -package base -linkpkg helloword.ml

Linking to a library in a non-standard path when installing an opam package

It is not possible to tell opam anything about the C compiler linking rules, neither about OCaml linking rules, or any other compilation rules, as opam is much above this. The responsibility of opam is to find a package with the best suiting version, download it, and install using the build and configuration scripts that are provided by the package maintainer.

Although opam provides facilities for package configuration parameters, the conf-zmq maintainer is not utilizing them and do not provide any parameterization for their package. In fact, there are no other options to pass the installation test of the conf-zmq package, other than installing them in the hardcoded location. You can submit a bug-report or ask the maintainer for further support. You can find all the links in the opam file of the package.

The good news is that there is a workaround. If the package description is broken, then you can always download the package to your local filesystem, fix it, and the pin the fixed version. And opam will now use your local version. If you want to distribute your package, you will need to push your changes upstream of course (if you want it to be available to the general public (i.e., via ocaml.org), or just have your own opam repository (that may contain only one package or many packages).

But for starters, here the first drop-in instructions, first obtain the sources either by cloning it from the GitHub repository or just by issuing the following command:

opam source zmq

You can then change your working directory to the folder that opam has created for you, e.g., for me it was

cd zmq.5.1.3/

Then (the hardest part) hack the package to make it installable on your system. (The first thing that you need is to drop the dependency on the broken conf-zmq package). Once you're ready, or think that you're ready just do

opam pin add .

opam should pick the package names from the opam files, but if it won't do this see opam pin --help for more options. It will then try to install the pinned package. If it fails, then continue hacking and doing

opam update
opam reinstall zmq # or install

Once the patch is ready, you can either embed it in your automation or create your own opam repository. It is also very easy, just create a new GitHub repo (or clone the ocaml/opam-repository, not recommended) then copy the package definition that you would like to change (for us it would be packages/zmq/zmq.5.1.3/) and apply your hacks to the opam and configurations scripts. If your hacks also include changes to the zmq source code, you can format them as patches and add use the patches stanza in your opam file to apply them on the fly.

How to install a specific OCaml branch on github as an opam switch

If I'm not mistaken, the version of the compiler used by a given switch is governed by one package among ocaml-base-compiler, ocaml-system-compiler and ocaml-variants. These packages can be handled, and in particular pinned, like any normal opam package. Thus, if you create an empty switch (e.g. opam switch create eintr-again --empty), and pin ocaml-variants to the branch you're interested in (opam pin add ocaml-variants https://github.com/stedolan/ocaml.git#eintr-again), you should obtain the compiler version you want in that switch.

Why are some standard ocaml libraries opam packages and some are not?

Libraries with OPAM package names base-XXX are optional libraries: they are from OCaml compiler itself, but they may or may not be installed depending on the computer environment, os and build configuration flags of the compiler. Existence of base-unix for example means that unix library is available in that environment.

On the other hand, str library is not system dependent and therefore available anywhere OCaml is installed. Therefore OPAM does not need to provide its base package explicitly to tell the existence of the library.

Though str exists for all the OCaml installations, its linking is not automatic. That's why ocamlfind requires a package for it.

OPAM packages are for installation by opam command. OCamlFind packages are for linking. They are related but different. Confusing but this is what we have in OCaml eco system for now.

Basic Oasis or Opam file for a simple OCaml project

So, first of all your don't have any active targets in your _oasis file. What I mean, is that OASIS is about building exectuables and libraries. You haven't described either. That means, that your BuildDepends doesn't have any effect, since it has only sense for Library and Executable entries. So, a first approximation would be the following:

OASISFormat: 0.4
Name: Playground
Version: 0.1.0
Synopsis: OCaml playground
Authors: Andrea Ferretti
License: Apache-2.0
BuildTools: ocamlbuild
BuildDepends: irmin.unix, lwt.unix

Executable "example"
Path: .
MainIs: example.ml
CompiledObject: best

Doing so, I end up with Irmin version 0.8.3. Unfortunately, I cannot
follow their examples, because apparently Irmin is at version 0.9.4,
and it looks like the API has changed. So, I would like to start a
clean project having as dependency just Irmin 0.9.4

If you got a version that is not the newest, then you can try to persuade opam constraint solver, that you really need that specific version, like:

 opam install irmin.0.9.4 git cohttp

Also, opam internal constraint solver isn't very sophisticated, so make sure that you have aspcud installed on your system. The following will install the latest opam with aspcud on a fresh ubuntu installation:

sudo add-apt-repository --yes ppa:avsm/ppa
sudo apt-get update
sudo apt-get --yes install opam

What is the simplest way to set up a clean project that depends on Irmin 0.9.4, being sure that it is self-contained (it will not rely on
preinstalled libraries other than those installed by the build
process)?

Well, simplicity is a matter of personal opinion. For example, you can do the same without any oasis at all, just using opam file, where you set your build field, just to ["ocamlbuild"; "-use-ocamlfind"; "-pkgs irmin.unix,lwt.unix"; "example.native"], but how well it will scale...

Install Ocaml older version, because libraries fail

You're installing everything correctly and there is no need to downgrade opam. You didn't actually show what was the problem. The error message shows that something has finally failed, but the actual error message was above. There was also a message that contains paths to error logs. I tried to install 3.09.3 on mine machine using opam switch create 3.09.3 and it went without any issues,

$ opam switch create 3.09.3

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[ocaml-base-compiler.3.09.3] downloaded from cache at https://opam.ocaml.org/cache

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base
∗ installed ocaml-base-compiler.3.09.3
∗ installed ocaml-config.1
∗ installed ocaml.3.09.3
Done.

So it could be that there were some issues local to your system, like you run out of space, for example.

With that said, you can still try to run these examples in the modern version of OCaml. To enable nums in the modern versions of OCaml, you need to install the package (which is no longer distributed along the OCaml compiler but is still available in opam),

opam install num

Then, you can load num in a toplevel (the ocaml interpreter), using the following

#use "topfind";;
#require "num-top";

The num-top library will load the nums library and even install toplevel printers to make your interacting with arbitrary precision numbers more comfortable. Those two lines should go instead of the #load "nums.cma";; line in the init.ml file.



Related Topics



Leave a reply



Submit