Skip to main content

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-target

Sample 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:4

This 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-targets

For 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-macosx

For 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-accelerators
Supported 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 CUDA

How 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-macosx

The 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.

FlagPurpose
--target-triplePlatform (arch + vendor + OS)
--target-cpuSpecific processor model
--target-featuresIndividual feature toggles
--target-acceleratorGPU or accelerator architecture

For example:

mojo build --target-triple aarch64-unknown-linux-gnu \
           --target-cpu cortex-a72 \
           --emit object -o myapp.o myapp.mojo

Use --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.mojo

GCC/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.

FlagPurpose
--marchArchitecture or CPU subtype to generate code for
--mcpuCPU model (sets architecture and tuning)
--mtuneOptimization 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.mojo

Error:

error: --target-cpu cannot be used with --march or --mcpu;
use either --target-cpu/--target-features or --march/--mcpu/--mtune

Pick one family and use it consistently. Both produce the same result for the same hardware.

Shared flags

Two flags work with both families:

  • --target-triple is always valid and is typically required for cross-compilation, regardless of which family you use.
  • --target-accelerator is 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.mojo

For 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 MI300X

When 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.mojo

This 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.mojo

This 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.mojo

This generates code for the Haswell instruction set and optimizes it for Skylake.

GPU kernel compilation

mojo build --target-accelerator=nvidia:sm_90 myapp.mojo

This 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.

ValueOutputStatus
exe (default)Executable binaryNative
shared-libShared (dynamic) libraryNative
objectObject file (experimental)Both
llvmUnoptimized LLVM IRBoth
llvm-bitcodeUnoptimized LLVM IR bitcodeBoth
asmAssembly (+ 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?