|
| 1 | +--- |
| 2 | +id: "native-target" |
| 3 | +short_title: "Compilation Targets: Native Code" |
| 4 | +title: "Compilation Targets: Native Code" |
| 5 | +description: "Compile OCaml to high-performance native code with ocamlopt. Maximum runtime performance with optimized machine code for production deployments." |
| 6 | +category: "Compilation Targets" |
| 7 | +--- |
| 8 | + |
| 9 | +OCaml can compile to native code, delivering high-performance executables with optimized machine code for production environments. |
| 10 | + |
| 11 | +## What is OCaml Native Code? |
| 12 | + |
| 13 | +OCaml native code is generated by ocamlopt, the high-performance native-code compiler that compiles OCaml source files to native code object files and links them to produce standalone executables. The native code system consists of: |
| 14 | + |
| 15 | +- **ocamlopt** - The native-code compiler (analogous to gcc or clang for C/C++) |
| 16 | +- **Native executables** - Stand-alone executable files that can be invoked directly without depending on the ocamlrun bytecode runtime system |
| 17 | +- **Runtime system** - Integrated directly into each executable, including the garbage collector |
| 18 | + |
| 19 | +Native code produces faster-running programs than bytecode, at the cost of increased compilation time and executable code size. Key characteristics: |
| 20 | + |
| 21 | +- Faster runtime performance than bytecode |
| 22 | +- Stand-alone executables requiring no external runtime |
| 23 | +- Cross-module inlining and optimization |
| 24 | +- Production-ready deployments |
| 25 | + |
| 26 | +## When to Use Native Code |
| 27 | + |
| 28 | +**Use native code** (ocamlopt) when you need faster runtime performance in production, want standalone executables, or are deploying to end users. |
| 29 | + |
| 30 | +**Use bytecode** (ocamlc) for fast iteration during development, CI/testing environments where compilation speed matters, or maximum portability. |
| 31 | + |
| 32 | +The typical OCaml workflow: develop with bytecode for fast compile times, switch to native code for production releases. The same source code compiles to both targets without modification. |
| 33 | + |
| 34 | +## Platform Support |
| 35 | + |
| 36 | +The native-code compiler is only available on certain platforms. From OCaml 5.0 onwards, native compilation is available only on 64-bit systems. |
| 37 | + |
| 38 | +### Supported Platforms (OCaml 5.x) |
| 39 | + |
| 40 | +- **x86-64 (AMD64)** - Linux, macOS, Windows |
| 41 | +- **ARM64 (AArch64)** - Linux, macOS (including Apple Silicon) |
| 42 | +- **RISC-V** - Linux |
| 43 | +- **IBM Z (s390x)** - Linux (OCaml 5.1+) |
| 44 | + |
| 45 | +Native compilation on 32-bit systems is no longer available, nor are there plans to bring it back. |
| 46 | + |
| 47 | +**Windows specifics:** Native compilation is supported via MSVC, MinGW, or Cygwin toolchains. See [OCaml on Windows](https://ocaml.org/docs/ocaml-on-windows) for setup details. |
| 48 | + |
| 49 | +If your target platform lacks native code support, the bytecode compiler provides a highly portable fallback. |
| 50 | + |
| 51 | +## Getting Started |
| 52 | + |
| 53 | +To compile OCaml programs to native code, use the ocamlopt compiler. For single files, specify the source file and output executable name. For projects with multiple modules, list them in dependency order. When using libraries, specify both the library archive and your source files. |
| 54 | + |
| 55 | +In practice, most developers use build systems like [Dune](https://dune.build/) rather than invoking ocamlopt directly. Dune handles compilation, dependency management, and build orchestration. |
| 56 | + |
| 57 | +For comprehensive compiler details, see the [OCaml Manual: Native-code Compilation (ocamlopt)](https://ocaml.org/manual/latest/native.html). For practical build workflows, see [Using the OCaml Compiler Toolchain](https://ocaml.org/docs/using-the-ocaml-compiler-toolchain). |
| 58 | + |
| 59 | +## Compilation Model & File Extensions |
| 60 | + |
| 61 | +OCaml's compilation model separates interface and implementation: |
| 62 | + |
| 63 | +- **.ml** - Module implementation (source) |
| 64 | +- **.mli** - Module interface/signature (source) |
| 65 | +- **.cmi** - Compiled interface (used by both bytecode and native) |
| 66 | +- **.cmx** - Compiled native object with cross-module optimization metadata |
| 67 | +- **.o** / **.obj** - Native machine code object file |
| 68 | +- **.cmxa** - Native library archive (collection of .cmx files) |
| 69 | +- **.a** / **.lib** - Native static library (collection of .o files) |
| 70 | + |
| 71 | +The .cmx files contain information for cross-module inlining and optimization. Unlike bytecode, these optimization metadata files must be available at link time for best performance. |
| 72 | + |
| 73 | +## Compatibility with Bytecode |
| 74 | + |
| 75 | +Compatibility with the bytecode compiler is extremely high: the same source code should run identically when compiled with ocamlc and ocamlopt. |
| 76 | + |
| 77 | +Key constraints: |
| 78 | + |
| 79 | +- It is not possible to mix native-code object files produced by ocamlopt with bytecode object files produced by ocamlc: a program must be compiled entirely with ocamlopt or entirely with ocamlc. |
| 80 | +- Native-code object files produced by ocamlopt cannot be loaded in the toplevel system. |
| 81 | + |
| 82 | +This binary compatibility means you can develop and test with bytecode for fast iteration, then deploy with native code for performance, using the same source code for both compilation targets. |
| 83 | + |
| 84 | +## Debugging and Profiling |
| 85 | + |
| 86 | +Native executables integrate with standard system tools: |
| 87 | + |
| 88 | +**Debugging:** |
| 89 | +- Compile with -g flag for debug symbols |
| 90 | +- Produces stack backtraces when the program terminates on an uncaught exception |
| 91 | +- Use gdb, lldb, or other native debuggers |
| 92 | +- OCaml and C frames appear in the same stack trace |
| 93 | + |
| 94 | +**Profiling:** |
| 95 | +- Use perf (Linux), Instruments (macOS), or similar native profilers |
| 96 | +- Compile with -g for accurate symbol resolution |
| 97 | +- gprof support via -p flag |
| 98 | + |
| 99 | +The native compiler maintains C calling conventions, making OCaml code visible to standard profiling and debugging tools. |
| 100 | + |
| 101 | +## Dynamic Loading |
| 102 | + |
| 103 | +The -shared option builds plugins (usually .cmxs files) that can be dynamically loaded with the Dynlink module. This provides a plugin system similar to shared libraries and DLLs, allowing runtime loading of OCaml code. Platform support varies—consult the manual for specifics. |
| 104 | + |
| 105 | +## Learn More |
| 106 | + |
| 107 | +- [OCaml Manual: Native-code Compilation](https://ocaml.org/manual/latest/native.html) - Complete ocamlopt reference |
| 108 | +- [Using the OCaml Compiler Toolchain](https://ocaml.org/docs/using-the-ocaml-compiler-toolchain) - Practical compilation guide |
| 109 | +- [The Compiler Backend: Bytecode and Native code](https://ocaml.org/docs/compiler-backend) - Deep dive: lambda form, optimization, assembly output |
0 commit comments