(library (name flan) (libraries unix) ; -linkall because lib/macro.ml installs itself into Parse.expander at module ; initialisation and nothing references it. Without it the linker drops the ; module from every executable that does not name it -- bin/main.exe among ; them -- and a program calling a macro would fail with an unknown name ; instead of expanding. The alternative was an install call at every entry ; point, including ones in files this cannot reach. (library_flags (-linkall)) ; Running a macro means dlopening it into the compiler, and OCaml has no ; dlopen for ELF -- Dynlink loads OCaml. These are the stubs for it, and the ; only C the compiler itself is built from. See lib/dynload_stubs.c. (foreign_stubs (language c) (names dynload_stubs)) ; No (c_library_flags (-ldl)): since glibc 2.34 dlopen lives in libc itself ; and libdl is a stub, and naming it breaks the merged build -- the partial ; link -output-complete-obj performs cannot resolve -ldl, so `flan dev` in ; one process fails at the link with "cannot find -ldl" while the ordinary ; build is unaffected. Add it back only with a platform guard. ) ; The host shim is Flan's, not the user's, so the compiler carries it rather ; than looking for it in an install directory. Generated from the real .c files ; so there is only ever one copy to edit. flan_dev.c goes into a dev build ; only — it is the run-time name lookup a REPL needs and a release build has ; no use for. ; [dyn_source] is runtime/flan_dyn_stub.c with runtime/flan_dyn.h pasted in ; front of it, because the generated module is one string and the stub includes ; the header by name. THE MERGE REPLACES THE STUB WITH runtime/flan_dyn.c and ; this rule keeps its shape — the header stays the contract both sides are ; diffed against, and concatenating it here is what makes the compiler carry a ; self-contained translation unit the way it already carries flan_rt.c. (rule (target runtime_src.ml) (deps %{workspace_root}/runtime/flan_rt.c %{workspace_root}/runtime/flan_dev.c %{workspace_root}/runtime/flan_dyn.h %{workspace_root}/runtime/flan_dyn_stub.c) (action (with-stdout-to runtime_src.ml (progn (echo "let source = {c|\n") (cat %{workspace_root}/runtime/flan_rt.c) (echo "|c}\n\nlet dev_source = {c|\n") (cat %{workspace_root}/runtime/flan_dev.c) (echo "|c}\n\nlet dyn_source = {c|\n") (cat %{workspace_root}/runtime/flan_dyn.h) (cat %{workspace_root}/runtime/flan_dyn_stub.c) (echo "|c}\n")))))