ocamldep example of a minimal makefile does not compile OCaml files correctly #12925
Description
ocamldep example of a minimal makefile does not compile OCaml files correctly. I'm not sure how to fix it–if you can advise I'd be happy to PR
Steps to repro
Copy the makefile from the docs for ocamldep, saving it as makefile
:
https://v2.ocaml.org/manual/depend.html#s:ocamldep-makefile
In the same directory, create source files mod1.ml, mod2.ml, mod3.ml,mod4.ml,mod5.ml:
echo 'let () = print_endline Mod2.value' > mod1.ml
echo 'let value = "hello1"' > mod2.ml
echo 'let value = ""' > mod3.ml
echo 'let () = print_endline Mod5.value' > mod4.ml
echo 'let value = "hello2"' > mod5.ml
Expected behavior
make prog1 && ./prog1
should print "hello1".make prog2 && ./prog2
should print "hello2".- then
make clean
should restore the directory to how it was before (only a makefile and .ml files)
Actual behavior
fails in a variety of ways. Here's what I tried:
$ make
makefile:15: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
# replace all each 4-spaces with a tab and try again
$ make
make: *** No rule to make target '.depend'. Stop.
I change the depend
rule to .depend
:
- depend
+ .depend
$ make
ocamldep *.mli *.ml > .depend
ocamlc -c mod2.ml
ocamlc -c mod1.ml
ocamlc -c mod3.ml
ocamlc -o prog1 mod1.cmo mod2.cmo mod3.cmo
File "_none_", line 1:
Error: Required module `Mod2' is unavailable
make: *** [makefile:15: prog1] Error 2
The generated arguments to ocamlc
at this point are incorrect, since mod1.cmo
has symbols defined in mod2.cmo
. A corrected version is: ocamlc -o prog1 mod2.cmo mod1.cmo mod3.cmo
.
The incorrect order is hard-coded in the Makefile, so we can manually fix. But that seems to defeat the purpose of using ocamldep
to dynamically discover the build order. How can we use the discovered dependency structure to invoke the compiler with dependencies in the right order?.
To see what happens, I did this manual tweaking:
- PROG1_OBJS=mod1.cmo mod2.cmo mod3.cmo
+ PROG1_OBJS=mod2.cmo mod1.cmo mod3.cmo
Then make prog1 && ./prog1
prints "hello1" (success).
However make prog2
fails, for a similar reason, and requires manual re-ordering PROG2_OBJS