InnocentZero's Treasure Chest

HomeFeedAbout MeList of interesting people

25 Nov 2025

Integrating MMTk in OCaml - 4

Done with exams for now, and back at figuring out this freaky makefile. I wanted to do it manually, but oh well. Seems like I'll use a tool because no way will I read 3000 lines of makefile rules.

So there's this tool called make2graph, which is what I'm using right now. However, dot's taking a buttload of time, and I'm not sure if there's an easy way to do it. Should I change format? I don't know. The tool does support outputs such as XML and PlantUML, but how long will those take? Not sure about that either.

Yeah, no, graphviz took long enough for me to get annoyed. Ffs. I had been sitting here for about half an hour now. I'll just do it manually. Let's go.

The main makefile

First up, we define the root directory variable ROOTDIR.

Next up, we include Makefile.common to include common definitions. That itself includes Makefile.config_if_required.

No surprises so far. It defines the default goal to be defaultentry, so nothing extraordinary there either. I still don't understand what the goal's trying to do though. And truth be told, I'm still slightly confused on how it's working.

Damn, after dwelving deep into the makefile tree, I find out this joke of a rile for stdlib/StdlibModules, which gets things from the runtime built. Wow, just wow.

Anyways, I need to figure out how to finally deal with this now. What the structure is, and such. Also, WHY IS defaultentry NOT BEING USED?

After a bunch of digging and seeing the output of make -p, I've come to the conclusion that ocaml build system fucking sucks. Anyways, the first step in the rules is mkdir .dep/runtime, and DEPDIR is defined in Makefile.common. On using that, I find this macro called COMPILE_C_FILE, which, well, compiles C files. TO be accurate, it expands to the rules that compile the C files, and has an order-only dependency on $(DEPDIR)/runtime.

Now on to where this macro is used. So this is used in a foreach command to write rules to generate xyz bullcrap from the runtime C source files. Basically, long story short, it'll generate object files from the C source files with some intermediate garbage. Someone shoot me already.

Yeah, I can't figure out where it's being used. So I'll just read through the entire makefile and the output of make --debug=why. I don't get paid enough for this shit though, I swear to god.

Why can we not have good things in life? Why? Just why?

Ok, I love make --debug=why. It immediately gave me what I wanted.

Now I just need to read through this.

Makefile targets

All things in monospace are target names here. And only those are the ones in monospace.

Startup (world.opt)

The first target is world.opt. This checks if the platform is supported (using checknative), then does a coldstart and compiles for opt.opt. We'll come to opt.opt later, but it's basically compiling everything for native platform.

coldstart

Coldstart needs boot/ocamlrun and runtime/libcamlrun. The first one is committed to the repo, so we're good. The second one, however… We'll talk about it later.

The first one might also need make bootstrap for updates.

The coldstart itself compiles the stdlib modules while setting the ocaml bytecode compiler to boot/ocamlrun, and then moves the stdlib files to boot/ and also runtime/libcamlrun.

runtime/libcamlrun

Now, back to runtime/libcamlrun. This depends on libcamlrun_OBJECTS, and also the mmtk code that we've added. For now, this only creates the archive of all the object files using ar rc (replace/insert + create if absent).

libcamlrun_OBJECTS

These are the object files that are needed to compile, well, what the heading is. The list is that of all object files with a .b.o suffix and the flags for bytecode. It takes all the runtime_BYTECODE_C_SOURCES and basically uses the rules created by COMPILE_C_MACRO to compile them with the relevant flags.

runtime_BYTECODE_C_SOURCES

This by itself is an array of C files that are the C sources common to both and the and the bytecode-only C sources. There's not much to it, they are basically files that are needed for runtime compilation.

TODO opt.opt

This does some basic stack check, recompiles the core system (coreall) using the new bootstrap compiler, and then

coreall

this makes the core compiler (ocamlc), and some other tools (ocamllex) and targets (ocamltools, library). The second-last target just be compiling a bunch of fizz-buzz tools needed here and there. The final one recompiles stdlib modules in the repo using the new core compiler.

ocamlc

This is generated from a bunch of rules defined in the common makefile's macro system. Basically compiles a lot of stuff here and there and then links it to form ocamlc.

ocamllex

This depends on ocamlyacc, and then calls the lex-all target in the makefile.

ocamlyacc

Basically make a bytecode program out of the modules is the yacc/ subdirectory.

lex-all

This basically creates lex/ocamllex in the same way as ocamlc, by using the macros defined in the common makefile.


Other posts
Creative Commons License
This website by innocentzer0 is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.