Help wanted with building the standard library with modification

Hi all,

I have forked OCaml to add functor, applicative, and monad interfaces to the standard library. The Applicative module depends on the Functor module, and when I try to build the standard library, the compiler emits an error that the Functor module is unbound upon reaching the applicative.mli even though I already updated the .depend file. When I introduced syntax errors into functor.mli and applicative.mli, the compiler only reported the error in functor.mli, suggesting that the Functor module is compiled before the Applicative module.

I have tried:

./configure
make depend
make world.opt

and:

./configure
cd stdlib
make depend
make all

Should I commit and push to origin before the build works so the people who are willing to help me troubleshoot can do so?

Thank you!

Okay, after some more troubleshooting, I found out something that may be important.

When I run make functor.cmi, the Applicative module builds, but when I run make stdlib__functor.cmi, it does not. Alternatively, if I refer to Stdlib__functor instead of Functor in applicative.mli and applicative.ml, the Applicative module builds. I see other standard library modules refer to each other without the Stdlib__ prefix, so what’s wrong with my build?

I would like to note that I have added the appropriate names to stdlib/Makefile stdlib/StdlibModules.

Update: I fixed the problem: I didn’t add my new modules to the Stdlib module. IIRC this is a new change to the standard library organization for release 4.07.

However, there is a new problem: stdlib__sys.cmi doesn’t seem to be built when I run make all, leading to compile errors.

Update: the stdlib__sys.cm_ listings don’t appear in .depend… could this be because sys.ml is generated? Also, when I run make depend in the stdlib directory, ../tools/ocamldep doesn’t exist…

Update: I recloned the repository. Now, when I run make world.opt, the error is Required module Stdlib__functor is unavailable in file _none_, the toplevel?

I would try first to build the compiler distribution without any patches, directly from trunk or 4.07. Then, you have the tooling in place, you can checkout your branch and try building there as well. As you noticed, you now need to add an alias in Stdlib (and your file names should be . Because the dependencies are not correct yet (the .depend files do not talk about your modules), you may need to build your module by hand, manually, by asking for make stdlib__foo.cmi in the right dependency order.

Once all the new .cmi are built, building the .cmo should work fine, and from there you can have make world working (this doesn’t build the native compiler and related tools), you can do make depend and you should be good to go.

1 Like

@gasche

Thank you so much for helping me.

I don’t know what broke with the Sys module, but it isn’t a problem after I recloned the repo. Right now, the standard library successfully builds when I run make all and all of my modules have .cmi, .cmo, .cmti, and .cmt files in the directory.

However, when I run make world.opt in the repo root, the build fails because the module Stdlib__functor is unavailable.

I am basing my changes off of c-cube’s Seq commits. Has the process for adding modules changed in the meantime?

Thanks for your time and effort.

What is the precise error? Does make world build? Did you rebuild all dependencies with make alldepends? Did you add the functor cmo to the stdlib Makefile?

1 Like

Thank you @octachron.

make world does not build either, and when I try to run make alldepends, make says that alldepends is not a target. I have done make depend.

I have edited the files stdlib/Makefile, otherlibs/thread/Makefile, and stdlib/StdlibModules to add the appropriate names. Additionally, I ran make depend for ocamldoc, and as a result the .depend file is different even though the differences seem irrelevant to my changes, and when I ran make depend for ocamldoc/stdlib_non_prefixed, the entire .depend file was deleted.

EDIT: Here is the relevant output for make world.opt:

make ocaml
make[2]: Entering directory '/home/REDACTED/ocaml'
boot/ocamlrun boot/ocamlc -g -nostdlib -I boot -use-prims runtime/primitives  -linkall -o ocaml.tmp compilerlibs/ocamlcommon.cma compilerlibs/ocamlbytecomp.cma compilerlibs/ocamltoplevel.cma toplevel/topstart.cmo
File "_none_", line 1:
Error: Required module `Stdlib__functor' is unavailable
Makefile:828: recipe for target 'ocaml.tmp' failed
make[2]: *** [ocaml.tmp] Error 2
make[2]: Leaving directory '/home/REDACTED/ocaml'
Makefile:448: recipe for target 'opt.opt' failed
make[1]: *** [opt.opt] Error 2
make[1]: Leaving directory '/home/REDACTED/ocaml'
Makefile:503: recipe for target 'world.opt' failed
make: *** [world.opt] Error 2

Here is the relevant output for make world:

make ocaml
make[2]: Entering directory '/home/REDACTED/ocaml'
boot/ocamlrun boot/ocamlc -g -nostdlib -I boot -use-prims runtime/primitives  -linkall -o ocaml.tmp compilerlibs/ocamlcommon.cma compilerlibs/ocamlbytecomp.cma compilerlibs/ocamltoplevel.cma toplevel/topstart.cmo
File "_none_", line 1:
Error: Required module `Stdlib__functor' is unavailable
Makefile:828: recipe for target 'ocaml.tmp' failed
make[2]: *** [ocaml.tmp] Error 2
make[2]: Leaving directory '/home/REDACTED/ocaml'
Makefile:484: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/home/REDACTED/ocaml'
Makefile:498: recipe for target 'world' failed
make: *** [world] Error 2

Update: I cloned the repo again so that I can add a simple module and determine what I need to do to make the compiler build. I discovered that even though otherlibs/threads/stdlib.mli is a link to stdlib/stdlib.mli, otherlibs/threads/stdlib.ml isn’t a link to the corresponding .ml file? I added the modules to the stdlib in the threads library, but even though my minimal test repo builds, my main one with my functor/applicative/monad changes still doesn’t, with the same error.

Update: I realized that alldepends isn’t a target, but alldepend is and I ran it. I still have the same error.

I realized that I forgot to remove a reference to Stdlib__functor in applicative.ml from when I was troubleshooting, and I think that leaving it may have messed up the build and caused the errors. However, I’m not sure.

I recloned OCaml and moved my changes over. I read @gasche’s advice, but found that in order to get the libraries to build, I actually needed to do make name.cmi and make name.cmx, as opposed to make stdlib__name.cmi. Now, I got the standard library compiled again.

Now, when I run make world.opt, there is an error that required module Applicative is unavailable when the .cmo files of ocaml/ocamldoc, and when I ran make clean in its directory, ocaml/debugger before it, are linked. I assume that the same error would occur for directories that have not been reached yet. I noticed that the standard library is linked via -I ../stdlib in the compile command; is Applicative supposed to be defined by searching that directory?

:confused:

Should I post the git diff or my updated files somewhere?

Update: I realized that I may have forgotten to update otherlibs/threads/Makefile when I transferred my changes, but when I went to check, I couldn’t find my ocaml directory - I checked my bash history and I didn’t delete it, so I’m a little confused about what I messed up. Luckily, my changes are based on a personal utility library, so all I lost are the boilerplate changes (e.g. adding to stdlib.ml(i)). Perhaps it’s better for me to start from scratch with my new knowledge anyway. I will redo my changes and inform you of the result.

I you commit your changes (even partially broken) and push it to a personal clone of the OCaml repository, we could clone it and have a look.

Your pain now could be turned into valuable experience for others by writing down the steps that you needed to add new stdlib modules in a stdlib/HACKING.adoc file – you can look at the others HACKING.adoc files in the repository for an overview of the general style.

You might also want to have look to the PR for adding the Float module .

Thanks! I noticed that $(LIB)/$(P)float.cmo wasn’t added to otherlibs/threads/Makefile… :confused:

@gasche Thank you; here is my commit: https://github.com/TheAspiringHacker/ocaml/commit/3fa28725662e0d127303bacda8a31028ff0b7a8c

I figured that I would have better luck if I added a single module, then recompiled OCaml. I made a new branch and added Functor, and it compiles! I’m writing a test case to ensure that Functor is accessible.

Update: A test failed, but it didn’t seem to be mine…

Update: I ran make one DIR=tests/lib-functor in the testsuite directory and it passed.

Update: All tests passed on branch trunk, so I must have broken something. :confused: I’m going to investigate the test.

Update: After a make clean and a rebuild, the tests pass. shrugs

Update: When I tried to add the Applicative module, I got a compile error about not finding Functor, even though I had already added it to the standard library. I’m investigating the problem.

Update: After a make alldepend and make clean, I got OCaml compiling again.

Thank you @gasche and @octachron for your help. When I rebuilt the compiler after adding each module, I didn’t have any major build issues. I have now made a pull request: https://github.com/ocaml/ocaml/pull/1920.

I will also make a pull request improving the hacking documentation.