import{_ as s,c as a,o as e,aj as t}from"./chunks/framework.C2AwuPrQ.js";const k=JSON.parse('{"title":"Your First Build","description":"","frontmatter":{},"headers":[],"relativePath":"en/guide/first-build.md","filePath":"en/guide/first-build.md"}'),n={name:"en/guide/first-build.md"};function l(h,i,d,p,o,r){return e(),a("div",null,[...i[0]||(i[0]=[t(`

Your First Build

This page walks you through building a static PHP binary from scratch, end to end.

TIP

If you installed spc as a pre-built binary, replace every spc in this page with ./spc (or .\\spc.exe on Windows).

If you installed from source, use bin/spc instead.

Two Approaches

StaticPHP supports two build workflows — pick the one that fits your situation:

ApproachWhen to use
craft (one-shot)Everyday use, getting started quickly
Step-by-stepFine-grained control over the build pipeline

The craft command reads a craft.yml file and handles everything automatically — downloading dependencies, compiling libraries, and building PHP — in a single run.

Write craft.yml

Create a craft.yml in your working directory and declare the PHP version, extensions, and target SAPIs:

yaml
php-version: 8.5
extensions: bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer
sapi:
  - cli
  - micro

Not sure which extensions you need? Use the command generator to produce a craft.yml automatically.

Run the Build

bash
spc craft

The build pipeline runs in order: download dependencies → compile libraries → compile PHP. No interaction required.

To see more detail, pass -v, -vv, or -vvv:

bash
spc craft -v

Inspect the Output

On success, binaries land in buildroot/bin/:

SAPIOutput path
clibuildroot/bin/php (Windows: buildroot/bin/php.exe)
fpmbuildroot/bin/php-fpm
microbuildroot/bin/micro.sfx
embedbuildroot/lib/libphp.a
frankenphpbuildroot/bin/frankenphp

Give the CLI binary a quick smoke-test:

bash
./buildroot/bin/php -v
./buildroot/bin/php -m

Option 2: Step-by-Step Build

This approach lets you run download and compile as separate steps — useful when you want to cache downloads in CI and reuse them across builds.

Step 1: Download Dependencies

In v3, you can skip this step entirely — running build:php directly will automatically download any missing artifacts.

If you want to pre-download ahead of time, or if you're working in a slow-network environment and want to separate the download phase, use the download command:

bash
# Download only what the chosen extensions need (recommended)
spc download --for-extensions="bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer" --with-php=8.5

# Download by specific package names
spc download "curl,openssl" --with-php=8.5

Downloads are cached in downloads/ and reused across builds automatically.

bash
# Slow connection? Increase parallelism and retries
spc download --for-extensions="bcmath,openssl,curl" --parallel 10 --retry=3

# Use pre-built binaries where available — skips compiling those dependencies
spc download --for-extensions="bcmath,openssl,curl" --prefer-binary

Step 2: Build PHP

bash
# Build the cli SAPI
spc build:php "bcmath,phar,zlib,openssl,curl,fileinfo,tokenizer" --build-cli

# Build multiple SAPIs in one go
spc build:php "bcmath,phar,zlib,openssl,curl" --build-cli --build-micro

Common Build Options

OptionDescription
--build-cliBuild the cli SAPI
--build-fpmBuild php-fpm (not available on Windows)
--build-microBuild micro.sfx
--build-embedBuild the embed SAPI
--build-frankenphpBuild FrankenPHP
--enable-ztsEnable thread-safe (ZTS) mode
--no-stripKeep debug symbols; do not strip the binary
-I key=valueHard-compile an INI option into PHP
--with-upx-packCompress output with UPX (run spc install-pkg upx first)

Example — baking in a larger memory limit and disabling the system function:

bash
spc build:php "bcmath,pcntl,posix" --build-cli -I "memory_limit=4G" -I "disable_functions=system"

Packaging a micro App

Once you have micro.sfx, use micro:combine to bundle your PHP code into a single self-contained executable:

bash
echo "<?php echo 'Hello, World!' . PHP_EOL;" > hello.php
spc micro:combine hello.php --output=hello
./hello

Works with .phar files too, and you can inject INI settings at packaging time:

bash
# Bundle a phar
spc micro:combine your-app.phar --output=your-app

# Inject INI via command-line options
spc micro:combine your-app.phar --output=your-app -I "memory_limit=512M"

# Inject INI from a file
spc micro:combine your-app.phar --output=your-app -N /path/to/custom.ini

Debugging and Rebuilding

If a build fails or you want to trace what's happening, use -v / -vv / -vvv:

bash
spc build:php "bcmath,openssl" --build-cli -vv

To wipe compiled artifacts and start fresh without re-downloading, run reset:

bash
spc reset
# Then rebuild
spc build:php "bcmath,openssl" --build-cli

TIP

reset only removes buildroot/ and source/. Your downloads/ cache is preserved. Add --with-download if you also want to clear the download cache.

If you're stuck, open an Issue and include your craft.yml (if any) and a zip of the log/ directory.

What's Next

`,51)])])}const u=s(n,[["render",l]]);export{k as __pageData,u as default};