Skip to content

ocamldep example of a minimal makefile does not compile OCaml files correctly #12925

Open
@mheiber

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



Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions