Merlin complains about a missing module in the same project
Asked Answered
S

3

13

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?

Statius answered 19/7, 2015 at 9:16 Comment(0)
S
14

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.

Semivitreous answered 19/7, 2015 at 14:23 Comment(5)
thanks Ivan. It still doesn't work. I have a correct project layout - the sources are in src dir, .merlin is in the root of the project. The reason for B +thread directive is here : github.com/the-lambda-church/merlin, I added as suggested in merlin docs. You are right about open Core.Std. I ran the compilation - the sources compile correctly, I see o files in _build/src but merlin still doesn't recognise the awesome.ml module. Looks like something is wrong with my setup - I will keep digging. Thanks!Statius
I suspect, that you have problems, with your makefile, and it doesn't compile anything. So, without a Makefile file, if I will just go to the top directory of your project and issue ocamlbuild src/main.native, then merlin recognizes Awesome module. Basically, you Makefile looks incorrect to me. And it just do not compile anything. A good check: there should be _build/src/awesome.cmi file after running build.Semivitreous
nope, makefile is good - it compiles, produces a binary main which I can execute. awesome.cmi/awesome.cmo/awesome.cmt/awesome.cmti/awesome.cmxare generated in _build/srcStatius
Well, then the next guess would be, that your emacs is somehow misconfigured. Look carefully, for the messages from emacs. The easiest way to run it without a problem is to run emacs from a terminal in which you previously run eval $(opam config env)Semivitreous
thanks, I will check my emacs setup. much appreciated.Statius
S
2

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
Selfexistent answered 21/10, 2015 at 18:4 Comment(4)
This actually completely fixed it for me and I have no idea why. Does ocamlbuild somehow save state? I'm pretty new, so it's entirely possible that I just am very ignorant of how the whole dev environment works hahInvoluted
Ocamlbuild will save the "foo.cmi" interface file inside the "_build" directory. Which I guess counts as "saving state".Selfexistent
Ohhh makes sense. I assumed Merlin was looking at the second and not built files I guess. Guess I was wrong!Involuted
Very odd… I got the same problem, but compiling the CMIs didn’t solve it. 😢Mowery
H
1

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.

Heiser answered 19/8, 2016 at 12:50 Comment(1)
I did the same, but Merlin keeps complaining about modules that are there. One of two: there are magical undocumented settings; or there are annoying bugs.Mowery

© 2022 - 2024 — McMap. All rights reserved.