<!-- Source: https://medius.k4tech.net/bindings/c/build -->
# Build & features

_Linking and the optional surfaces_

Two files: the header [`medius.h`](/bindings/c.md) and the native library [`libmedius_capi`](/bindings/c.md). Point the compiler at both and link. C++ is identical: same header, add `-std=c++17`. For your first program see the [Quickstart](/bindings/c/quickstart.md).

## Feature flags

_Mock and flash, off by default_

Two surfaces are gated. Each is a [cargo feature](https://doc.rust-lang.org/cargo/reference/features.html) on `medius-capi` _and_ a matching [`#ifdef`](https://en.cppreference.com/w/c/preprocessor/conditional) in the header.

| Cargo feature | Header macro | Declares | What it does |
| --- | --- | --- | --- |
| `mock` | `MEDIUS_FEATURE_MOCK` | [`MediusMockBox`](/bindings/c/api.md#mock), the `medius_mock_*` calls, `medius_device_with_mock` / `_open_mock` | A scriptable fake box for tests. See [Mock box](/library/features/mock.md). |
| `flash` | `MEDIUS_FEATURE_FLASH` | [`medius_flash(port, bin_path, host)`](/bindings/c/api.md#module) | Flash firmware with [esptool](https://github.com/espressif/esptool). See [Flash firmware](/library/features/flash.md). |

#### BUILD WITH THE SURFACES, THEN COMPILE AGAINST THEM

```bash
# build the library with both surfaces
cargo build -p medius-capi --release --features mock,flash

# define the matching macros when you compile your program
cc app.c -DMEDIUS_FEATURE_MOCK -DMEDIUS_FEATURE_FLASH \
   -I medius-capi/include -L target/release -lmedius_capi -lpthread -o app
```

> **Warning**
>
> The prebuilt tarball has **neither** surface. Define a macro whose symbols aren't in the library and you get a link error; build the library with a feature but forget the macro and the declarations stay hidden. The two must match.

## Linking & loading

_Header, library, and the flags that find them_

Get the two files from a [release tarball](/bindings/c/build.md#packaging), or build the [crate](https://github.com/K4HVH/medius) yourself with the [Rust toolchain](https://rustup.rs) (`cargo build -p medius-capi --release` writes them under `target/release/`). Then these flags wire them in.

```
  compile  ──▶  needs your code + medius.h
  link     ──▶  adds libmedius_capi
  run      ──▶  loads libmedius_capi
```

| Flag | Points at | Example |
| --- | --- | --- |
| `-I<dir>` | the directory holding `medius.h` | `-I medius-capi/include` |
| `-L<dir>` | the directory holding the library | `-L target/release` |
| `-lmedius_capi` | the library itself (the linker adds the `lib` prefix and extension) | resolves `libmedius_capi.so` |
| [`-lpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) | Linux only; the core spawns reader/keepalive threads | append after `-lmedius_capi` |

#### PER-OS LIBRARY FILENAME

| OS | Shared library | Static library | Note |
| --- | --- | --- | --- |
| Linux | `libmedius_capi.so` | `libmedius_capi.a` | add `-lpthread` |
| macOS | `libmedius_capi.dylib` | `libmedius_capi.a` | none |
| Windows | `medius_capi.dll` | `medius_capi.lib` | link `medius_capi.dll.lib` (import) or `.lib` (static); no `lib` prefix |

#### COMPILE A ONE-LINE SANITY CHECK

```c
// hello.c: proves the library links and loads
#include <medius.h>
#include <stdio.h>

int main(void) {
    printf("medius %s, abi %u\n", medius_version_string(), medius_abi_version());
    return 0;
}
```

```bash
cc hello.c -I medius-capi/include -L target/release -lmedius_capi -lpthread -o hello
LD_LIBRARY_PATH=target/release ./hello
# medius 3.0.0, abi 3
```

> **Note**
>
> `-L` only helps the linker. The shared library must also be findable by the dynamic loader when the program _runs_: Linux `LD_LIBRARY_PATH` or an rpath, macOS `DYLD_LIBRARY_PATH` / `@rpath`, Windows the `.dll` next to the exe or on `PATH`. Or link the static library (`.a` / `.lib`) to fold it into your binary and skip the run-time hunt.

## Packaging

_Prebuilt tarballs, no vcpkg or Conan port_

Each release attaches one tarball per platform, `medius-capi-<target-triple>.tar.gz`, to the [GitHub Release](https://github.com/K4HVH/medius/releases). Download, unpack, and use the flags above.

| Inside the tarball | Contents |
| --- | --- |
| `include/medius.h` | the header (mock/flash declarations gated by the macros) |
| `lib/` | the prebuilt `libmedius_capi`, shared and static, with mock and flash off |

> **Note**
>
> No [vcpkg](https://vcpkg.io) or [Conan](https://conan.io) port: those build C and C++ from source with no Rust toolchain, so a Rust-backed library doesn't fit. Use the prebuilt tarball, or build `medius-capi` from source. Python uses the [prebuilt wheel](/bindings/python/build.md#packaging).
