# Embedded C compiler and linker via LLVM

> Use embedded Clang and LLVM to compile freestanding C17 into object files or LLVM IR, or link and invoke a native function in memory through ORC LLJIT.

`elide cc` embeds Clang compilation and LLVM's ORC LLJIT execution pipeline. Compile one freestanding C17
translation unit for the current host, emit an object file or textual LLVM IR, or link and invoke a native
function in memory. These operations require no separate compiler installation.

> [!NOTE] Frontend scope
> Native tools are part of Elide 1.6.2. The initial CLI exposes object output, LLVM IR
> output and in-memory JIT execution. It does not expose executable or shared-library output, system headers,
> include paths, library selection or cross-compilation.

## Compile a C source file

`answer.c`:

```c
long long answer(void) {
  return 42;
}
```

Compile it to a native object file:

```bash
elide cc -- -c answer.c -o answer.o
```

`answer.o` is a host-native relocatable object. To produce an executable or shared library from it, pass it
to a full compiler driver or linker; the current `cc` CLI does not expose those output modes.

Without `-o`, Elide writes the source basename with an `.o` extension in the current working directory:
`elide cc -- -c src/answer.c` produces `./answer.o`.

## Inspect LLVM IR

Select both `-S` and `-emit-llvm` to write textual LLVM IR:

```bash
elide cc -- -S -emit-llvm answer.c -o answer.ll
```

Without `-o`, the output is `answer.ll` in the current directory. `-S` alone does not emit assembly, and
`-c -emit-llvm` does not emit bitcode; these combinations are rejected.

## Invoke a native function

Compile the same source to LLVM IR, JIT-compile and link it in memory, then invoke `answer`:

```bash
elide cc -- --run answer answer.c
```

```terminaloutput
42
```

The entry point must be defined with the C calling convention, no arguments, no varargs and an LLVM `i64`
return type, represented here by `long long`. `int`, floating-point, pointer and `void` return types are
rejected for the entry point.

Elide prints the signed 64-bit result and exits successfully. The returned value does not become the shell
exit status: returning `42` still gives exit status `0`. `--run` creates no object or executable file and
cannot be combined with `-c`, `-S`, `-emit-llvm` or `-o`.

ORC LLJIT owns compilation, in-memory linking and symbol lookup for that invocation. The JIT and its code
are released after the call; functions and native addresses do not persist across commands. The CLI does
not expose argument passing or external library loading. Native code executes with the process's privileges;
invalid memory access or other native faults can terminate the process.

## Options

Pass compiler arguments after `--`:

| Option | Behavior |
| --- | --- |
| `-c` | Write a native object file. |
| `-S -emit-llvm` | Write textual LLVM IR. |
| `-o PATH` | Set the object or IR output path. |
| `--run SYMBOL` | Compile, link in memory and invoke a no-argument function returning `long long`. |
| `--help`, `-h` | Show the embedded compiler's help. |

```bash
elide cc -- --help
```

Exactly one source file and one output mode are required. Other compiler-driver options, including `-I`,
`-D`, `-l`, `-O` and `--target`, are not accepted. The command refuses to overwrite its source with its output.

## Headers and toolchain boundaries

The embedded compiler uses freestanding C17 with standard include discovery disabled. Write self-contained
translation units; installed host headers and bundled Native Image sysroots are not exposed through `cc`.
Adding `SDKROOT` does not enable system includes in this command.

Elide also packages a full Clang driver, LLD and target resources for
[Native Image](https://elide.help/docs/toolchain/jvm/native-image). That driver handles Native Image's C compilation and final
executable or shared-library link; `elide cc -- --run` uses ORC LLJIT for in-memory linking. On macOS,
Native Image requires an explicit `SDKROOT` until the distribution includes an Apple SDK. The freestanding
examples above need no Apple SDK.

To generate Java bindings for an existing C library, use [jextract](https://elide.help/docs/toolchain/native/jextract), or compile
bindings directly with [Java C header bindings](https://elide.help/docs/toolchain/jvm/javac#c-header-bindings).

## Availability

| Elide distribution | Embedded `cc` |
| --- | --- |
| macOS arm64 | Supported. |
| Dynamically linked Linux amd64 or arm64 | Supported. |
| Fully static Linux / musl Elide | Not included. |
| Windows | Not included. |

The supported distributions include native tools alongside the JVM toolchain and load the compiler payload
when needed. A custom build made with `--no-jvm-toolchain` omits both. Having JVM tools on Windows or a fully
static build does not imply that `cc` or `jextract` is available.

A dynamically linked Linux Elide can still build a musl-targeted Native Image when its distribution includes
the appropriate sysroot; that is separate from running native tools inside a fully static Elide binary.
