Ocamldoc and open modules - ocaml

I'm trying to document a small project of mine using ocamldoc.
I have one main .ml file which opens two others .ml files.
$ ocamldoc -html included1.ml included2.ml
Works just fine, but when I add the including file, like
$ ocamldoc -html included1.ml included2.ml including.ml
I get this:
File "including.ml", line 5, characters 5-16:
Error: Unbound module Included1
1 error(s) encountered
I see from the ocamldoc documentation that opening modules is perfectly fine, until no conflict arises.
How should I proceed?

It's fine for a module to use other modules however it needs to be able to see the compiled interfaces for those. So in your case you first need to compile the .ml files to generate .cmi files. Then you need to indicate to ocamldoc where these files are. So something like this should do:
ocamlc -c included1.ml
ocamlc -c included2.ml
ocamlc -c -I . including.ml
ocamldoc -html -I . included1.ml included2.ml including.ml
Note that in general it's a good (essential) practice to create .mli files for each of your modules an document and ocamldoc these rather than the .ml files.

Related

Unbound Module (Personal Files)

I have two .ml files, type.ml and main.ml, in the same directory.
I am following this official link: https://ocaml.org/docs/modules
File main.ml:
open Type
let () = print_endline "Hello World!"
I compile with this line, accordingly to the tutorial:
ocamlopt -o main main.ml type.ml
However, I have this error:
Error: Unbound module Type
The source files need to be ordered with the dependencies coming before the dependent. That is, it should be:
ocamlopt -o main type.ml main.ml
This is somewhat vaguely explained in the manual:
The order in which .cmx and .ml arguments are presented on the command line is relevant: compilation units are initialized in that order at run-time, and it is a link-time error to use a component of a unit before having initialized it. Hence, a given x.cmx file must come before all .cmx files that refer to the unit x.
Also, if you're doing anything more significant I would recommend using a build system like dune to avoid having to mess with details like this.

(Ocaml) unbound module error on visual code

I have just started to learn Ocaml.
I'm using visual code as my IDE on Ubuntu,
and I have OCaml extension and merlin installed.
and I have the following problem -
my workspace folder contains only 2 files:
a.ml and b.ml.
In the file a.ml I have defined a module named "COOL", and in the file b.ml I wrote:
~ b.ml ~
open COOL;;
I get an error that says "Unbound module COOL merlin"
Is there any way to make it see the module on file a.ml?
I tried searching for solution, I saw something with makefile and .merlin and B build
but I didn't understand it, I don't have anything but the 2 files I mentioned.
I would be happy if someone can tell me what exactly should be done in order for this little example to work.
tl; dr: do ocamlc -c a.ml (or whatever your compilation command is) in order to generate the a.cmi file that merlin will use to get the list of symbols defined in module A.
Apart the fact that in b.ml your module is indeed named A.COOL (unless you open A before open COOL) as mentioned by glennsl, the point is that merlin is, as far as I know, only watching the current file being edited, i.e. b.ml in your case. In order to have access to external symbols, you thus need to have compiled the other files (or at least their corresponding .mli if they exist), in order to have the relevant .cmi files available to merlin.
This is implicit in the paragraph of the documentation describing build paths, which says "[merlin] needs to know where to find the cmi files of the other modules of your project", i.e. those files need to exist in the first place.

Compiling and Running Ocaml Script from the Terminal

I have files called assert.ml, assert.mli, test.ml and test.mli stored in a folder. assert is I guess you'd call it a library file--it's something I downloaded but didn't write myself. test.ml is a file containing the script
;; open Assert
;; print_endline "test"
In the terminal I navigate to the containing folder and run
$ ocamlc -c assert.mli test.mli
$ ocaml assert.ml test.ml
Nothing happens as a result. However, if I remove the ;; open Assert line from the script and run
$ ocaml test.ml
then it prints.
As a note, I've had some people tell me not to write the open command as ;; open Assert but the advice seems entirely stylistic. I have to write it this way for the class I'm taking.
If anyone can explain to me how I ought to be compiling and running differently I'd appreciate it. I tried following some other guides' advice in using ocamlopt instead but when I ran it, no executable file was produced as a result.
The ocaml command is the REPL for OCaml. The command line looks like this:
ocaml [ object-files ] [ script-file ]
An object file is a compiled (bytecode) module, which is produced by the ocamlc command. These files end with .cmo. A script file is a file of OCaml source code, which ends with .ml.
Note that only one script file is allowed.
The command you say you're using has two script files and no object files. So, it's not surprising that it doesn't work. In my experiments, what ocaml does is run just the first of the two script files. I believe this explains what you see. One of your files produces output, and it will be run if you give it first. The other produces no output, so there is no output when that file is given first.
What you should probably be doing is producing a .cmo file for the Assert module.
That would look like this:
$ ocamlc -c assert.mli assert.ml test.mli
Then you should run ocaml with one object file and one script file, like this:
$ ocaml assert.cmo test.ml

Using ocamlmktop with ocamlbuild

I have a project that builds successfully using ocamlbuild. However, I would also like an easy way to interact with the project's individual functions from different modules via the toplevel but my attempts at using ocamlmktop haven't worked out as I'd like. I've found that unless I manually put the .cmi files in the active directory, I get an "Unbound module" error. The command I'm currently using to build is:
ocamlfind ocamlmktop -I _build -o my_ocaml -linkpkg -package str module1.cmo module2.cmo
Is there a better, less hacky way to get the toplevel to work in this project structure without moving cmi files out of the _build directory?
Edit: I've figured out that I can get it to load the types and modules if I run the toplevel as
./my_ocaml -I _build
But this still seems hacky. Is there a way to bake the search path or cmi files in perhaps?
Edit 2: I think the solution to my problem may actually be not to compile a custom toplevel at all given this restriction about interface files. I have instead added load directives to my .ocamlinit to use the modules. If anybody has better ideas to solve this, I'd greatly appreciate it.
You can build a toplevel by listing the module names you want in a my_ocaml.mltop file:
Module1
Module2
subdir/Module3
Then building the target my_ocaml.top will call ocamlmktop in the expected way, and you can run the resulting my_ocaml.top toplevel.
This does not change the way that you need to add _build to the include path for the type-checker to be able to find the .cmi files. You can do this when you invoke the toplevel by passing the command-line arguments -I _build, or from the toplevel with #dir "_build";; -- the last command can also be put in your .ocamlinit if you prefer.

OCamlbuild not resolving subdirectory dependency

I have an OCaml project and I'm running into a weird issue.
The directory structure looks like this:
./tests
test.ml
templatetest.ml
./src
template.ml
...
andsoforth.ml
I am building it like this:
ocamlbuild -Is src,tests tests/test.native
Key point being, tests/test.ml depends on tests/templatetest.ml.
When I build it, I get:
+ /usr/local/bin/ocamlc.opt -c -I tests -I src -o tests/test.cmo tests/test.ml
File "tests/test.ml", line 1, characters 0-17:
Error: Unbound module TemplateTest
Command exited with code 2.
Compilation unsuccessful after building 2 targets (0 cached) in 00:00:00.
I tried adding a _tags file in the top directory containing:
<src> or <tests>: include
That still produced the same error. (I believe ocamlbuild tests/test.native with the _tags file is the exact same thing as the previous build line I used.)
I also created an empty _tags file in both ./tests and ./src, but that didn't change anything either.
Any suggestions? If you need, the entire source is here. Just run make test. Thanks!
It a funny issue: not TemplateTest but Templatetest. For the former name, you module file should be named templateTest.ml