# Dune - full path in libraries and modules

**URL:** <https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834>\
**Category:** Ecosystem\
**Tags:** dune\
**Created:** [November 6, 2018, 12:10am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834 "2018-11-06T00:10:06Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![vzaliva](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/vzaliva/32/206_2.png) [@vzaliva](https://discuss.ocaml.org/u/vzaliva)\
**Post date:** [November 6, 2018, 12:10am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/1 "2018-11-06T00:10:06Z")

</div>

I am building an executable which depends on 3rd party somefile.ml. I want to do something like this:

```
(executable
  (name test)
  (modules test ../../lib/somefile))

```

Unfortunately, this does not work. The error is:

Error: Module …/…/lib/somefile doesn’t exist. I also tried to make it into a library with (wrapped fasle):

```
(executable
  (name test)
  (libraries extracted core .../../lib/)
  (modes byte))

```

Which also does not work. Any workarounds?

---

<div class="post-metadata">

**Author:** ![rgrinberg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rgrinberg/32/40_2.png) [@rgrinberg](https://discuss.ocaml.org/u/rgrinberg)\
**Post date:** [November 6, 2018, 12:22am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/2 "2018-11-06T00:22:30Z")

</div>

Note that the libraries field only accepts library names. You will not be able to use module names or file paths in that field.

The best workaround for your problem is to use the `copy_file#` stanza. For example:

```auto
(copy_file# ../../lib/somefile)

```

---

<div class="post-metadata">

**Author:** ![vzaliva](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/vzaliva/32/206_2.png) [@vzaliva](https://discuss.ocaml.org/u/vzaliva)\
**Post date:** [November 6, 2018, 12:28am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/3 "2018-11-06T00:28:14Z")

</div>

Thanks. It will work for a single file.

I do not see why `libraries` stanza enforces local path. If I have a folder `foo` with the following dune file:

(library  
(name foo)  
(wrapped false))

I can use it as `(libraries foo)` when it is local, but not as `(libraries ../../foo)` if it happens to reside elsewhere.  
It is a limitation.

---

<div class="post-metadata">

**Author:** ![vzaliva](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/vzaliva/32/206_2.png) [@vzaliva](https://discuss.ocaml.org/u/vzaliva)\
**Post date:** [November 6, 2018, 12:31am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/4 "2018-11-06T00:31:20Z")

</div>

Is `copy_file#` part of dune-1.2.1? I could not fund it in documentation and trying to use it does not work.

---

<div class="post-metadata">

**Author:** ![rgrinberg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rgrinberg/32/40_2.png) [@rgrinberg](https://discuss.ocaml.org/u/rgrinberg)\
**Post date:** [November 6, 2018, 12:34am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/5 "2018-11-06T00:34:01Z")

</div>

`libraries` does not enforce any local paths. It does not work with paths at all. Briefly, `libraries` accepts names that were set either in the `name` or `public_name` field of libraries. However, the `name` field will only be available in the scope of the library (the `.opam` file defines that).

If you would like to include libraries defined in another project on your file system, you can simply symlink the directory where that library is defined into your project by the way. It does not make so much to copy modules from external libraries.

I made it a mistake, it is actually called `(copy_files# ..)` and it also accepts globs if you would like to copy multiple files.

---

<div class="post-metadata">

**Author:** ![vzaliva](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/vzaliva/32/206_2.png) [@vzaliva](https://discuss.ocaml.org/u/vzaliva)\
**Post date:** [November 6, 2018, 12:39am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/6 "2018-11-06T00:39:55Z")

</div>

```
(executable
  (name test)
  (copy_files# ../lib/file.ml)

```

Gives me:

```
Error: Unknown field copy_files#
```

---

<div class="post-metadata">

**Author:** ![rgrinberg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rgrinberg/32/40_2.png) [@rgrinberg](https://discuss.ocaml.org/u/rgrinberg)\
**Post date:** [November 6, 2018, 12:41am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/7 "2018-11-06T00:41:06Z")

</div>

Note that I stated that `copy_files#` is a stanza. That’s like a top-level command in a dune file. So it should be:

```auto
(copy_files# ../lib/file.ml)

(executable (name test))

```

---

<div class="post-metadata">

**Author:** ![vzaliva](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/vzaliva/32/206_2.png) [@vzaliva](https://discuss.ocaml.org/u/vzaliva)\
**Post date:** [November 6, 2018, 12:46am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/8 "2018-11-06T00:46:04Z")

</div>

Thanks! We are making some progress here 🙂 Now I am hitting this error:

```
Error: path outside the workspace: ../lib/file.ml from .
```

---

<div class="post-metadata">

**Author:** ![rgrinberg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rgrinberg/32/40_2.png) [@rgrinberg](https://discuss.ocaml.org/u/rgrinberg)\
**Post date:** [November 6, 2018, 1:04am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/9 "2018-11-06T01:04:58Z")

</div>

Could you describe your problem a bit more by the way? Are you trying to import a source from the same project? Or is it a different project? By project, I mean a `dune-project` here.

If you’re importing a library from a different project, I recommend that you either:

1. Create a workspace that would include both projects. This would mean having a dir structure like:

```auto
ls workspace/
 proj1/
 proj2/

```

1. Simply symlink proj2 into you proj1.

---

<div class="post-metadata">

**Author:** ![vzaliva](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/vzaliva/32/206_2.png) [@vzaliva](https://discuss.ocaml.org/u/vzaliva)\
**Post date:** [November 6, 2018, 1:31am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/10 "2018-11-06T01:31:14Z")

</div>

There is a project called Vellvm, which generates some OCaml code from Coq. It’s OCaml source includes:

1. Auto-generated code (during build)
2. Library code `llvm_printer.ml`
3. Sample main/testing code

I switched it from ocamlbuld to dune. The pull request is pending and they are about to merge it. [https://github.com/vzaliva/vellvm/tree/dune](https://github.com/vzaliva/vellvm/tree/dune)

Now, there is another project, HELIX, which wants to use Vellvm as a library. [https://github.com/vzaliva/helix/tree/LLVM](https://github.com/vzaliva/helix/tree/LLVM) It also generates some OCaml code from Coq and using dune.  
Right now it assumes that vellvm will be a git submodule (or symlink) under `lib`.

HELIX Coq code depends on Vellvm Coq code. This works pretty well. When generating ML code, it creates files `ml/extracted`. Vellvm Coq code is re-used and re-extracted as ML here. So far so good.

Now I am trying to find a way to have some additional OCaml code from Vellvm re-usable in projects like HELIX. Currently, it is just `llvm_printer.ml` but there might be more in the future. The directory structure is:

```
HELIX/
     + lib/
          + vellvm/
             + src/
                 +ml/
                    dune-project
                    dune
                    llvm_printer.ml
                    extracted/
                      dune
                      *.ml
                    main.ml
  + ml/
      dune-project
      dune
      extracted/
          dune
          *.ml
      test.ml

```

One of the problems is that `llvm_printer.ml` depends on some modules from `extracted`. Luckily they are the same in both Vellvm and HELIX as they generated from the same Vellvm Coq code.

One reason I’ve chosen to use dune here is the promise of _composable builds_. But I may have misunderstood the limitations…

---

<div class="post-metadata">

**Author:** ![rgrinberg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rgrinberg/32/40_2.png) [@rgrinberg](https://discuss.ocaml.org/u/rgrinberg)\
**Post date:** [November 6, 2018, 3:25am UTC](https://discuss.ocaml.org/t/dune-full-path-in-libraries-and-modules/2834/11 "2018-11-06T03:25:45Z")

</div>

In dune, the unit of composition of rules is the directory. So dune will discover all rules in starting from a root (workspace or project) and will have a unified view of the build in terms of libraries, executables, etc. However, the unit of sharing code is the library. So if you want your `llvm_printer.ml` source to be re-usable it must be in some library. Once you define this library (using the library stanza), it will be usable in HELIX it will be usable under the `public_name` you give this library. This is provided that you’re in a workspace that includes both projects of course. That is usually easy enough to arrange using symlinks or just putting related projects in root directory.
