# Linking library without full path

**URL:** <https://discuss.ocaml.org/t/linking-library-without-full-path/14009>\
**Category:** Learning\
**Created:** [February 6, 2024, 1:41pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009 "2024-02-06T13:41:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![TobyK](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TobyK](https://discuss.ocaml.org/u/TobyK)\
**Post date:** [February 6, 2024, 1:41pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/1 "2024-02-06T13:41:58Z")

</div>

It’s been a while since I used Ocaml and perhaps my setup is now incorrect but I can’t seem to use a standard opam-installed library without specifying the full path. I’ve done:

> opam update -u; opam switch 5.0.0; eval `opam config env`; opam user-setup install

and using `ocamlfind ocamlc -only-show` tells me the correct compile command is

> ocamlc.opt -o testprog.exe -I /home/toby/.opam/5.0.0/lib/zarith /home/toby/.opam/5.0.0/lib/zarith/zarith.cma testprog.ml

which works, but I have to include the full library path. The following commands

> ocamlc.opt -o testprog.exe zarith.cma testprog.ml  
> ocamlc.opt -o testprog.exe /home/toby/.opam/5.0.0/lib/zarith/zarith.cma testprog.ml  
> ocamlc.opt -o testprog.exe -I +zarith zarith.cma testprog.ml

all give me the dreaded “Unbound module” error.

I have these set;

> OPAM\_SWITCH\_PREFIX=‘/home/toby/.opam/5.0.0’; export OPAM\_SWITCH\_PREFIX;  
> CAML\_LD\_LIBRARY\_PATH=‘/home/toby/.opam/5.0.0/lib/stublibs:/home/toby/.opam/5.0.0/lib/ocaml/stublibs:/home/toby/.opam/5.0.0/lib/ocaml’; export CAML\_LD\_LIBRARY\_PATH;  
> OCAML\_TOPLEVEL\_PATH=‘/home/toby/.opam/5.0.0/lib/toplevel’; export OCAML\_TOPLEVEL\_PATH;

How can I compile and link with libraries such as zarith without having to specify full paths or use ocamlfind every time?

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [February 6, 2024, 2:35pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/2 "2024-02-06T14:35:15Z")

</div>

I guess the nowadays approach consists to have a `dune-project` and a `dune` files and lets `dune` search the library. When all is setup, a single `dune exec ./testprog.exe` compile the program if needed and launch it.

---

<div class="post-metadata">

**Author:** ![TobyK](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TobyK](https://discuss.ocaml.org/u/TobyK)\
**Post date:** [February 6, 2024, 2:55pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/3 "2024-02-06T14:55:21Z")

</div>

OK I will look into that, but it is strange the compiler cant find the module interface or library using the environment variables when it is installed in a standard place. In particular I don’t know why ‘-I +zarith’ doesn’t work.

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [February 6, 2024, 3:06pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/4 "2024-02-06T15:06:38Z")

</div>

The `+` is only useful for the handful of libraries bundled with the compiler, which is not the case for `zarith`.

---

<div class="post-metadata">

**Author:** ![TobyK](https://avatars.discourse-cdn.com/v4/letter/t/82dd89/32.png) [@TobyK](https://discuss.ocaml.org/u/TobyK)\
**Post date:** [February 6, 2024, 3:13pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/5 "2024-02-06T15:13:56Z")

</div>

Ok, that’s not mentioned in the man page: “Add the given directory to the list of directories searched”

---

<div class="post-metadata">

**Author:** ![vlaviron](https://avatars.discourse-cdn.com/v4/letter/v/ec9cab/32.png) [@vlaviron](https://discuss.ocaml.org/u/vlaviron)\
**Post date:** [February 6, 2024, 3:33pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/6 "2024-02-06T15:33:00Z")

</div>

The OCaml compiler still operates on a model where it controls where its own libraries are installed, but not others. So `-I +unix/` means that you expect the compiler to have installed unix in a subdirectory of its standard library location, and this works because unix is shipped by the compiler.  
On the other hand, external libraries like `zarith` can be installed in arbitrary ways (through `opam`, your system package manager, or by hand), so you cannot rely on it being located close to the standard library.  
(The compiler knows where it is going to be installed itself, so I guess we could add support for syntax like `~lib/zarith` to point to the library folder of the installation target, but given that `ocamlfind` already does a very good job of dealing with these issues it is not a priority.)

You can use `ocamlfind` to either generate whole command-line, like you did, or just find the library for a specific package (`ocamlfind query zarith`). The second option would likely be useful if you want to integrate it in your own build system.

Finally, if you know your packages come from `opam` and are installed in predictable ways, you can also ask `opam` for the path to its installation library and use it to semi-hardcode paths: `$(opam var lib)/zarith`.

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [February 6, 2024, 4:22pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/7 "2024-02-06T16:22:30Z")

</div>

I think the issue is that `zarith` used to (and maybe still does) install itself in the OCaml standard library directory if `ocamlfind` was not available. In that case, simply passing `-I +zarith` would work.

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![xavierleroy](https://avatars.discourse-cdn.com/v4/letter/x/a9adbd/32.png) [@xavierleroy](https://discuss.ocaml.org/u/xavierleroy)\
**Post date:** [February 7, 2024, 4:46pm UTC](https://discuss.ocaml.org/t/linking-library-without-full-path/14009/8 "2024-02-07T16:46:11Z")

</div>

> [@TobyK](#):
>
> How can I compile and link with libraries such as zarith without having to specify full paths or use ocamlfind every time?

There’s nothing wrong with using ocamlfind “every time”, i.e. for all invocations of the OCaml compilers: it’s lightweight and handles library packages very well. Or, use Dune as a build manager, it will also handle library packages correctly.

The ZArith readme should be updated to not mention `-I +zarith`, which no longer works.
