Merlin complains about a missing module in the same project

5.7k Views Asked by At

I am new to Ocaml and just setting up my dev environment with emacs, merlin and flycheck. Everything works more or less expected except one thing : merlin doesn't seem to be able recognise the dependencies between the modules in the same project.

e.g. I have a test project with two modules: main.ml and awesome.ml.

here is my main.ml which references the second module awesome.ml

(* main.ml *)
open Core
module A = Awesome
let _ =
   Printf.printf "hello \n Converted to string we get: %s\n"
     (A.str_of_t (A.succ A.one_t));

here is awesome.ml:

(* awesome.ml *) 
type t = int
let one_t = 1
let succ i = i + 1
let str_of_t = string_of_int

when I send main.ml buffer to evaluate into utop with utop-eval-buffer function, I am getting an error: "Error: Unbound module Awesome"

I have .merlin in the root of the project which has S instruction. I know it is found by merlin as it doesn't complain about "open Core"

S src
PKG core lwt ounit
B _build/src
B +threads

here is my _tags:

<src/**>: include
<src/**>: package(oUnit), package(core)
true:thread

the regular project compilation with ocamlbuild works fine, no errors. here is Makefile

## Makefile
default: main
main: main.native

test: test.native

%.native:
   ocamlbuild -use-ocamlfind $@
   mv $@ $*

.PHONY: test default

any ideas why Awesome module is not recognised in utop or this is expected behaviour?

3

There are 3 best solutions below

1
On

I had the same problem. I tried installing merlin through opam or sources, but I couldn't solve this problem until I put the ".merlin" file in to the \src directory--not at the root-- with a "REC" tag in it.

5
On

Merlin will see other modules once you have compiled them (in fact, once you have compiled its interfaces). So given your .merlin is correct it will see everything after you run compilation. Your files should indeed be in a src folder, i.e., your project layout, based on your .merlin file should look like this:

Makefile
.merlin
src/
   awesome.ml
   main.ml

This is not a required layout, but this is the one, that you described to Merlin. The reason, why I suspect that it is not the same, is your Makefile.

P.S. Just as a side note, there is a small issue in your code: you should open Core.Std not Core.

4
On

As Ivan's answer pointed out, Merlin can only recognize a module in your project after you compile it. If Merlin is giving you an unbound module Foo error, one solution is to run

ocamlbuild foo.cmi