# Understanding `zig build-exe`

### Understanding `zig build-exe`

In the previous section, we used this command:

```bash
zig run hello.zig
```

That command compiles your Zig file and runs it immediately.

Now we will look at a different command:

```bash
zig build-exe hello.zig
```

This command compiles your Zig file and creates an executable file.

An executable file is a program you can run directly from your operating system.

#### Source File and Executable File

Start with this file:

```text
hello.zig
```

Inside it, write:

```zig
const std = @import("std");

pub fn main() void {
    std.debug.print("Hello, executable!\n", .{});
}
```

Now run:

```bash
zig build-exe hello.zig
```

Zig reads `hello.zig`, checks the code, compiles it, links it, and creates an executable.

On Linux and macOS, the result is usually:

```text
hello
```

You run it with:

```bash
./hello
```

On Windows, the result is usually:

```text
hello.exe
```

You run it with:

```powershell
.\hello.exe
```

The source file is the text you write.

The executable file is the program Zig creates.

#### What `build-exe` Means

The command has two parts:

```bash
zig build-exe hello.zig
```

The first part is:

```text
zig
```

This runs the Zig tool.

The second part is:

```text
build-exe
```

This tells Zig what kind of output you want.

The third part is:

```text
hello.zig
```

This is the input file.

So the command means:

```text
Use Zig to build an executable from hello.zig.
```

#### Compile and Link

When you run `zig build-exe`, Zig does more than one thing.

First, it compiles your Zig code. Compilation checks the source code and turns it into lower-level machine instructions.

Second, it links the program. Linking connects your code with the pieces it needs from libraries and the operating system.

For a small program, this feels like one step. Internally, it has several stages.

You do not need to understand every stage yet. For now, remember this:

```text
Source code goes in.
Executable program comes out.
```

#### `zig run` vs `zig build-exe`

Both commands compile code, but they are used for different situations.

| Command | What it does | When to use it |
|---|---|---|
| `zig run hello.zig` | Compile and run immediately | Quick experiments |
| `zig build-exe hello.zig` | Compile and save executable | Creating a program file |

When learning, `zig run` is convenient.

When you want a real output file, use `zig build-exe`.

#### Running the Executable

After building, you run the executable directly.

On Linux and macOS:

```bash
./hello
```

The `./` means “run the file named `hello` in the current directory.”

This is needed because most Unix-like shells do not automatically search the current directory for programs.

On Windows PowerShell:

```powershell
.\hello.exe
```

The `.\` means the same idea: run the file in the current directory.

#### Choosing an Output Name

By default, Zig uses the source file name.

If the input is:

```text
hello.zig
```

the output is usually:

```text
hello
```

or:

```text
hello.exe
```

You can choose a different output name with `-femit-bin`.

```bash
zig build-exe hello.zig -femit-bin=myprogram
```

Now the output is named:

```text
myprogram
```

On Windows, you may choose:

```powershell
zig build-exe hello.zig -femit-bin=myprogram.exe
```

This is useful when the file name and program name should be different.

#### Build Modes

Zig can build the same program in different modes.

A build mode controls safety checks, optimization, and debugging information.

The most common modes are:

| Mode | Purpose |
|---|---|
| `Debug` | Best for development and learning |
| `ReleaseSafe` | Optimized, but keeps many safety checks |
| `ReleaseFast` | Optimized for speed |
| `ReleaseSmall` | Optimized for small binary size |

By default, Zig builds in debug mode.

Debug mode is best while learning because it keeps helpful checks and better debugging information.

To build in release-fast mode:

```bash
zig build-exe hello.zig -O ReleaseFast
```

To build in release-safe mode:

```bash
zig build-exe hello.zig -O ReleaseSafe
```

To build in release-small mode:

```bash
zig build-exe hello.zig -O ReleaseSmall
```

For now, use the default mode unless you have a reason to change it.

#### What Debug Mode Gives You

Debug mode is slower than release mode, but it is better for learning.

It helps catch mistakes such as:

| Mistake | Example |
|---|---|
| Integer overflow | A number becomes too large for its type |
| Invalid array access | Code reads outside an array |
| Reaching impossible code | Code reaches `unreachable` |
| Better stack traces | Error messages are easier to inspect |

Speed matters later. Correctness matters first.

Use debug builds while writing and testing code.

#### A Simple Error Example

Try this program:

```zig
const std = @import("std");

pub fn main() void {
    const items = [_]u8{ 1, 2, 3 };
    std.debug.print("{}\n", .{items[10]});
}
```

Build and run it:

```bash
zig build-exe hello.zig
./hello
```

The array has only three elements, but the program tries to access index `10`.

In debug mode, Zig can catch this kind of error instead of silently continuing with invalid memory.

This is one reason debug builds are useful.

#### Cross Compilation Preview

One powerful feature of `zig build-exe` is cross compilation.

Cross compilation means building a program for a different platform.

For example, on one machine you can ask Zig to build for Linux:

```bash
zig build-exe hello.zig -target x86_64-linux
```

Or for Windows:

```bash
zig build-exe hello.zig -target x86_64-windows
```

Or for macOS on Apple Silicon:

```bash
zig build-exe hello.zig -target aarch64-macos
```

You do not need to master this now. The important idea is that Zig treats cross compilation as a normal compiler feature, not an advanced trick.

#### Common Beginner Problems

If you run:

```bash
zig build-exe hello.zig
```

and see an error like:

```text
error: file not found
```

make sure your terminal is in the same directory as `hello.zig`.

You can list files in the current directory.

On macOS and Linux:

```bash
ls
```

On Windows PowerShell:

```powershell
dir
```

If you build successfully but cannot run the program, check the file name.

On Linux and macOS, use:

```bash
./hello
```

On Windows, use:

```powershell
.\hello.exe
```

If you type only:

```bash
hello
```

on Linux or macOS, the shell may not find it. Use `./hello`.

#### Mental Model

`zig build-exe` is the direct way to turn one Zig source file into one executable program.

You give Zig a `.zig` file.

Zig gives you a program file.

That is the basic build path:

```text
hello.zig -> compiler -> hello
```

Later, when projects become larger, we will use `zig build` and a `build.zig` file. But `zig build-exe` is the simplest place to start because it shows the core idea without extra project structure.

