Compilation targets
Mojo compiles code for a range of targets, from your local machine to other CPUs, operating systems, and GPUs. You can inspect what the compiler supports, choose a target configuration, and generate code for that target.
Compilation targets describe where and how your program runs. They define the platform, CPU, features, and optional accelerators used during code generation, for both native and cross-compilation workflows, including GPU-enabled (heterogeneous builds).
The Mojo command line compiler lets you inspect your current platform, select a target configuration, and generate code for that target. Use it to build for your own system or target other CPUs, operating systems, and accelerators.
Query your system and available targets
Before setting compilation or cross-compilation flags, check which targets the compiler supports and what it detects on your system. These commands list available targets and show how the compiler configures your current machine.
Use these commands to understand and choose the components of a target, including the target triple (architecture, vendor, OS), CPU, features, and accelerators.
Effective target
The effective target is the configuration the compiler uses for your current system when you don't set target flags.
Print the full target configuration for your system:
mojo build --print-effective-targetSample output on an Apple M4 MacBook Pro. The features are truncated in this example to save space:
Effective target configuration:
--target-triple arm64-apple-darwin25.3.0
--target-cpu apple-m4
--target-features +aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,...
--target-accelerator metal:4This output shows the flags that reproduce your host configuration. Use it to see what the compiler assumes when you don't set target flags.
Supported targets
List the target architectures the compiler can generate code for. Use this command to see which architectures are available before selecting a target or composing a target triple.
mojo build --print-supported-targetsFor example:
Registered Targets:
arm64 - ARM64 (little endian)
arm64_32 - ARM64 (little endian ILP32)
aarch64 - AArch64 (little endian)
aarch64_32 - AArch64 (little endian ILP32)
aarch64_be - AArch64 (big endian)
r600 - AMD GPUs HD2XXX-HD6XXX
amdgcn - AMD GCN GPUs
hexagon - Hexagon
...Supported target CPUs
List valid CPU names for a given target triple. Set --target-triple
to select the target triple and narrow the results.
mojo build --print-supported-cpus \
--target-triple=aarch64-apple-macosxFor example:
Available CPUs for target aarch64-apple-macosx:
a64fx
ampere1
apple-a10
apple-a11
apple-m1
apple-m4
...Supported accelerators
List the GPU and accelerator architectures the compiler can target.
mojo build --print-supported-acceleratorsSupported GPU and Accelerator Architectures:
NVIDIA (CUDA):
sm_52 - Maxwell (GTX 970)
sm_60 - Pascal (Tesla P100)
sm_90 - Hopper (H100)
...
AMD (ROCm/HIP):
gfx942 - CDNA3 (MI300X)
mi300x - (alias) -> gfx942
...
Apple Silicon GPU:
apple-m1 - Apple M1
apple-m2 - Apple M2
...
Other:
cuda - Generic CUDAHow Mojo describes a build target
When the compiler generates machine code, it needs a few key details about the hardware it targets:
- The architecture defines the base instruction set, such as x86-64 or AArch64.
- The CPU model adds processor-specific behavior and may enable instructions beyond the base.
- The feature set controls individual hardware capabilities that can be enabled or disabled, such as AVX-512 or Neon.
For GPU and accelerator targets, one more detail applies:
- The accelerator architecture identifies the GPU or other accelerator to generate device code for.
If you don't set these explicitly, the compiler uses your host system.
Target triples
A target triple identifies the platform you're compiling for. It lists the architecture, vendor, and operating system in a single value:
x86_64-unknown-linux-gnu
aarch64-apple-macosxThe triple sets the overall execution environment and binary conventions. It's the starting point for cross-compilation and works with both flag sets described in the next section.
Two ways to set your target
Mojo provides two sets of flags to specify target hardware. They reach the same result through different interfaces, and you can't mix them in one command. These are Mojo target flags and GCC/Clang-compatible flags.
Mojo target flags
These flags let you set the triple, CPU, and features directly.
| Flag | Purpose |
|---|---|
--target-triple | Platform (arch + vendor + OS) |
--target-cpu | Specific processor model |
--target-features | Individual feature toggles |
--target-accelerator | GPU or accelerator architecture |
For example:
mojo build --target-triple aarch64-unknown-linux-gnu \
--target-cpu cortex-a72 \
--emit object -o myapp.o myapp.mojoUse --target-features to enable or disable individual hardware
extensions.
mojo build --target-triple x86_64-unknown-linux-gnu \
--target-cpu x86-64-v3 \
--target-features "+avx512f" \
--emit object -o myapp.o myapp.mojoGCC/Clang-compatible flags
Mojo supports the same --march, --mcpu, and --mtune flags used
in GCC and Clang. These flags follow the behavior documented in the
GCC manual and work as they do in clang.
| Flag | Purpose |
|---|---|
--march | Architecture or CPU subtype to generate code for |
--mcpu | CPU model (sets architecture and tuning) |
--mtune | Optimization hint for a specific processor |
For example:
mojo build --target-triple x86_64-unknown-linux-gnu \
--mcpu=haswell \
--emit object -o myapp.o myapp.mojo--march controls which instructions the compiler can use. Code
compiled with --march=skylake-avx512 can use AVX-512 instructions,
but it won't run on hardware that lacks them.
--mcpu sets both the architecture and tuning from a single CPU
name.
--mtune guides optimization without changing which instructions
the compiler uses. It tells the compiler to prefer instruction
sequences that run faster on the given processor. The code still runs
correctly on other processors with the same instruction support.
The --march flag supports extension syntax for adding features
inline:
mojo build --target-triple x86_64-unknown-linux-gnu \
--march=x86-64-v3+avx512f \
--emit asm -o myapp.s myapp.mojo⚠️ Don't mix the two families
The Mojo compiler enforces a clear separation between these flag
families. Using --target-cpu or --target-features with --march
or --mcpu in the same command produces an error:
# This fails:
mojo build --target-cpu=haswell --mcpu=skylake myapp.mojoError:
error: --target-cpu cannot be used with --march or --mcpu;
use either --target-cpu/--target-features or --march/--mcpu/--mtunePick one family and use it consistently. Both produce the same result for the same hardware.
Shared flags
Two flags work with both families:
--target-tripleis always valid and is typically required for cross-compilation, regardless of which family you use.--target-acceleratoris always valid and is used to target GPUs with either family.
GPU and accelerator targets
Mojo supports heterogeneous builds that generate host code for the
CPU and device code for a GPU in a single build. Use
--target-accelerator to specify the GPU architecture:
mojo build --target-accelerator=sm_90 myapp.mojoFor NVIDIA and AMD targets, use a prefix to select the platform:
mojo build --target-accelerator=nvidia:sm_90 myapp.mojo # NVIDIA H100
mojo build --target-accelerator=amdgpu:gfx942 myapp.mojo # AMD MI300XWhen you use --emit asm with a GPU target, the compiler produces a
separate file for each kernel alongside the host assembly: .ptx for
NVIDIA, .amdgcn for AMD, and .ll for Metal.
Cross-compilation in practice
Generate an object file for another platform
mojo build --target-triple aarch64-unknown-linux-gnu \
--target-cpu cortex-a72 \
--emit object -o myapp.o myapp.mojoThis produces an object file for the target platform. Link it with a toolchain for that platform.
Generate assembly for inspection or external toolchains
mojo build --target-triple x86_64-unknown-linux-gnu \
--emit asm -o myapp.s myapp.mojoThis produces assembly for the target platform. Use it for inspection or pass it to an external toolchain for further processing.
Target a specific CPU with tuning
mojo build --target-triple x86_64-unknown-linux-gnu \
--march=x86-64 --mcpu=haswell --mtune=skylake \
--emit object -o myapp.o myapp.mojoThis generates code for the Haswell instruction set and optimizes it for Skylake.
GPU kernel compilation
mojo build --target-accelerator=nvidia:sm_90 myapp.mojoThis compiles GPU kernels for the specified accelerator and includes them with the host build.
Emit options
The --emit flag controls the output mojo build produces. These
options are essential for cross-compilation because you can't yet
produce linked executables with the Mojo compiler.
| Value | Output | Status |
|---|---|---|
exe (default) | Executable binary | Native |
shared-lib | Shared (dynamic) library | Native |
object | Object file (experimental) | Both |
llvm | Unoptimized LLVM IR | Both |
llvm-bitcode | Unoptimized LLVM IR bitcode | Both |
asm | Assembly (+ GPU sidecars) | Both |
What's working
Outputs that don't require linking work with any supported target:
--emit object— produces a relocatable object file for the target--emit asm— produces assembly for the target--emit llvm— produces LLVM IR configured for the target--emit llvm-bitcode— produces LLVM bitcode for the target
Outputs that require linking need a linker for the target platform, which Mojo doesn't provide and aren't working:
--emit exe— fails at the link step when cross-compiling--emit shared-lib— fails at the link step when cross-compiling
To produce a cross-compiled executable or shared library, generate an object file and link it with a toolchain for your target platform.
Was this page helpful?
Thank you! We'll create more content like this.
Thank you for helping us improve!