# Julia — Admin & Developer Guide

This guide is for the people who build, deploy, embed, and extend Julia: operators compiling Julia from source, packagers and distributors, developers embedding `libjulia` in larger applications, HPC administrators tuning Julia across clusters, and contributors who need a map of the runtime's internals. It documents Julia's architecture, its build system, configuration surface, security-relevant behavior, and the organization of its C/C++ core.

For installing and *using* the `julia` program day-to-day, see the companion **User Guide**. This document deliberately goes deeper: it is meant to be exhaustive enough that an engineer (or an AI) could understand how Julia is structured and reproduce its build and deployment.

> [!NOTE]
> This guide describes the Julia source tree at version `1.14.0-DEV` (commit `2614585`). Julia is released under the MIT license (© 2009–2025 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and contributors).

---

## Table of Contents

1. [Executive Summary](#1-executive-summary)
2. [System Architecture](#2-system-architecture)
3. [Repository Structure](#3-repository-structure)
4. [System Requirements](#4-system-requirements)
5. [Building Julia from Source](#5-building-julia-from-source)
6. [Build Configuration Reference (`Make.user`)](#6-build-configuration-reference-makeuser)
7. [The Runtime in Depth](#7-the-runtime-in-depth)
8. [System Images, Package Images, and AOT (`juliac`)](#8-system-images-package-images-and-aot-juliac)
9. [Embedding `libjulia`](#9-embedding-libjulia)
10. [Configuration & Environment Surface](#10-configuration--environment-surface)
11. [Operations](#11-operations)
12. [Security Analysis](#12-security-analysis)
13. [Code Quality & Conventions](#13-code-quality--conventions)
14. [Testing Strategy](#14-testing-strategy)
15. [Troubleshooting (Build & Deploy)](#15-troubleshooting-build--deploy)
16. [Potential Improvements](#16-potential-improvements)
17. [Contributing](#17-contributing)
18. [Quick Reference](#18-quick-reference)

---

## 1. Executive Summary

Julia is a programming-language implementation: a compiler, a runtime, a standard library, and a command-line front end, distributed together. Architecturally it is a **polyglot** project:

- The **language core and runtime** are written in C and C++ (`src/`) — the type system, multiple-dispatch method tables, the LLVM-based code generator, garbage collectors, task scheduler, and the embedding API.
- The **standard library** (`base/` and `stdlib/`) is written largely in Julia itself, which is possible because the runtime bootstraps a working Julia early in the build.
- A **front-end parser** lives in the bundled `flisp` Scheme interpreter (`src/flisp`) plus the newer `JuliaSyntax` / `JuliaLowering` components.
- A thin **C loader** (`cli/`) is what users actually invoke as `julia`; it locates and loads the runtime shared libraries and jumps into them.

The defining design choices an administrator must understand:

| Choice | Operational consequence |
|---|---|
| **JIT compilation via LLVM** | First use of a function is compiled; "time-to-first-result" latency is real and is mitigated by caching (system images, package images, precompilation). |
| **System image** | Julia starts from a pre-compiled snapshot of Base + stdlib. Building, customizing, and shipping these images is a core deployment lever. |
| **Three-library split** (`libjulia`, `libjulia-internal`, `libjulia-codegen`) | Code generation can be separated from the runtime; `libjulia-codegen` is optional and deletable to save space. |
| **Self-contained depot** | All package/cache/config state lives under `~/.julia` (configurable). Uninstalling is "delete two directories." |
| **BinaryBuilder dependencies** | The build downloads pre-built external libraries by default; air-gapped builds must opt out (`USE_BINARYBUILDER=0`). |

> [!IMPORTANT]
> The single most consequential operational concept in Julia is the **system image**. Almost every performance, startup-latency, deployment, and HPC-portability decision routes through how the sysimage is built and targeted (`-J`, `--output-*`, `--trim`, `JULIA_CPU_TARGET`). Read [Section 8](#8-system-images-package-images-and-aot-juliac) carefully.

---

## 2. System Architecture

### 2.1 The launch / loading chain

The `julia` binary is **not** the runtime — it is a small RPATH-style relative-path loader (`cli/loader_exe.c`, `cli/loader_lib.c`). Its job is to open the runtime libraries in the correct order and hand control to them.

```text
                       ┌──────────────────────────────────────────┐
   user runs `julia`   │  julia (loader executable, cli/)           │
 ───────────────────►  │  main() → jl_load_repl()                   │
                       └───────────────┬────────────────────────────┘
                                       │ dlopen() DEP_LIBS, in order:
                                       │
              ┌────────────────────────┼─────────────────────────────┐
              ▼                        ▼                              ▼
      ┌───────────────┐       ┌──────────────────┐        ┌────────────────────┐
      │  libstdc++     │       │ libjulia-internal │        │ libjulia-codegen    │
      │  (probed: use  │       │  (the runtime:    │        │ (LLVM code gen;     │
      │  system one if │       │  GC, types,       │        │  OPTIONAL — falls   │
      │  newer, else   │       │  dispatch, tasks) │        │  back to internal)  │
      │  bundled)      │       └──────────────────┘        └────────────────────┘
      └───────────────┘                 │
                                         │ re-export runtime symbols,
                                         │ jl_init_options(), set up fast TLS
                                         ▼
                               jl_repl_entrypoint(argc, argv)
                                         │
                                         ▼
                          REPL  /  script  /  -e expression
```

Key facts grounded in `cli/loader_lib.c`:

- **`DEP_LIBS`** is a colon-separated, order-sensitive list of dependent libraries; `libjulia` must be last. Libraries prefixed `@` are "special" and handled with custom logic. There are exactly **three** special libraries: `libstdc++`, `libjulia-internal`, `libjulia-codegen`.
- **libstdc++ probing**: on Linux, the loader probes for a *system* libstdc++ newer than the bundled one and prefers it (to stay compatible with third-party dynamic libraries that link the system C++ runtime). This is controlled by `JULIA_PROBE_LIBSTDCXX` (`1`/`yes`/`0`/`no`).
- **Optional codegen**: if `libjulia-codegen` cannot be found, the loader sets it to `libjulia-internal` and uses a fallback function table — Julia can then run already-compiled code but cannot generate new code.
- **Fast TLS**: on Linux/FreeBSD the loader sets up a static thread-local-storage key for the per-thread GC stack (`jl_pgcstack`), guarded by an atomic semaphore so it is installed exactly once.
- **Windows**: the loader bundles its own minimal libc shims (`cli/loader_win_utils.c`) — `malloc`/`free` over the process heap, UTF-16↔WTF-8 conversion, command-line splitting — so it can run without depending on libgcc.

### 2.2 The runtime libraries (`src/`)

The runtime is a large C/C++ codebase. The file inventory itself is a clean architecture map; the largest and most load-bearing translation units:

| Concern | Primary source | Role |
|---|---|---|
| **Code generation** | `codegen.cpp`, `cgutils.cpp`, `intrinsics.cpp` | Lower Julia IR to LLVM IR; emit native code |
| **JIT** | `jitlayers.cpp`, `aotcompile.cpp`, `cgmemmgr.cpp` | ORC-style JIT layers; ahead-of-time compilation; code memory management |
| **Type system** | `jltypes.c`, `datatype.c`, `subtype.c`, `typemap.c` | Types, datatype layout, the subtyping algorithm, dispatch type maps |
| **Multiple dispatch** | `gf.c`, `method.c` | Generic functions, method tables, specialization & dispatch |
| **Builtins & intrinsics** | `builtins.c`, `runtime_intrinsics.c` | Core operations and numeric intrinsics |
| **Garbage collection** | `gc-stock.c`, `gc-mmtk.c`, `gc-debug.c`, `gc-heap-snapshot.c` | Two collectors: the **stock** GC and an **MMTk**-based GC; debugging & heap snapshots |
| **Tasks & threads** | `task.c`, `threading.c` | Green-thread tasks (coroutines), the threadpool scheduler |
| **System image** | `staticdata.c`, `staticdata_utils.c`, `ircode.c` | Serialize/deserialize the compiled session image; IR (de)serialization |
| **Startup & API** | `init.c`, `jlapi.c`, `jloptions.c` | Process init, the embedding C API, command-line option parsing |
| **FFI** | `ccall.cpp` | `ccall`/`@ccall` foreign-function interface to C/Fortran |
| **Interpreter** | `interpreter.c`, `toplevel.c` | Interpret IR (used during bootstrap and where JIT is disabled); top-level eval |
| **Signals & stack** | `signals-unix.c`, `signals-mach.c`, `stackwalk.c` | Signal handling per platform; backtraces |
| **AST / parser bridge** | `ast.c`, `src/flisp/` | Bridge to the flisp-based front end |
| **CPU dispatch** | `processor.cpp`, `llvm-multiversioning.cpp` | Multi-versioning of code for different CPU feature sets |

> [!NOTE]
> The presence of **both** `gc-stock.c` and `gc-mmtk.c` reflects that Julia supports a pluggable GC: the long-standing stock collector and an alternative built on the MMTk memory-management toolkit, selected at build time.

### 2.3 The compiler front end

Julia's surface syntax is parsed and lowered through a chain that includes the embedded **flisp** Scheme interpreter (`src/flisp/`, a complete femtolisp implementation) and the newer **`JuliaSyntax`** and **`JuliaLowering`** components (in-tree at the repository root). Parsed and lowered code becomes Julia IR, which the interpreter runs directly or the codegen path compiles via LLVM.

### 2.4 The standard library

`base/` is the `Base` module — the always-available core, written in Julia. `stdlib/` holds the bundled standard-library packages (e.g. `Dates`, `Random`, `LinearAlgebra` machinery, `REPL`, `Printf`, `Sockets`, `Logging`, `Markdown`, `TOML`, `Test`, `Profile`, `InteractiveUtils`, `LibGit2`, plus a large set of `*_jll` artifact packages wrapping external binaries such as `OpenBLAS_jll`, `LLVM`, `MPFR_jll`, `GMP_jll`, `LibCURL_jll`, `OpenSSL_jll`, `Zstd_jll`). The `*_jll` packages are how Julia ships and locates its bundled native dependencies at runtime.

---

## 3. Repository Structure

| Directory | Contents |
|---|---|
| `base/` | The `Base` module — core standard library, written in Julia |
| `Compiler/` | The compiler (type inference / optimization) as a relocatable component |
| `JuliaSyntax/` | Modern parser |
| `JuliaLowering/` | Lowering (desugaring) component |
| `cli/` | The command-line launcher / loader (C) |
| `contrib/` | Miscellaneous scripts and platform install helpers (mac/, windows/, build helpers) |
| `deps/` | External dependencies and their build glue |
| `doc/` | The user manual (`doc/src/`), developer docs (`doc/src/devdocs/`), and the `julia.1` man page (`doc/man/`) |
| `etc/` | The default `startup.jl` |
| `src/` | The language core and runtime (C/C++ + flisp) |
| `stdlib/` | Bundled standard-library packages |
| `test/` | Test suites (including `embedding/`, `gcext/`, `trimming/`, `clangsa/`, `llvmpasses/`) |

> [!TIP]
> Julia's Makefiles define automatic `print-<VARNAME>` rules. For example `make print-JULIA_PRECOMPILE` prints the value of `JULIA_PRECOMPILE`. This is the fastest way to introspect any build variable.

---

## 4. System Requirements

### 4.1 Disk and memory (build)

- **~5 GiB disk** if building all dependencies (the README cites ~2 GiB for a basic build; the detailed build doc cites ~5 GiB when building all dependencies).
- **~4 GiB virtual memory** during the build.

### 4.2 Toolchain

Building Julia requires a working C/C++ toolchain and GNU `make`. External libraries (LLVM, OpenBLAS, LibGit2, GMP, MPFR, PCRE2, SuiteSparse, libuv, etc.) are downloaded pre-built by default via BinaryBuilder; building them yourself requires the corresponding system toolchains.

> [!CAUTION]
> The build **will fail badly** if any parent directory of the build tree contains spaces or shell metacharacters such as `$` or `:` in its name. This is a limitation of GNU make. Keep the source path simple (e.g. `/home/user/julia`).

> [!NOTE]
> On macOS, run `xcode-select --install` to provide the command-line tools; otherwise you may hit missing-header/library errors such as `ld: library not found for -lcrt1.10.6.o`.

### 4.3 Supported platforms

The Julia project publishes official binaries and a tiered support matrix at <https://julialang.org/downloads/support>. The recommended runtime install on all platforms is **Juliaup** (see the User Guide).

---

## 5. Building Julia from Source

### 5.1 Acquire the source

```bash
git clone https://github.com/JuliaLang/julia.git
cd julia
```

By default you are on the latest unstable development branch. For production, check out a released tag:

```bash
git checkout v1.13.0   # replace with the desired release tag
```

> [!TIP]
> Behind a firewall? Force HTTPS for git submodule/dependency fetches:
> ```bash
> git config --global url."https://".insteadOf git://
> ```
> and set `https_proxy` / `http_proxy` as needed.

### 5.2 Build

```bash
make
```

For a parallel build, pass the job count:

```bash
make -j 8
```

The first build downloads pre-built external dependencies automatically. When it completes, a `julia` symlink appears in the build directory (the real executable is under `<build-directory>/usr/bin`):

```bash
./julia
```

### 5.3 Verify

```bash
make testall
```

You should see a series of running tests complete without error.

### 5.4 Out-of-tree builds

```bash
make O=/path/to/builddir configure
make -C /path/to/builddir
```

Out-of-tree build directories share the source files and `deps/srccache`, and each can carry its own `Make.user`.

### 5.5 Install

Set a prefix in `Make.user`:

```make
prefix=/opt/julia
```

then:

```bash
make install
```

> [!WARNING]
> If a Julia install already exists in the target prefix, delete it before `make install`.

### 5.6 Air-gapped / self-built dependencies

To build every dependency from source (no network during build), put this in `Make.user`:

```make
USE_BINARYBUILDER=0
```

### 5.7 Updating an existing tree

```bash
cd julia
git pull && make
```

If bootstrap fails after a large update, `make clean && make` (or, more rarely, `make cleanall && make`) usually resolves it.

### 5.8 Distribution artifacts

The top-level Makefile exposes targets for producing distributable artifacts:

| Target | Produces |
|---|---|
| `make binary-dist` | A binary distribution tarball (runs `distclean` first) |
| `make source-dist` / `make full-source-dist` / `make light-source-dist` | Source distributions |
| `make exe` | A standalone executable bundle |
| `make app` / `make darwinframework` | macOS `.app` / framework (see `contrib/mac/`) |
| `make win-extras` | Windows packaging extras |

See `doc/src/devdocs/build/distributing.md` for platform-specific packaging notes.

---

## 6. Build Configuration Reference (`Make.user`)

Build options are set in a `Make.user` file placed at the source root (or per out-of-tree build directory). **Never edit `Make.inc`** for this purpose — it documents the available variables at its top, but `Make.user` is the override mechanism.

Operationally important build variables:

| Variable | Effect |
|---|---|
| `prefix=<dir>` | Install location for `make install` |
| `USE_BINARYBUILDER=0` | Build all external dependencies from source instead of downloading pre-built |
| `O=<dir>` (on the `make` command line) | Configure an out-of-tree build directory |
| `JULIA_CPU_TARGET=<targets>` | CPU multi-versioning target string baked into the build (see [Section 8.4](#84-cpu-targeting--multi-versioning)) |
| `JULIA_PRECOMPILE` | Whether to precompile the system image during build (inspect with `make print-JULIA_PRECOMPILE`) |
| `WITH_GC_DEBUG_ENV` | Enable GC-debug environment hooks (e.g. `JULIA_GC_WAIT_FOR_DEBUGGER`) |
| `USE_INTEL_JITEVENTS` / `USE_OPROFILE_JITEVENTS` / `USE_PERF_JITEVENTS` | Enable JIT-profiling integration (VTune / OProfile / Perf) |
| `JULIA_BUILD_MODE` | `release` or `debug` (the default target builds one of these) |

> [!TIP]
> `make debug` and `make release` build the debug and release runtimes respectively; `make` alone builds whichever `JULIA_BUILD_MODE` selects. The debug runtime is `libjulia-debug` and the executable is `julia-debug`.

Dependency-wipe targets are invaluable when an external library is in a bad state:

```bash
make -C deps clean-llvm       # rebuild LLVM from the cached source dist
make -C deps distclean-llvm   # also re-download the LLVM source dist
```

---

## 7. The Runtime in Depth

### 7.1 Startup sequence

1. The OS runs the **loader** (`cli/loader_exe.c` `main`). On Windows the entry is `mainCRTStartup`, which converts `wchar_t` arguments to UTF-8 first.
2. The loader's constructor (`jl_load_libjulia_internal`) opens `DEP_LIBS` in order, performing libstdc++ probing and re-exporting runtime symbols, then calls `jl_init_options`.
3. Fast TLS for the per-thread GC stack is installed (Linux/FreeBSD).
4. `jl_load_repl` looks up and jumps to `jl_repl_entrypoint` inside `libjulia-internal`.
5. The runtime initializes (`init.c`), loads the **system image** (Base + stdlib, pre-compiled), processes command-line options (`jloptions.c`), and dispatches to the REPL, a script, or an `-e` expression.

### 7.2 Compilation pipeline

```text
 source text
   │  flisp / JuliaSyntax  (parse)
   ▼
 surface AST
   │  JuliaLowering        (desugar → lowered IR)
   ▼
 lowered Julia IR
   │  Compiler/ (type inference, optimization)
   ▼
 typed, optimized IR
   │  codegen.cpp → LLVM IR → jitlayers.cpp (ORC JIT)   [libjulia-codegen]
   ▼
 native machine code  ──► executed; cached in memory and (optionally) on disk
```

The first call of a function for a given argument-type signature triggers specialization + compilation; the result is reused. Disk caches (system images, package images, precompilation files) persist this work across sessions.

### 7.3 Garbage collection

Julia ships a generational, non-moving **stock** collector (`gc-stock.c`) and an alternative **MMTk**-based collector (`gc-mmtk.c`), chosen at build time. GC parallelism is controlled by `--gcthreads=N[,M]` / `JULIA_NUM_GC_THREADS`, and memory pressure by `--heap-size-hint` / `JULIA_HEAP_SIZE_HINT`. GC debugging facilities live in `gc-debug.c`; heap snapshots in `gc-heap-snapshot.c` (triggerable via `JULIA_PROFILE_PEEK_HEAP_SNAPSHOT`).

### 7.4 Tasks and threading

Julia tasks (`task.c`) are stackful coroutines scheduled across OS threads (`threading.c`). There are two **threadpools**: `:default` for compute and `:interactive` for latency-sensitive work, sized via `-t N,M` / `JULIA_NUM_THREADS=N,M`. `JULIA_EXCLUSIVE` affinitizes default-pool threads for dedicated machines; `JULIA_THREAD_SLEEP_THRESHOLD` tunes spin-then-sleep behavior.

### 7.5 Foreign-function interface

`ccall.cpp` implements `ccall`/`@ccall`, Julia's zero-overhead C/Fortran FFI. This is also the mechanism by which the `*_jll` artifact packages call into bundled native libraries.

---

## 8. System Images, Package Images, and AOT (`juliac`)

This is the heart of Julia deployment and performance tuning.

### 8.1 System images

A **system image** is a serialized snapshot of a compiled Julia world: Base, the standard library, and their compiled methods (`staticdata.c` handles (de)serialization). Julia starts from a default system image; `-J`/`--sysimage <file>` selects a different one.

Generate images and other static outputs with these `julia` switches:

| Switch | Output |
|---|---|
| `--output-ji <name>` | System image data file (`.ji`) |
| `--output-o <name>` | Object file including system image data |
| `--output-bc` / `--output-unopt-bc` | (Unoptimized) LLVM bitcode |
| `--output-asm` | Assembly |
| `--output-incremental={yes\|no*}` | Incremental vs. complete output |
| `--strip-metadata` | Drop docstrings and source locations from the image |
| `--strip-ir` | Drop compiled-function IR from the image |

> [!TIP]
> A custom system image that pre-compiles your application's hot paths is the most effective way to eliminate first-call latency in production and HPC jobs. The community tool **PackageCompiler.jl** wraps this workflow.

### 8.2 Package images (pkgimages)

Package images cache *native code* per package on disk. They are controlled by `--pkgimages={yes*|no|existing}` and `--permalloc-pkgimg`. `JULIA_MAX_NUM_PRECOMPILE_FILES` (default 10) bounds how many cached variants of a single package are kept.

### 8.3 Trimming and `juliac`

`--trim={no*|safe|unsafe|unsafe-warn}` builds a system image containing **only** code provably reachable from methods marked by `entrypoint`, enabling much smaller binaries. The in-tree `juliac` tooling (`contrib/juliac/`, installed as `juliac.jl` plus build scripts) drives the ahead-of-time compilation path (`aotcompile.cpp`).

| `--trim` mode | Dynamic call sites |
|---|---|
| `no` (default) | Full image, nothing trimmed |
| `safe` | Compile-time **error** on dynamic call sites |
| `unsafe` | Allowed; binary may be missing code and can error at runtime |
| `unsafe-warn` | Allowed with compile-time warnings; may error at runtime |

> [!WARNING]
> `unsafe`/`unsafe-warn` trimming can produce binaries that throw at runtime due to code that was trimmed away. Validate trimmed binaries against a representative workload before shipping.

### 8.4 CPU targeting & multi-versioning

Julia can emit **multiple versions** of code for different CPU feature sets (`processor.cpp`, `llvm-multiversioning.cpp`). Two distinct controls:

- **`-C`/`--cpu-target`** affects **in-memory JIT** codegen for the current session. `julia -C help` lists valid targets.
- **`JULIA_CPU_TARGET`** affects **disk-cached** images (system and package images) only — not the in-session JIT.

The target string is `;`-separated; each entry is a CPU/architecture name plus optional comma-separated features. Special keywords: `sysimage` (reuse the running sysimage's target), `clone_all` (force-clone all functions), `base(N)` (base-target index), `opt_size` (`-Os`), `min_size` (`-Oz`).

> [!IMPORTANT]
> On heterogeneous HPC clusters where nodes have different processors, set `JULIA_CPU_TARGET` to a target that is valid on the *least capable* node (or use `sysimage`) so cached code runs everywhere. Package images can only target the same or *more specific* features than their base system image.

---

## 9. Embedding `libjulia`

Julia exposes a C API (`jlapi.c`, header `src/julia.h`) so it can be embedded in larger C/C++ (or, via the C ABI, Rust/Python/C#) applications.

### 9.1 Minimal embedding (Unix)

```c
#include <julia.h>
JULIA_DEFINE_FAST_TLS // define exactly once, in an executable (not a shared library)

int main(int argc, char *argv[])
{
    jl_init();                          // set up the Julia context
    jl_eval_string("print(sqrt(2.0))"); // run Julia code
    jl_atexit_hook(0);                  // flush writes, run finalizers
    return 0;
}
```

Compile and link against `libjulia` (with Julia installed at `$JULIA_DIR`):

```bash
gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib \
    -Wl,-rpath,$JULIA_DIR/lib test.c -ljulia
```

> [!NOTE]
> - `jl_init()` auto-detects the install location. Use `jl_init_with_image_file` / `jl_init_with_image_handle` to pin a custom location or system image.
> - Dynamically linking `libjulia` currently requires `RTLD_GLOBAL`.
> - If embedded Julia must see symbols from the host executable (Linux), add `-Wl,--export-dynamic`.
> - `cli/loader_exe.c` itself is a worked example of setting `jl_options` while linking `libjulia`; `test/embedding/` contains a full example program.

### 9.2 `julia-config.jl`

The `julia-config.jl` script (in Julia's shared data directory) emits the exact compiler/linker flags an embedding program needs for *this* distribution. Use it instead of hard-coding flags.

### 9.3 GC extensions

The `test/gcext/` suite and the runtime's GC-extension hooks let embedders register foreign roots with the collector — relevant when the host application holds references to Julia objects.

---

## 10. Configuration & Environment Surface

Julia has **no central config file** for the runtime; configuration is expressed through (a) command-line switches, (b) environment variables, and (c) the user's `startup.jl`. The User Guide contains the complete switch and environment-variable reference. The admin-relevant highlights:

### 10.1 Path and depot control

| Variable | Operational role |
|---|---|
| `JULIA_DEPOT_PATH` | Where all package/cache/config/history state lives. Use a trailing `:` to override the user depot while keeping bundled resources; key for shared/read-only deployments. **Set before startup.** |
| `JULIA_LOAD_PATH` | Which environments/packages are loadable. **Set before startup.** |
| `JULIA_PROJECT` | The initial active environment. **Set before startup.** |
| `JULIA_BINDIR` | Override the detected executable directory (`Sys.BINDIR`). |
| `JULIA_HISTORY` | Relocate the REPL history file. |

### 10.2 Read-only / immutable deployments

For images deployed on read-only filesystems (containers, HPC scratch policies):

```bash
julia --compiled-modules=existing --pkgimages=existing --startup-file=no
```

This uses existing caches without attempting to write new ones. Point `JULIA_DEPOT_PATH` at a writable scratch location if any writes are needed.

### 10.3 Package server / network policy

| Variable | Use |
|---|---|
| `JULIA_PKG_SERVER` | Set the registry/package server URL; `""` bypasses the PkgServer protocol |
| `JULIA_PKG_SERVER_REGISTRY_PREFERENCE` | `conservative` (firewall-safe default) vs. `eager` |
| `JULIA_PKG_OFFLINE` | Fully offline package operation |
| `JULIA_PKG_USE_CLI_GIT` | Use system `git` instead of libgit2 |
| `JULIA_SSL_CA_ROOTS_PATH`, `JULIA_*_VERIFY_HOSTS` | TLS/SSH host-verification policy |

### 10.4 Startup files (run order)

`startup.jl` is loaded from `$JULIA_DEPOT_PATH/config/startup.jl` (or `~/.julia/config/startup.jl`). System-wide startup is searched at `$JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl` and `$JULIA_BINDIR/../etc/julia/startup.jl`.

> [!CAUTION]
> `__init__()` functions of modules baked into a system image (via PackageCompiler) run **before** `startup.jl`. Environment variables those modules read must be set before the process starts, not in `startup.jl`.

---

## 11. Operations

### 11.1 Deployment checklist

- [ ] Decide install method: **Juliaup** for interactive/dev, a pinned binary tarball or custom system image for production/HPC.
- [ ] Pin the Julia version (release tag or sysimage build).
- [ ] Set `JULIA_DEPOT_PATH` to a writable, appropriately-sized location (caches and artifacts grow).
- [ ] Set `JULIA_CPU_TARGET` for the target hardware (or the least-capable node on a heterogeneous cluster).
- [ ] Decide on a custom system image to remove first-call latency for your workload.
- [ ] Configure package-server/network policy for the deployment's network posture.
- [ ] For containers/read-only roots: use `--compiled-modules=existing --pkgimages=existing`.
- [ ] Lock a consistent launch command (flags affect caching — see below).

### 11.2 Startup / shutdown

- **Start:** `julia [flags]`. There is no daemon; each invocation is a process. For services, keep a long-lived process (the JIT warms up over time).
- **Stop:** `exit()` / `exit(code)` from Julia, <kbd>Ctrl</kbd>+<kbd>D</kbd> interactively, or a normal signal. `--handle-signals={yes*|no}` controls Julia's own signal handlers.

### 11.3 Logging and diagnostics

| Need | Mechanism |
|---|---|
| Debug logging for a module | `JULIA_DEBUG=ModuleName` |
| What is being compiled (and how long) | `--trace-compile=stderr --trace-compile-timing` |
| What is being dispatched | `--trace-dispatch=stderr` |
| Top-level expression tracing | `--trace-eval=loc` |
| Subsystem timing zones | `JULIA_TIMING_SUBSYSTEMS=+GC,-INFERENCE` |
| Heap snapshot | `JULIA_PROFILE_PEEK_HEAP_SNAPSHOT` |
| Per-task metrics | `--task-metrics=yes` |
| Allocation / coverage profiling | `--track-allocation`, `--code-coverage` |

> [!NOTE]
> CI debug environment variables auto-enable `--trace-eval` (location mode) and verbose test output, so re-running a failed CI job with debug logging needs no script changes.

### 11.4 Caching hygiene

Because optimization-affecting flags (`-O`, `-g`, `--check-bounds`) change generated code, **changing them between runs invalidates and regenerates caches**. Pin a single launch command per deployment to keep precompilation/pkgimage caches warm. Pkg's automatic artifact/package GC (disable with `JULIA_PKG_GC_AUTO=false`, Julia 1.12+) reclaims depot space.

### 11.5 Backup / state

The only persistent state Julia writes is under the depot (`~/.julia` by default): installed packages, registries, artifacts, compiled caches, config, and REPL history. Back up `Project.toml` + `Manifest.toml` for reproducibility; the rest of the depot is reconstructible from those plus the registries.

---

## 12. Security Analysis

> [!NOTE]
> This section assesses the security-relevant behavior of the Julia *implementation and toolchain* as observed in the source tree. It is not a vulnerability assessment of any particular deployment.

### 12.1 Trust model

Julia executes arbitrary code by design — it is a programming language. There is **no sandbox** around user code: a `.jl` script, an `-e` expression, an `include`, or a loaded package can do anything the OS user can (file I/O, network, `ccall` into native code, spawning processes via shell mode / `run`). Treat running untrusted Julia code exactly as you would treat running an untrusted native binary.

### 12.2 Code loading & supply chain

- **Package server / registries:** packages are fetched from `JULIA_PKG_SERVER` (default `https://pkg.julialang.org`). Artifact integrity is verified by hash; `JULIA_PKG_IGNORE_HASHES=1` disables that verification and should be used only as a last resort.
- **TLS/SSH host verification:** governed by `JULIA_SSL_CA_ROOTS_PATH` and the `JULIA_*_VERIFY_HOSTS` family. The default `conservative` registry preference is the firewall- and supply-chain-safer choice; `eager` publishes resources that haven't necessarily been processed by the storage servers.
- **`Manifest.toml` pinning** is the primary supply-chain control: it records exact resolved versions and hashes, making environments reproducible and auditable.

### 12.3 Native library loading

The loader (`cli/loader_lib.c`) loads dependent libraries by **relative path** from the library directory (RPATH-style), reducing reliance on ambient `LD_LIBRARY_PATH`. On Linux it may prefer a *system* libstdc++ if it is newer (controllable via `JULIA_PROBE_LIBSTDCXX`), and it emulates the dynamic linker's library search (`LD_LIBRARY_PATH` → `/etc/ld.so.cache` → default libdirs) when probing for a system libstdc++. Operators who need fully hermetic loading can disable probing.

### 12.4 Memory safety

The runtime is C/C++ and is therefore subject to the usual memory-safety considerations of native code. The project maintains substantial defensive infrastructure:

- **Clang Static Analyzer** integration (`src/clangsa/`, `test/clangsa/`) with custom checkers for Julia's GC-rooting invariants.
- **Sanitizer** build support: AddressSanitizer (`contrib/asan/`), ThreadSanitizer (`contrib/tsan/`), and MemorySanitizer wiring in the loader. The loader disables `RTLD_DEEPBIND` and tweaks fork behavior under ASan/TSan.
- **GC-extension** and **gcext** tests (`test/gcext/`) exercise foreign-root registration.

### 12.5 Reporting vulnerabilities

Security issues are reported per the project's `SECURITY.md`. General bugs go to the GitHub issue tracker; a reproducible bug-report session can be captured with `julia --bug-report=KIND`.

---

## 13. Code Quality & Conventions

- **License header:** every source file carries `// This file is a part of Julia. License is MIT: https://julialang.org/license`. `contrib/add_license_to_files.jl` adds it.
- **Whitespace policy:** enforced by `contrib/check-whitespace.jl`; the build target `make check-whitespace` (and `make fix-whitespace`) gate it. `make test` and `make testall` both run `check-whitespace` first.
- **C/C++ core, Julia stdlib:** the deliberate split keeps the performance-critical, GC-aware machinery in C/C++ while the broad, evolving standard library is written in Julia and bootstrapped during the build.
- **Multi-platform code** is heavily `#ifdef`-guarded (`_OS_WINDOWS_`, `_OS_LINUX_`, `_OS_DARWIN_`, `_CPU_X86_64_`, etc.), and Windows runs with bundled libc shims to avoid a libgcc dependency.
- **X-macro pattern:** exported-symbol lists are generated via X-macros (`jl_exported_funcs.inc`, `jl_exported_data.inc`) consumed in `cli/jl_exports.h` — a single source of truth re-expanded for declarations, address tables, and name tables.

---

## 14. Testing Strategy

The `test/` tree is driven by `make test` / `make testall` (and `make testall1`), which run `runtests.jl` with `--check-bounds=yes --startup-file=no --depwarn=error`. The test Makefile enumerates test groups dynamically.

| Test area | Directory | Exercises |
|---|---|---|
| Test groups | `test/` (e.g. `unicode`, `strings`, `compiler`, `Compiler`, `JuliaSyntax`, `JuliaLowering`) | Core language & compiler |
| Stdlib tests | `stdlib/*/test/` | Each standard-library package |
| Embedding | `test/embedding/` | The C embedding API end-to-end |
| GC extensions | `test/gcext/` | Foreign-root registration |
| Trimming / AOT | `test/trimming/` | `--trim` binaries |
| Static analysis | `test/clangsa/` | Clang Static Analyzer GC-rooting checks |
| LLVM passes | `test/llvmpasses/` | Custom LLVM optimization passes |
| Relocation | `test/relocatedepot`, `RelocationTestPkg1–4` | Depot relocatability |

Useful invocations:

```bash
make test                 # core tests
make testall              # everything
make test-Dates           # a single stdlib's tests (pattern: test-<Name>)
make -C test embedding    # the embedding suite
```

> [!TIP]
> The Revise-based flow (`make test ... revise=true`, `make revise-<group>`) lets you re-test changes without rebuilding the system image.

---

## 15. Troubleshooting (Build & Deploy)

### Error: bootstrap fails building the system image

- **Cause:** accumulated Base changes broke the bootstrap, or stale dependency builds.
- **Solution:** `make clean && make`; if it persists, `make cleanall && make`. The build prints exactly this hint on such failures.
- **Prevention:** rebuild after large `git pull`s; avoid mixing incompatible dependency versions.

### Error: `library not found for -lcrt1.10.6.o` (macOS)

- **Cause:** missing/outdated Xcode command-line tools after a macOS update.
- **Solution:** `xcode-select --install`.
- **Prevention:** reinstall the CLT after OS upgrades.

### Error: `CMake Error: ... CMakeCache.txt directory ... is different ...`

- **Cause:** the source directory was moved after a dependency was configured.
- **Solution:** delete the offending dependency under `deps/` so it reconfigures.
- **Prevention:** don't relocate the source tree mid-build; use out-of-tree builds (`O=`) for movable build dirs.

### Problem: the build fails immediately with cryptic make errors

- **Cause:** a parent directory of the build tree contains a space or a shell metacharacter (`$`, `:`).
- **Solution:** move the source tree to a path with none of those characters.
- **Prevention:** keep build paths simple and ASCII.

### Problem: build cannot reach the network

- **Cause:** default BinaryBuilder dependency downloads are blocked.
- **Solution:** set `USE_BINARYBUILDER=0` in `Make.user` to build dependencies from source, or pre-seed `deps/srccache`.
- **Prevention:** for air-gapped CI, bake a `Make.user` with `USE_BINARYBUILDER=0` and a populated srccache.

### Problem: cached code keeps regenerating in production

- **Cause:** launch flags affecting codegen (`-O`, `-g`, `--check-bounds`) vary between runs, or the depot is read-only.
- **Solution:** pin one launch command; for read-only roots use `--compiled-modules=existing --pkgimages=existing` and a writable `JULIA_DEPOT_PATH`.
- **Prevention:** treat the launch command as part of the deployment artifact.

### Problem: a custom/trimmed binary throws at runtime

- **Cause:** `--trim=unsafe`/`unsafe-warn` removed code reached via a dynamic call site.
- **Solution:** rebuild with `--trim=safe` to surface the offending sites at compile time, or mark the needed entry points.
- **Prevention:** validate trimmed binaries against a representative workload before release.

### Problem: third-party native libraries fail to load alongside Julia (Linux)

- **Cause:** libstdc++ version mismatch between the bundled and system copies.
- **Solution:** Julia's loader probes for and prefers a newer system libstdc++ automatically; control it with `JULIA_PROBE_LIBSTDCXX` (`1`/`0`).
- **Prevention:** ensure the system libstdc++ is current, or disable probing for fully hermetic loading.

### Problem: GC waits forever / want to attach a debugger on a GC crash

- **Cause:** `JULIA_GC_WAIT_FOR_DEBUGGER` is set, but it only works on a GC-debug build.
- **Solution:** build with `WITH_GC_DEBUG_ENV=1`; then set the variable and attach your debugger.

---

## 16. Potential Improvements

Observations for maintainers and integrators, derived from the source layout:

- **First-call latency** remains the headline ergonomic cost of the JIT model. The trajectory (precompilation → pkgimages → `--trim`/`juliac` AOT) is clearly toward smaller, faster-starting artifacts; investing in custom system images is the most reliable operator-side mitigation today.
- **Dual GC** (`gc-stock.c` + `gc-mmtk.c`) signals an in-progress collector strategy; deployments sensitive to pause behavior should track which collector their build selects and benchmark both.
- **Optional codegen library** (`libjulia-codegen`) enables shipping run-only distributions (delete codegen to save space) — useful for locked-down or size-constrained deployments where new code generation is unnecessary.
- **CPU multi-versioning** is powerful but easy to misconfigure on heterogeneous clusters; documenting an organization-standard `JULIA_CPU_TARGET` per hardware tier avoids "illegal instruction" surprises.

---

## 17. Contributing

The project welcomes contributions from developers of all experience levels — bug fixes, documentation, tests, and performance work. New contributors should start with `CONTRIBUTING.md`.

> [!IMPORTANT]
> If a pull request contains substantial contributions from a generative AI tool, the project asks that you disclose this with details and review all changes before opening. This also applies to issues, discussions, and comments.

**Local workflow:**

```bash
git clone https://github.com/JuliaLang/julia.git
cd julia
make -j$(nproc)
make check-whitespace      # gate your change passes whitespace policy
make testall               # or a targeted test group, e.g. make test-strings
```

Documentation is built with Documenter.jl: `make docs` (HTML into `doc/_build/`), and doctests run via `make -C doc doctest=true`.

---

## 18. Quick Reference

### 18.1 Build commands

| Command | Purpose |
|---|---|
| `make` / `make -j N` | Build (parallel) |
| `make debug` / `make release` | Build a specific runtime variant |
| `make install` (with `prefix=` in `Make.user`) | Install |
| `make testall` | Run the full test suite |
| `make test-<Name>` | Run one test group / stdlib |
| `make docs` | Build the HTML manual |
| `make clean` / `make cleanall` | Clean (light / deep) |
| `make binary-dist` | Produce a binary distribution |
| `make print-<VAR>` | Print a build variable |
| `make -C deps clean-<dep>` | Rebuild one dependency |

### 18.2 Key build variables (`Make.user`)

| Variable | Purpose |
|---|---|
| `prefix=<dir>` | Install location |
| `USE_BINARYBUILDER=0` | Build deps from source (air-gapped) |
| `JULIA_CPU_TARGET=<targets>` | Baked-in CPU multi-versioning |
| `O=<dir>` (cmdline) | Out-of-tree build dir |
| `WITH_GC_DEBUG_ENV=1` | Enable GC-debug env hooks |
| `USE_*_JITEVENTS=1` | JIT-profiling integration |

### 18.3 Runtime libraries

| Library | Role |
|---|---|
| `julia` (loader) | Locates and loads the runtime, jumps to `jl_repl_entrypoint` |
| `libjulia` | Public shared library (embedding target) |
| `libjulia-internal` | The runtime: types, dispatch, GC, tasks, sysimage |
| `libjulia-codegen` | LLVM code generation (optional; falls back to internal) |
| `libjulia-debug` / `julia-debug` | Debug-build variants |

### 18.4 Source map (where to look)

| To understand… | Read… |
|---|---|
| Launch/loading | `cli/loader_exe.c`, `cli/loader_lib.c` |
| Option parsing | `src/jloptions.c`, `src/jloptions.h` |
| Embedding API | `src/jlapi.c`, `src/julia.h` |
| Codegen / JIT | `src/codegen.cpp`, `src/jitlayers.cpp`, `src/aotcompile.cpp` |
| Type system / dispatch | `src/jltypes.c`, `src/subtype.c`, `src/gf.c`, `src/method.c` |
| GC | `src/gc-stock.c`, `src/gc-mmtk.c` |
| Tasks / threads | `src/task.c`, `src/threading.c` |
| System image | `src/staticdata.c` |
| CLI reference | `doc/man/julia.1`, `doc/src/manual/command-line-interface.md` |
| Env-var reference | `doc/src/manual/environment-variables.md` |
| Build instructions | `README.md`, `doc/src/devdocs/build/build.md` |

### 18.5 Official resources

| Resource | URL |
|---|---|
| Homepage | <https://julialang.org> |
| Documentation | <https://docs.julialang.org> |
| Install | <https://julialang.org/install/> |
| Packages / Pkg docs | <https://julialang.org/packages/> · <https://pkgdocs.julialang.org> |
| Source | <https://github.com/JuliaLang/julia> |
| Issues | <https://github.com/JuliaLang/julia/issues> |
| Discourse / Zulip / Slack | linked from <https://julialang.org> |

---

_Generated June 2026 from JuliaLang/julia at 2614585. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
