Link in “custom runtime” mode. In the default linking mode, the linker produces bytecode that is intended to be executed with the shared runtime system, ocamlrun. In the custom runtime mode, the linker produces an output file that contains both the runtime system and the bytecode for the program. The resulting file is larger, but it can be executed directly, even if the ocamlrun command is not installed. Moreover, the “custom runtime” mode enables static linking of OCaml code with user-defined C functions, as described in chapter 22. Unix: Never use the strip command on executables produced by ocamlc -custom, this would remove the bytecode part of the executable. Unix: Security warning: never set the “setuid” or “setgid” bits on executables produced by ocamlc -custom, this would make them vulnerable to attacks.
Linking OCaml binaries Last updated Feb 11, 2025
Linking is the most complex build action. Not only can the linker
produce either native or bytecode executables, it can also emit C
object files that can then be linked to and called by C programs.
Furthermore, for bytecode linking, it can embed the vm interpreter
(ocamlrun
) in the emitted bytecode executable; alternatively, it can
build a customized version of the interpreter containing the foreign
libraries needed by the application code. In all cases, the user can
choose from among standard, debug, and instrumented system runtimes,
and where foreign libraries are involved, can choose between static
and dynamic linking.
Invoking the compiler (ocamlc
, ocamlopt
) without -c
or -a
tells it to produce an executable (unless you also pass -output-obj
or -output-complete-obj
; see below).
Common options
-
-runtime-variant
: Use one of three system runtimes (standard, debug, instrumented). See also 5.3. 25 Building with the instrumented runtime. -
-noautolink
. "When linking .cma/.cmxa libraries, ignore -cclib and -ccopt options potentially contained in the libraries (if these options were given when building the libraries)." -
-output-obj
. "Cause the linker to produce a C object file instead of a native/bytecode executable file." -
-output-complete-obj
. "Same as -output-obj option except the object file produced includes the runtime and autolink libraries." -
-linkall?
Native binaries
What to build
executable
This is the default. “The output of the linking phase is a regular Unix or Windows executable file. It does not need ocamlrun to run.”
-
-nodynlink
“Allow the compiler to use some optimizations that are valid only for code that is statically linked to produce a non-relocatable executable. The generated code cannot be linked to produce a shared library nor a position-independent executable (PIE). Many operating systems produce PIEs by default, causing errors when linking code compiled with -nodynlink. Either do not use-nodynlink
or pass the option-ccopt -no-pie
at link-time.” (5.3.16 (ocamlopt))
C object
-
-output-obj
. “Cause the linker to produce a C object file instead of a native/bytecode executable file.” -
-output-complete-obj
. “Same as -output-obj option except the object file produced includes the runtime and autolink libraries.”
Bytecode binaries
What to build
executable
This is the default. “The output of the linking phase is a file
containing compiled bytecode that can be executed by the OCaml
bytecode interpreter: the command named ocamlrun
.”
-
default: “[T]he linker produces bytecode that is intended to be executed with the shared runtime system,
ocamlrun
.” If the application code depends on foreign (C/C++) libraries, the linker will record their names in the bytecode executable, andocamlrun
will dynamically load and link them when the program is launched. For more information, see 5.3.15.3 Dynamic loading of shared libraries. -
-custom
. “[T]he linker produces an output file that contains both the runtime system and the bytecode for the program.” That is, effectively embedsocamlrun
in the output, which can be executed directly. If the application code depends on foreign (C/C++) libraries, the linker will statically link them into the executable.See 5.3.22.1.3 Statically linking C code with OCaml code for more information.
-
-use-runtime
. “Generate a bytecode executable file that can be executed on the custom runtime system runtime-name, built earlier with ocamlc -make-runtime runtime-name.” For more information see 5.3.22.1.6 Building standalone custom runtime systems -
-output-complete-exe
. “Build a self-contained executable by linking a C object file containing the bytecode program, the OCaml runtime system and any other static C code given to ocamlc. The resulting effect is similar to -custom, except that the bytecode is embedded in the C code so it is no longer accessible to tools such as ocamldebug. On the other hand, the resulting binary is resistant to strip.”
C object
-
-output-obj
. “Cause the linker to produce a C object file instead of a native/bytecode executable file.” -
-output-complete-obj
. “Same as -output-obj option except the object file produced includes the runtime and autolink libraries.”
Foreign library linkage
“Foreign library” means a static (.a ) or shared (.so , .dll on Windows) library, whether produced from C/C++ code or some other language, e.g. Rust.
|
There are three ways to tell the linker about foreign libraries:
-
Static libraries:
-
Native binaries: pass directly on the command line (e.g.
libfoo.a
); -
Bytecode binaries (
-custom
mode):-
pass directly on the command line;
-
pass using
-cclib -lname
-
If the library is not located in one of the standard library directories, also pass
-ccopt -Ldir
-
-
-
-
Shared libraries:
-
Native binaries: pass on command line (e.g.
libfoo.so
) -
Bytecode binaries: (default mode)
-
pass directly on command line
-
“a library named
dllname.so
(respectively,.dll
) residing in one of the standard library directories can also be specified as-dllib -lname
.” -
-dllpath dir
may be used to add a directorydir
to the run-time search path for shared C libraries. “The-dllpath
option simply storesdir
in the produced executable file, where ocamlrun can find it and use it as described in section 15.3.” -
Question: can we pass shared libs in
-custom
mode?
-
-
Manual:
For bytecode executables that depend on foreign libraries:
-
use static archives or dynamic shared objects (
-cclib
,-dllib
, etc.) -
use a standard, custom (
-custom
), or user-define application runtime (-use-runtime
)
We have two cc link options:
-
dynamic. The default; means dynamic load & link, not just linking a shared lib.
-
static. build-time loading of static (.a) lib. (Or shared lib?) Enabled by
-custom
flag.
I.e. dynamic means run-time linkage; static means build-time linkage.
Scenarios:
-
case: no cclib deps
-
case: static (.a) cclib deps
-
subcase: link dynamic
-
subcase: link static
-
-
case: shared (.so) cclib deps
-
subcase: link dynamic
-
subcase: link static
-
-
case: both static and shared cclib deps
-
subcase: link dynamic
-
subcase: link static
-
See Manual, Chapter 13 Batch Compilation
Build-time static linkage
CLI Options
-
-cclib -llibname
Pass the
-llibname
option to the C linker when linking in “custom runtime” mode (see the -custom option). This causes the given C library to be linked with the program at build-time.The library can be either an archive ( .a
) or a shared lib (.so
) (?) -
-ccopt option
Pass the given option to the C compiler and linker. When linking in “custom runtime” mode, for instance
-ccopt -Ldir
causes the C linker to search for C libraries in directorydir
. (See the-custom
option.) -
-cc ccomp
Use ccomp as the C linker when linking in “custom runtime” mode (see the
-custom
option) and as the C compiler for compiling.c
source files. When linking object files produced by a C++ compiler (such as g++ or clang++), it is recommended to use-cc c++
.OBazl never uses the OCaml compiler to compile C/C++ code, so this option is not relevant for OBazl users.
Load-time shared-object linkage
No special requirements, just pass the .so
file on the command line,
just as for .a
files.
Run-time load & link (dlopen)
For bytecode executables:
CLI Options
-
-dllib -llibname
Arrange for the C shared library
dlllibname.so
(dlllibname.dll
under Windows) to be loaded dynamically by the run-time system ocamlrun at program start-up time. -
-dllpath dir
Adds the directory
dir
to the run-time search path for shared C libraries. At link-time, shared libraries are searched in the standard search path (the one corresponding to the -I option). The-dllpath
option simply stores dir in the produced executable file, where ocamlrun can find it and use it as described in section 15.3.