Thus, it is obvious that the purpose of different files is (by limiting this to the bytecode compiler):
mylibrary.mli - definition of human readable interface (not required, compiler needs only .cmi)
mylibrary.cmi - the compiled interface needed when compiling the code that calls mylibrary
library.o - object-object C
dlllibrary.so - a shared library object made from .o
dlllibrary.a - a static library object made from .o
mylibrary.cmo - a bytecode object compiled from mylibrary.ml
mylibrary.cma - bytecode library
Then mylibrary.cma (with mylibrary.cmi and dlllibrary.so ) are needed when loading mylibrary from the top level:
#load "mylibrary.cma";;
OR
You can compile a bytecode program that dynamically links to mylibrary.cma ( mylibrary.cmi and dlllibrary.so also needed):
ocamlc mylibrary.cma <program>.ml
OR
dynamic binding to a bytecode object instead of a bytecode library (required files: mylibrary.cmo , mylibrary.cmi , dlllibrary.so ):
ocamlc dlllibrary.so mylibrary.cmo <program>.ml
(Note: then run the bytecode with: ocamlrun -I . <program> , assuming dlllibrary.so is in the current directory.)
OR
static binding to objects (required files: mylibrary.cmo , mylibrary.cmi liblibrary.a )
ocamlc -custom liblibrary.a mylibrary.cmo <program>.ml
OR
static binding to library objects (required files: mylibrary.cma , mylibrary.cmi , liblibrary.a )
ocamlc -custom -I . mylibrary.cma <program>.ml
Thus, depending on how the library will be used in the future, different files are needed. With the exception of .mli it is required only for readers, and the .o object file compiled from the C library is not needed (but in some cases it will be required when compiling into native code).