Deploy the environment using the command, the command will download a static php-cli binary from [self-hosted server](https://dl.static-php.dev/static-php-cli/).
Next, it will automatically download Composer from [getcomposer](https://getcomposer.org/download/latest-stable/composer.phar) or [Aliyun mirror](https://mirrors.aliyun.com/composer/composer.phar).
# [macOS], need install Homebrew first. See https://brew.sh/
# Remember change your composer executable path. For M1/M2 Chip mac, "/opt/homebrew/bin/", for Intel mac, "/usr/local/bin/". Or add it to your own path.
Using `bin/spc craft`, you can use a configuration file and a command to automatically check the environment, download source code, build dependency libraries, build PHP and extensions, etc.
You need to write a `craft.yml` file and save it in the current working directory. `craft.yml` can be generated by [command generator](./cli-generator) or written manually.
For manual writing, please refer to the comments in [craft.yml configuration](../develop/craft-yml.md) to write it.
Let's assume that you compile an extension combination and choose PHP 8.4, outputting `cli` and `fpm`:
If the build is successful, you will see the `buildroot/bin` directory in the current directory, which contains the compiled PHP binary file, or the corresponding SAPI.
- cli: The build result is `buildroot/bin/php.exe` on Windows and `buildroot/bin/php` on other platforms.
- fpm: The build result is `buildroot/bin/php-fpm`.
- micro: The build result is `buildroot/bin/micro.sfx`. If you need to further package it with PHP code, please refer to [Packaging micro binary](./manual-build#command-micro-combine).
- embed: See [Using embed](./manual-build#embed-usage).
If the build fails, you can use the `--debug` parameter to view detailed error information,
or use the `--with-clean` to clear the old compilation results and recompile.
If the build still fails to use the above method, please submit an issue and attach your `craft.yml` and `craft.log`.
## Step-by-step build command
If you have customized requirements, or the need to download and compile PHP and dependent libraries separately, you can use the `bin/spc` command to execute step by step.
If you can run `bin/spc` normally but cannot compile static PHP or dependent libraries normally,
you can run `bin/spc doctor` first to check whether the system itself lacks dependencies.
```bash
# Quick check
bin/spc doctor
# Quickly check and fix when it can be automatically repaired (use package management to install dependent packages, only support the above-mentioned operating systems and distributions)
If you need to repeatedly build and debug, you can delete the `buildroot/` and `source/` directories so that you can re-extract and build all you need from the downloaded source code package:
During the compilation process, in some special cases,
the compiler and the content of the compilation directory need to be intervened.
You can try to use the following commands:
-`--cc=XXX`: Specifies the execution command of the C language compiler (Linux default `musl-gcc` or `gcc`, macOS default `clang`)
-`--cxx=XXX`: Specifies the execution command of the C++ language compiler (Linux defaults to `g++`, macOS defaults to `clang++`)
-`--with-clean`: clean up old make files before compiling PHP
-`--enable-zts`: Make compiled PHP thread-safe version (default is NTS version)
-`--no-strip`: Do not run `strip` after compiling the PHP library to trim the binary file to reduce its size (the macOS binary file without trim can use dynamically linked third-party extensions)
-`--with-libs=XXX,YYY`: Compile the specified dependent library before compiling PHP, and activate some extended optional functions (such as libavif of the gd library, etc.)
-`--with-config-file-path=XXX`: Set the path in which to look for `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
-`--with-config-file-scan-dir=XXX`: Set the directory to scan for `.ini` files after reading `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
-`-I xxx=yyy`: Hard compile INI options into PHP before compiling (support multiple options, alias is `--with-hardcoded-ini`)
-`--with-micro-fake-cli`: When compiling micro, let micro's `PHP_SAPI` pretend to be `cli` (for compatibility with some programs that check `PHP_SAPI`)
-`--disable-opcache-jit`: Disable opcache jit (enabled by default)
-`-P xxx.php`: Inject external scripts during static-php-cli compilation (see **Inject external scripts** below for details)
-`--without-micro-ext-test`: After building micro.sfx, do not test the running results of different extensions in micro.sfx
-`--with-suggested-exts`: Add `ext-suggests` as dependencies when compiling
-`--with-suggested-libs`: Add `lib-suggests` as dependencies when compiling
-`--with-upx-pack`: Use UPX to reduce the size of the binary file after compilation (you need to use `bin/spc install-pkg upx` to install upx first)
For hardcoding INI options, it works for cli, micro, embed sapi. Here is a simple example where we preset a larger `memory_limit` and disable the `system` function:
Use the `micro:combine` command to build the compiled `micro.sfx` and your code (`.php` or `.phar` file) into an executable binary.
You can also use this command to directly build a micro binary injected with ini configuration.
::: tip
Injecting ini configuration refers to adding a special structure after micro.sfx to save ini configuration items before combining micro.sfx with PHP source code.
micro.sfx can identify the INI file header through a special byte, and the micro can be started with INI through the INI file header.
The original wiki of this feature is in [phpmicro - Wiki](https://github.com/easysoft/phpmicro/wiki/INI-settings), and this feature may change in the future.
:::
The following is the general usage, directly packaging the php source code into a file:
```bash
# Before doing the packaging process, you should use `build --build-micro` to compile micro.sfx
echo "<?php echo 'hello';" > a.php
bin/spc micro:combine a.php
# Just use it
./my-app
```
You can use the following options to specify the file name to be output, and you can also specify micro.sfx in other paths for packaging.
```bash
# specify the output filename
bin/spc micro:combine a.php --output=custom-bin
# Use absolute path
bin/spc micro:combine a.php -O /tmp/my-custom-app
# Specify micro.sfx in other locations for packaging
If you want to inject ini configuration items, you can use the following parameters to add ini to the executable file from a file or command line option.
```bash
# Specified using command-line options (-I is shorthand for --with-ini-set)
bin/spc micro:combine a.php -I "a=b" -I "foo=bar"
# Use ini file specification (-N is shorthand for --with-ini-file)
Note, please do not directly use the PHP source code or the `php.ini` file in the system-installed PHP,
it is best to manually write an ini configuration file that you need, for example:
```ini
; custom.ini
curl.cainfo=/path/to/your/cafile.pem
memory_limit=1G
```
The ini injection of this command is achieved by appending a special structure after micro.sfx,
which is different from the function of inserting hard-coded INI during compilation.
:::
If you want to package phar, just replace `a.php` with the packaged phar file.
But please note that micro.sfx under phar needs extra attention to the path problem, see [Developing - Phar directory issue](../develop/structure#phar-application-directory-issue).
## Command - extract
Use the command `bin/spc extract` to unpack and copy the source code required for compilation,
including php-src and the source code of various dependent libraries (you need to specify the name of the library to be unpacked).
For example, after we have downloaded sources, we want to distribute and execute the build process,
manually unpack and copy the package to a specified location, and we can use commands.
```bash
# Unzip the downloaded compressed package of php-src and libxml2, and store the decompressed source code in the source directory
It should be noted that the project directory must contain the `vendor/installed.json` and `composer.lock` files, otherwise they cannot be found normally.
# You need to decompress the downloaded PHP source code to the source directory first
# You can use `bin/spc extract php-src` to decompress the source code separately
bin/spc dev:php-version
# Sort the configuration files in the config/ directory in alphabetical order (e.g. ext.json)
bin/spc dev:sort-config ext
```
## Command - install-pkg
Use the command `bin/spc install-pkg` to download some precompiled or closed source tools and install them into the `pkgroot` directory.
When `bin/spc doctor` automatically repairs the Windows environment, tools such as nasm and perl will be downloaded, and the installation process of `install-pkg` will also be used.
Here is an example of installing the tool:
- Download and install UPX (Linux and Windows only): `bin/spc install-pkg upx`
## Command - del-download
In some cases, you need to delete single or multiple specified download source files and re-download them, such as switching PHP versions.
The `bin/spc del-download` command is provided after the `2.1.0-beta.4` version. Specified source files can be deleted.
Deletes downloaded source files containing precompiled packages and source code named as keys in `source.json` or `pkg.json`. Here are some examples:
- Delete the old PHP source code and switch to download the 8.3 version: `bin/spc del-download php-src && bin/spc download php-src --with-php=8.3`
- Delete the download file of redis extension: `bin/spc del-download redis`
- Delete the downloaded musl-toolchain x86_64: `bin/spc del-download musl-toolchain-x86_64-linux`
## Inject External Script
Injecting external scripts refers to inserting one or more scripts during the static-php-cli compilation process
to more flexibly support parameter modifications and source code patches in different environments.
Under normal circumstances, this function mainly solves the problem that the patch cannot be modified
by modifying the static-php-cli code when compiling with `spc` binary.
There is another situation: your project directly depends on the `crazywhalecc/static-php-cli` repository and is synchronized with main branch,
but some proprietary modifications are required, and these feature are not suitable for merging into the main branch.
In view of the above situation, in the official version 2.0.0, static-php-cli has added multiple event trigger points.
You can write an external `xx.php` script and pass it in through the command line parameter `-P` and execute.
When writing to inject external scripts, the methods you will use are `builder()` and `patch_point()`.
Among them, `patch_point()` obtains the name of the current event, and `builder()` obtains the BuilderBase object.
Because the incoming patch point does not distinguish between events,
you must write the code you want to execute in `if(patch_point() === 'your_event_name')`,
otherwise it will be executed repeatedly in other events.
The following are the supported `patch_point` event names and corresponding locations:
For the objects, methods and interfaces supported by static-php-cli, you can read the source code. Most methods and objects have corresponding comments.
Commonly used objects and functions using the `-P` function are:
If you need to build multiple times locally, the following method can save you time downloading resources and compiling.
- If you only switch the PHP version without changing the dependent libraries, you can use `bin/spc switch-php-version` to quickly switch the PHP version, and then re-run the same `build` command.
- If you want to rebuild once, but do not re-download the source code, you can first `rm -rf buildroot source` to delete the compilation directory and source code directory, and then rebuild.
- If you want to update a version of a dependency, you can use `bin/spc del-download <source-name>` to delete the specified source code, and then use `download <source-name>` to download it again.
- If you want to update all dependent versions, you can use `bin/spc download --clean` to delete all downloaded sources, and then download them again.