mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-08 17:35:36 +08:00
Temp
This commit is contained in:
@@ -1,63 +1,5 @@
|
||||
# Contributing
|
||||
|
||||
Thank you for being here, this project welcomes your contributions!
|
||||
|
||||
## Contribution Guide
|
||||
|
||||
If you have code or documentation to contribute, here's what you need to know first.
|
||||
|
||||
1. What type of code are you contributing? (new extensions, bug fixes, security issues, project framework optimizations, documentation)
|
||||
2. If you contribute new files or new snippets, is your code checked by `php-cs-fixer` and `phpstan`?
|
||||
3. Have you fully read the [Developer Guide](../develop/) before contributing code?
|
||||
|
||||
If you can answer the above questions and have made changes to the code,
|
||||
you can initiate a Pull Request in the project GitHub repository in time.
|
||||
After the code review is completed, the code can be modified according to the suggestion, or directly merged into the main branch.
|
||||
|
||||
## Contribution Type
|
||||
|
||||
The main purpose of this project is to compile statically linked PHP binaries,
|
||||
and the command line processing function is written based on `symfony/console`.
|
||||
Before development, if you are not familiar with it,
|
||||
Check out the [symfony/console documentation](https://symfony.com/doc/current/components/console.html) first.
|
||||
|
||||
### Security Update
|
||||
|
||||
Because this project is basically a PHP project running locally, generally speaking, there will be no remote attacks.
|
||||
But if you find such a problem, please **DO NOT submit a PR or Issue in the GitHub repository,
|
||||
You need to contact the project maintainer (crazywhalecc) via [mail](mailto:admin@zhamao.me).
|
||||
|
||||
### Fix Bugs
|
||||
|
||||
Fixing bugs generally does not involve modification of the project structure and framework,
|
||||
so if you can locate the wrong code and fix it directly, please submit a PR directly.
|
||||
|
||||
### New Extensions
|
||||
|
||||
For adding a new extension,
|
||||
you need to understand some basic structure of the project and how to add a new extension according to the existing logic.
|
||||
It will be covered in detail in the next section on this page.
|
||||
In general, you will need:
|
||||
|
||||
1. Evaluate whether the extension can be compiled inline into PHP.
|
||||
2. Evaluate whether the extension's dependent libraries (if any) can be compiled statically.
|
||||
3. Write library compile commands on different platforms.
|
||||
4. Verify that the extension and its dependencies are compatible with existing extensions and dependencies.
|
||||
5. Verify that the extension works normally in `cli`, `micro`, `fpm`, `embed` SAPIs.
|
||||
6. Write documentation and add your extension.
|
||||
|
||||
### Project Framework Optimization
|
||||
|
||||
If you are already familiar with the working principle of `symfony/console`,
|
||||
and at the same time want to make some modifications or optimizations to the framework of the project,
|
||||
please understand the following things first:
|
||||
|
||||
1. Adding extensions does not belong to project framework optimization,
|
||||
but if you find that you have to optimize the framework when adding new extensions,
|
||||
you need to modify the framework itself before adding extensions.
|
||||
2. For some large-scale logical modifications (such as those involving LibraryBase, Extension objects, etc.),
|
||||
it is recommended to submit an Issue or Draft PR for discussion first.
|
||||
3. In the early stage of the project, it was a pure private development project, and there were some Chinese comments in the code.
|
||||
After internationalizing your project you can submit a PR to translate these comments into English.
|
||||
4. Please do not submit more useless code fragments in the code,
|
||||
such as a large number of unused variables, methods, classes, and code that has been rewritten many times.
|
||||
<!-- TODO: v3 contribution guide.
|
||||
Sections: code style (php-cs-fixer, phpstan), adding a new library/extension,
|
||||
adding a doctor check, submitting PRs, security disclosures. -->
|
||||
|
||||
6
docs/en/develop/build-lifecycle.md
Normal file
6
docs/en/develop/build-lifecycle.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Build Lifecycle
|
||||
|
||||
<!-- TODO: Describe the full build pipeline stage sequence.
|
||||
When each hook fires: #[BeforeStage], #[AfterStage], #[PatchBeforeBuild].
|
||||
How platform selection (#[BuildFor]) works at runtime.
|
||||
Diagram of stage order for a typical library and extension build. -->
|
||||
@@ -4,4 +4,4 @@ aside: false
|
||||
|
||||
# craft.yml Configuration
|
||||
|
||||
<!--@include: ../../deps-craft-yml.md-->
|
||||
<!-- TODO: Full reference for craft.yml fields. -->
|
||||
|
||||
@@ -1,70 +1,4 @@
|
||||
# Doctor module
|
||||
# Doctor Module
|
||||
|
||||
The Doctor module is a relatively independent module used to check the system environment, which can be entered with the command `bin/spc doctor`, and the entry command class is in `DoctorCommand.php`.
|
||||
|
||||
The Doctor module is a checklist with a series of check items and automatic repair items.
|
||||
These items are stored in the `src/SPC/doctor/item/` directory,
|
||||
And two Attributes are used as check item tags and auto-fix item tags: `#[AsCheckItem]` and `#[AsFixItem]`.
|
||||
|
||||
Take the existing check item `if necessary tools are installed`,
|
||||
which is used to check whether the packages necessary for compilation are installed in the macOS system.
|
||||
The following is its source code:
|
||||
|
||||
```php
|
||||
use SPC\doctor\AsCheckItem;
|
||||
use SPC\doctor\AsFixItem;
|
||||
use SPC\doctor\CheckResult;
|
||||
|
||||
#[AsCheckItem('if necessary tools are installed', limit_os: 'Darwin', level: 997)]
|
||||
public function checkCliTools(): ?CheckResult
|
||||
{
|
||||
$missing = [];
|
||||
foreach (self::REQUIRED_COMMANDS as $cmd) {
|
||||
if ($this->findCommand($cmd) === null) {
|
||||
$missing[] = $cmd;
|
||||
}
|
||||
}
|
||||
if (!empty($missing)) {
|
||||
return CheckResult::fail('missing system commands: ' . implode(', ', $missing), 'build-tools', [$missing]);
|
||||
}
|
||||
return CheckResult::ok();
|
||||
}
|
||||
```
|
||||
|
||||
The first parameter of the attribute is the name of the check item,
|
||||
and the following `limit_os` parameter restricts the check item to be triggered only under the specified system,
|
||||
and `level` is the priority of executing the check item, the larger the number, the higher the priority higher.
|
||||
|
||||
The `$this->findCommand()` method used in it is the method of `SPC\builder\traits\UnixSystemUtilTrait`,
|
||||
the purpose is to find the location of the system command, and return NULL if it cannot be found.
|
||||
|
||||
Each check item method should return a `SPC\doctor\CheckResult`:
|
||||
|
||||
- When returning `CheckResult::fail()`, the first parameter is used to output the error prompt of the terminal,
|
||||
and the second parameter is the name of the repair item when this check item can be automatically repaired.
|
||||
- When `CheckResult::ok()` is returned, the check passed. You can also pass a parameter to return the check result, for example: `CheckResult::ok('OS supported')`.
|
||||
- When returning `CheckResult::fail()`, if the third parameter is included, the array of the third parameter will be used as the parameter of `AsFixItem`.
|
||||
|
||||
The following is the method for automatically repairing items corresponding to this check item:
|
||||
|
||||
```php
|
||||
#[AsFixItem('build-tools')]
|
||||
public function fixBuildTools(array $missing): bool
|
||||
{
|
||||
foreach ($missing as $cmd) {
|
||||
try {
|
||||
shell(true)->exec('brew install ' . escapeshellarg($cmd));
|
||||
} catch (RuntimeException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
`#[AsFixItem()]` first parameter is the name of the fix item, and this method must return True or False.
|
||||
When False is returned, the automatic repair failed and manual handling is required.
|
||||
|
||||
In the code here, `shell()->exec()` is the method of executing commands of the project,
|
||||
which is used to replace `exec()` and `system()`, and also provides debugging, obtaining execution status,
|
||||
entering directories, etc. characteristic.
|
||||
<!-- TODO: Migrate and update from v2 doctor-module.md.
|
||||
Cover v3 changes: --auto-fix, .spc-doctor.lock, new check items for v3 toolchain. -->
|
||||
|
||||
@@ -1,35 +1,4 @@
|
||||
# Start Developing
|
||||
|
||||
Developing this project requires the installation and deployment of a PHP environment,
|
||||
as well as some extensions and Composer commonly used in PHP projects.
|
||||
|
||||
The development environment and running environment of the project are almost exactly the same.
|
||||
You can refer to the **Manual Build** section to install system PHP or use the pre-built static PHP of this project as the environment.
|
||||
I will not go into details here.
|
||||
|
||||
Regardless of its purpose, this project itself is actually a `php-cli` program. You can edit and develop it as a normal PHP project.
|
||||
At the same time, you need to understand the Shell languages of different systems.
|
||||
|
||||
The current purpose of this project is to compile statically compiled independent PHP,
|
||||
but the main part also includes compiling static versions of many dependent libraries,
|
||||
so you can reuse this set of compilation logic to build independent binary versions of other programs, such as Nginx, etc.
|
||||
|
||||
## Environment preparation
|
||||
|
||||
A PHP environment is required to develop this project. You can use the PHP that comes with the system,
|
||||
or you can use the static PHP built by this project.
|
||||
|
||||
Regardless of which PHP you use, in your development environment you need to install these extensions:
|
||||
|
||||
```
|
||||
curl,dom,filter,mbstring,openssl,pcntl,phar,posix,sodium,tokenizer,xml,xmlwriter
|
||||
```
|
||||
|
||||
The static-php-cli project itself does not require so many extensions, but during the development process,
|
||||
you will use tools such as Composer and PHPUnit, which require these extensions.
|
||||
|
||||
> For micro self-executing binaries built by static-php-cli itself, only `pcntl,posix,mbstring,tokenizer,phar` is required.
|
||||
|
||||
## Start development
|
||||
|
||||
Continuing down to see the project structure documentation, you can learn how `static-php-cli` works.
|
||||
<!-- TODO: Developer introduction, environment setup, required PHP extensions.
|
||||
Link to Vendor Mode for library authors, and Contributing for code contributors. -->
|
||||
|
||||
6
docs/en/develop/package-model.md
Normal file
6
docs/en/develop/package-model.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Package Model
|
||||
|
||||
<!-- TODO: Explain the unified package model: library / php-extension / target types.
|
||||
Cover the per-package YAML format (config/pkg/), the `depends` field,
|
||||
platform overrides (@windows / @unix notation), artifact.source and artifact.binary.
|
||||
Show annotated example YAML for a library and an extension. -->
|
||||
@@ -1,59 +1,4 @@
|
||||
# Modifications to PHP source code
|
||||
# PHP Source Modifications
|
||||
|
||||
During the static compilation process, static-php-cli made some modifications to the PHP source code
|
||||
in order to achieve good compatibility, performance, and security.
|
||||
The following is a description of the current modifications to the PHP source code.
|
||||
|
||||
## Micro related patches
|
||||
|
||||
Based on the patches provided by the phpmicro project,
|
||||
static-php-cli has made some modifications to the PHP source code to meet the needs of static compilation.
|
||||
The patches currently used by static-php-cli during compilation in the [patch list](https://github.com/easysoft/phpmicro/tree/master/patches) are:
|
||||
|
||||
- static_opcache
|
||||
- static_extensions_win32
|
||||
- cli_checks
|
||||
- disable_huge_page
|
||||
- vcruntime140
|
||||
- win32
|
||||
- zend_stream
|
||||
- cli_static
|
||||
- macos_iconv
|
||||
- phar
|
||||
|
||||
## PHP <= 8.1 libxml patch
|
||||
|
||||
Because PHP only provides security updates for 8.1 and stops updating older versions,
|
||||
static-php-cli applies the libxml compilation patch that has been applied in newer versions of PHP to PHP 8.1 and below.
|
||||
|
||||
## gd extension Windows patch
|
||||
|
||||
Compiling the gd extension under Windows requires major changes to the `config.w32` file.
|
||||
static-php-cli has made some changes to the gd extension to make it easier to compile under Windows.
|
||||
|
||||
## YAML extension Windows patch
|
||||
|
||||
YAML extension needs to modify the `config.w32` file to compile under Windows.
|
||||
static-php-cli has made some modifications to the YAML extension to make it easier to compile under Windows.
|
||||
|
||||
## static-php-cli version information insertion
|
||||
|
||||
When compiling, static-php-cli will insert the static-php-cli version information into the PHP version information for easy identification.
|
||||
|
||||
## Add option to hardcode INI
|
||||
|
||||
When using the `-I` parameter to hardcode INI into static PHP functionality,
|
||||
static-php-cli will modify the PHP source code to insert the hardcoded content.
|
||||
|
||||
## Linux system repair patch
|
||||
|
||||
Some compilation environments may lack some system header files or libraries.
|
||||
static-php-cli will automatically fix these problems during compilation, such as:
|
||||
|
||||
- HAVE_STRLCAT missing problem
|
||||
- HAVE_STRLCPY missing problem
|
||||
|
||||
## Fiber issue fix patch for Windows
|
||||
|
||||
When compiling PHP on Windows, there will be some issues with the Fiber extension.
|
||||
static-php-cli will automatically fix these issues during compilation (modify `config.w32` in php-src).
|
||||
<!-- TODO: Migrate and update from v2 php-src-changes.md.
|
||||
Add v3-specific patches (FrankenPHP embed, Windows fiber fix, etc.). -->
|
||||
|
||||
6
docs/en/develop/registry.md
Normal file
6
docs/en/develop/registry.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Registry & Plugin System
|
||||
|
||||
<!-- TODO: Explain spc.registry.yml structure.
|
||||
How to add an external registry via SPC_REGISTRIES env var.
|
||||
Vendor-specific configurations, overriding core packages.
|
||||
Registry resolution order and conflict rules. -->
|
||||
@@ -1,372 +1,5 @@
|
||||
# Source module
|
||||
# Source Module
|
||||
|
||||
The download source module of static-php-cli is a major module.
|
||||
It includes dependent libraries, external extensions, PHP source code download methods and file decompression methods.
|
||||
The download configuration file mainly involves the `source.json` and `pkg.json` file, which records the download method of all downloadable sources.
|
||||
|
||||
The main commands involved in the download function are `bin/spc download` and `bin/spc extract`.
|
||||
The `download` command is a downloader that downloads sources according to the configuration file,
|
||||
and the `extract` command is an extractor that extract sources from downloaded files.
|
||||
|
||||
Generally speaking, downloading sources may be slow because these sources come from various official websites, GitHub,
|
||||
and other different locations.
|
||||
At the same time, they also occupy a large space, so you can download the sources once and reuse them.
|
||||
|
||||
The configuration file of the downloader is `source.json`, which contains the download methods of all sources.
|
||||
You can add the source download methods you need, or modify the existing source download methods.
|
||||
|
||||
The download configuration structure of each source is as follows.
|
||||
The following is the source download configuration corresponding to the `libevent` extension:
|
||||
|
||||
```json
|
||||
{
|
||||
"libevent": {
|
||||
"type": "ghrel",
|
||||
"repo": "libevent/libevent",
|
||||
"match": "libevent.+\\.tar\\.gz",
|
||||
"provide-pre-built": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The most important field here is `type`. Currently, the types it supports are:
|
||||
|
||||
- `url`: Directly use URL to download, for example: `https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz`.
|
||||
- `pie`: Download PHP extensions from Packagist using the PIE (PHP Installer for Extensions) standard.
|
||||
- `ghrel`: Use the GitHub Release API to download, download the artifacts uploaded from the latest version released by maintainers.
|
||||
- `ghtar`: Use the GitHub Release API to download.
|
||||
Different from `ghrel`, `ghtar` is downloaded from the `source code (tar.gz)` in the latest Release of the project.
|
||||
- `ghtagtar`: Use GitHub Release API to download.
|
||||
Compared with `ghtar`, `ghtagtar` can find the latest one from the `tags` list and download the source code in `tar.gz` format
|
||||
(because some projects only use `tag` release version).
|
||||
- `bitbuckettag`: Download using BitBucket API, basically the same as `ghtagtar`, except this one applies to BitBucket.
|
||||
- `git`: Clone the project directly from a Git address to download sources, applicable to any public Git repository.
|
||||
- `filelist`: Use a crawler to crawl the Web download site that provides file index,
|
||||
and get the latest version of the file name and download it.
|
||||
- `custom`: If none of the above download methods are satisfactory, you can write `custom`,
|
||||
create a new class under `src/SPC/store/source/`, extends `CustomSourceBase`, and write the download script yourself.
|
||||
|
||||
## source.json Common parameters
|
||||
|
||||
Each source file in source.json has the following params:
|
||||
|
||||
- `license`: the open source license of the source code, see **Open Source License** section below
|
||||
- `type`: must be one of the types mentioned above
|
||||
- `path` (optional): release the source code to the specified directory instead of `source/{name}`
|
||||
- `provide-pre-built` (optional): whether to provide precompiled binary files.
|
||||
If `true`, it will automatically try to download precompiled binary files when running `bin/spc download`
|
||||
|
||||
::: tip
|
||||
The `path` parameter in `source.json` can specify a relative or absolute path. When specified as a relative path, the path is based on `source/`.
|
||||
:::
|
||||
|
||||
## Download type - url
|
||||
|
||||
URL type sources refer to downloading files directly from the URL.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `url`: The download address of the file, such as `https://example.com/file.tgz`
|
||||
- `filename` (optional): The file name saved to the local area. If not specified, the file name of the url will be used.
|
||||
|
||||
Example (download the imagick extension and extract it to the extension storage path of the php source code):
|
||||
|
||||
```json
|
||||
{
|
||||
"ext-imagick": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/imagick",
|
||||
"path": "php-src/ext/imagick",
|
||||
"filename": "imagick.tgz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Download type - pie
|
||||
|
||||
PIE (PHP Installer for Extensions) type sources refer to downloading PHP extensions from Packagist that follow the PIE standard.
|
||||
This method automatically fetches extension information from the Packagist repository and downloads the appropriate distribution file.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `repo`: The Packagist vendor/package name, such as `vendor/package-name`
|
||||
|
||||
Example (download a PHP extension from Packagist using PIE):
|
||||
|
||||
```json
|
||||
{
|
||||
"ext-example": {
|
||||
"type": "pie",
|
||||
"repo": "vendor/example-extension",
|
||||
"path": "php-src/ext/example",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: tip
|
||||
The PIE download type will automatically detect the extension information from Packagist metadata,
|
||||
including the download URL, version, and distribution type.
|
||||
The extension must be marked as `type: php-ext` or contain `php-ext` metadata in its Packagist package definition.
|
||||
:::
|
||||
|
||||
## Download type - ghrel
|
||||
|
||||
ghrel will download files from Assets uploaded in GitHub Release.
|
||||
First use the GitHub Release API to get the latest version, and then download the corresponding files according to the regular matching method.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `repo`: GitHub repository name
|
||||
- `match`: regular expression matching Assets files
|
||||
- `prefer-stable`: Whether to download stable versions first (default is `false`)
|
||||
|
||||
Example (download the libsodium library, matching the libsodium-x.y.tar.gz file in Release):
|
||||
|
||||
```json
|
||||
{
|
||||
"libsodium": {
|
||||
"type": "ghrel",
|
||||
"repo": "jedisct1/libsodium",
|
||||
"match": "libsodium-\\d+(\\.\\d+)*\\.tar\\.gz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Download type - ghtar
|
||||
|
||||
ghtar will download the file from the GitHub Release Tag.
|
||||
Unlike `ghrel`, `ghtar` will download the `source code (tar.gz)` from the latest Release of the project.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `repo`: GitHub repository name
|
||||
- `prefer-stable`: Whether to download stable versions first (default is `false`)
|
||||
|
||||
Example (brotli library):
|
||||
|
||||
```json
|
||||
{
|
||||
"brotli": {
|
||||
"type": "ghtar",
|
||||
"repo": "google/brotli",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Download type - ghtagtar
|
||||
|
||||
Use the GitHub Release API to download.
|
||||
Compared with `ghtar`, `ghtagtar` can find the latest one from the `tags` list and download the source code in `tar.gz` format
|
||||
(because some projects only use the `tag` version).
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `repo`: GitHub repository name
|
||||
- `prefer-stable`: Whether to download stable versions first (default is `false`)
|
||||
|
||||
Example (gmp library):
|
||||
|
||||
```json
|
||||
{
|
||||
"gmp": {
|
||||
"type": "ghtagtar",
|
||||
"repo": "alisw/GMP",
|
||||
"license": {
|
||||
"type": "text",
|
||||
"text": "EXAMPLE LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Download Type - bitbuckettag
|
||||
|
||||
Download using BitBucket API, basically the same as `ghtagtar`, except this one works with BitBucket.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `repo`: BitBucket repository name
|
||||
|
||||
## Download type - git
|
||||
|
||||
Clone the project directly from a Git address to download sources, applicable to any public Git repository.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `url`: Git link (HTTPS only)
|
||||
- `rev`: branch name
|
||||
|
||||
```json
|
||||
{
|
||||
"imap": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/static-php/imap.git",
|
||||
"rev": "master",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Download type - filelist
|
||||
|
||||
Use a crawler to crawl a web download site that provides a file index and get the latest version of the file name and download it.
|
||||
|
||||
Note that this method is only applicable to static sites with page index functions such as mirror sites and GNU official websites.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `url`: The URL of the page to crawl the latest version of the file
|
||||
- `regex`: regular expression matching file names and download links
|
||||
|
||||
Example (download the libiconv library from the GNU official website):
|
||||
|
||||
```json
|
||||
{
|
||||
"libiconv": {
|
||||
"type": "filelist",
|
||||
"url": "https://ftp.gnu.org/gnu/libiconv/",
|
||||
"regex": "/href=\"(?<file>libiconv-(?<version>[^\"]+)\\.tar\\.gz)\"/",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Download type - custom
|
||||
|
||||
If the above downloading methods are not satisfactory, you can write `custom`,
|
||||
create a new class under `src/SPC/store/source/`, extends `CustomSourceBase`, and write the download script yourself.
|
||||
|
||||
I won’t go into details here, you can look at `src/SPC/store/source/PhpSource.php` or `src/SPC/store/source/PostgreSQLSource.php` as examples.
|
||||
|
||||
## pkg.json General parameters
|
||||
|
||||
pkg.json stores non-source-code files, such as precompiled tools musl-toolchain and UPX. It includes:
|
||||
|
||||
- `type`: The same type as `source.json` and different kinds of parameters.
|
||||
- `extract` (optional): The path to decompress after downloading, the default is `pkgroot/{pkg_name}`.
|
||||
- `extract-files` (optional): Extract only the specified files to the specified location after downloading.
|
||||
|
||||
It should be noted that `pkg.json` does not involve compilation, modification and distribution of source code,
|
||||
so there is no `license` open source license field.
|
||||
And you cannot use the `extract` and `extract-files` parameters at the same time.
|
||||
|
||||
Example (download nasm locally and extract only program files to PHP SDK):
|
||||
|
||||
```json
|
||||
{
|
||||
"nasm-x86_64-win": {
|
||||
"type": "url",
|
||||
"url": "https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/nasm-2.16.01-win64.zip",
|
||||
"extract-files": {
|
||||
"nasm-2.16.01/nasm.exe": "{php_sdk_path}/bin/nasm.exe",
|
||||
"nasm-2.16.01/ndisasm.exe": "{php_sdk_path}/bin/ndisasm.exe"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The key name in `extract-files` is the file in the source folder, and the key value is the storage path. The storage path can use the following variables:
|
||||
|
||||
- `{php_sdk_path}`: (Windows only) PHP SDK path
|
||||
- `{pkg_root_path}`: `pkgroot/`
|
||||
- `{working_dir}`: current working directory
|
||||
- `{download_path}`: download directory
|
||||
- `{source_path}`: source code decompression directory
|
||||
|
||||
When `extract-files` does not use variables and is a relative path, the directory of the relative path is `{working_dir}`.
|
||||
|
||||
## Open source license
|
||||
|
||||
For `source.json`, each source file should contain an open source license.
|
||||
The `license` field stores the open source license information.
|
||||
|
||||
Each `license` contains the following parameters:
|
||||
|
||||
- `type`: `file` or `text`
|
||||
- `path`: the license file in the source code directory (required when `type` is `file`)
|
||||
- `text`: License text (required when `type` is `text`)
|
||||
|
||||
Example (yaml extension source code with LICENSE file):
|
||||
|
||||
```json
|
||||
{
|
||||
"yaml": {
|
||||
"type": "git",
|
||||
"path": "php-src/ext/yaml",
|
||||
"rev": "php7",
|
||||
"url": "https://github.com/php/pecl-file_formats-yaml",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When an open source project has multiple licenses, multiple files can be specified:
|
||||
|
||||
```json
|
||||
{
|
||||
"libuv": {
|
||||
"type": "ghtar",
|
||||
"repo": "libuv/libuv",
|
||||
"license": [
|
||||
{
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"path": "LICENSE-extra"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When the license of an open source project uses different files between versions,
|
||||
`path` can be used as an array to list the possible license files:
|
||||
|
||||
```json
|
||||
{
|
||||
"redis": {
|
||||
"type": "git",
|
||||
"path": "php-src/ext/redis",
|
||||
"rev": "release/6.0.2",
|
||||
"url": "https://github.com/phpredis/phpredis",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": [
|
||||
"LICENSE",
|
||||
"COPYING"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!-- TODO: Migrate and update from v2 source-module.md.
|
||||
Document v3 source types: url, ghrel, ghtar, ghtagtar, git, pecl (new), filelist, custom.
|
||||
Per-package YAML source block format. Parallel download (--parallel N). -->
|
||||
|
||||
@@ -1,180 +1,5 @@
|
||||
# Introduction to project structure
|
||||
# Project Structure
|
||||
|
||||
static-php-cli mainly contains three logical components: sources, dependent libraries, and extensions.
|
||||
These components contains 4 configuration files: `source.json`, `pkg.json`, `lib.json`, and `ext.json`.
|
||||
|
||||
A complete process for building standalone static PHP is:
|
||||
|
||||
1. Use the source download module `Downloader` to download specified or all source codes.
|
||||
These sources include PHP source code, dependent library source code, and extension source code.
|
||||
2. Use the source decompression module `SourceExtractor` to decompress the downloaded sources to the compilation directory.
|
||||
3. Use the dependency tool to calculate the dependent extensions and dependent libraries of the currently added extension,
|
||||
and then compile each library that needs to be compiled in the order of dependencies.
|
||||
4. After building each dependent library using `Builder` under the corresponding operating system, install it to the `buildroot` directory.
|
||||
5. If external extensions are included (the source code does not contain extensions within PHP),
|
||||
copy the external extensions to the `source/php-src/ext/` directory.
|
||||
6. Use `Builder` to build the PHP source code and build target to the `buildroot` directory.
|
||||
|
||||
The project is mainly divided into several folders:
|
||||
|
||||
- `bin/`: used to store program entry files, including `bin/spc`, `bin/spc-alpine-docker`, `bin/setup-runtime`.
|
||||
- `config/`: Contains all the extensions and dependent libraries supported by the project,
|
||||
as well as the download link and download methods of these sources. It is divided into files: `lib.json`, `ext.json`, `source.json`, `pkg.json`, `pre-built.json` .
|
||||
- `src/`: The core code of the project, including the entire framework and commands for compiling various extensions and libraries.
|
||||
- `vendor/`: The directory that Composer depends on, you do not need to make any modifications to it.
|
||||
|
||||
The operating principle is to start a `ConsoleApplication` of `symfony/console`, and then parse the commands entered by the user in the terminal.
|
||||
|
||||
## Basic command line structure
|
||||
|
||||
`bin/spc` is an entry file, including the Unix common `#!/usr/bin/env php`,
|
||||
which is used to allow the system to automatically execute with the PHP interpreter installed on the system.
|
||||
After the project executes `new ConsoleApplication()`, the framework will automatically register them as commands.
|
||||
|
||||
The project does not directly use the Command registration method and command execution method recommended by Symfony. Here are small changes:
|
||||
|
||||
1. Each command uses the `#[AsCommand()]` Attribute to register the name and description.
|
||||
2. Abstract `execute()` so that all commands are based on `BaseCommand` (which is based on `Symfony\Component\Console\Command\Command`),
|
||||
and the execution code of each command itself is written in the `handle()` method .
|
||||
3. Added variable `$no_motd` to `BaseCommand`, which is used to display the Figlet greeting when the command is executed.
|
||||
4. `BaseCommand` saves `InputInterface` and `OutputInterface` as member variables. You can use `$this->input` and `$this->output` within the command class.
|
||||
|
||||
## Basic source code structure
|
||||
|
||||
The source code of the project is located in the `src/SPC` directory,
|
||||
supports automatic loading of the PSR-4 standard, and contains the following subdirectories and classes:
|
||||
|
||||
- `src/SPC/builder/`: The core compilation command code used to build libraries,
|
||||
PHP and related extensions under different operating systems, and also includes some compilation system tool methods.
|
||||
- `src/SPC/command/`: All commands of the project are here.
|
||||
- `src/SPC/doctor/`: Doctor module, which is a relatively independent module used to check the system environment.
|
||||
It can be entered using the command `bin/spc doctor`.
|
||||
- `src/SPC/exception/`: exception class.
|
||||
- `src/SPC/store/`: Classes related to storage, files and sources are all here.
|
||||
- `src/SPC/util/`: Some reusable tool methods are here.
|
||||
- `src/SPC/ConsoleApplication.php`: command line program entry file.
|
||||
|
||||
If you have read the source code, you may find that there is also a `src/globals/` directory,
|
||||
which is used to store some global variables, global methods,
|
||||
and non-PSR-4 standard PHP source code that is relied upon during the build process, such as extension sanity check code etc.
|
||||
|
||||
## Phar application directory issue
|
||||
|
||||
Like other php-cli projects, spc itself has additional considerations for paths.
|
||||
Because spc can run in multiple modes such as `php-cli directly`, `micro SAPI`, `php-cli with Phar`, `vendor with Phar`, etc.,
|
||||
there are ambiguities in various root directories. A complete explanation is given here.
|
||||
This problem is generally common in the base class path selection problem of accessing files in PHP projects, especially when used with `micro.sfx`.
|
||||
|
||||
Note that this may only be useful for you when developing Phar projects or PHP frameworks.
|
||||
|
||||
> Next, we will treat `static-php-cli` (that is, spc) as a normal `php` command line program. You can understand spc as any of your own php-cli applications for reference.
|
||||
|
||||
There are three basic constant theoretical values below. We recommend that you introduce these three constants when writing PHP projects:
|
||||
|
||||
- `WORKING_DIR`: the working directory when executing PHP scripts
|
||||
|
||||
- `SOURCE_ROOT_DIR` or `ROOT_DIR`: the root directory of the project folder, generally the directory where `composer.json` is located
|
||||
|
||||
- `FRAMEWORK_ROOT_DIR`: the root directory of the framework used, which may be used by self-developed frameworks. Generally, the framework directory is read-only
|
||||
|
||||
You can define these constants in your framework entry or cli applications to facilitate the use of paths in your project.
|
||||
|
||||
The following are PHP built-in constant values, which have been defined inside the PHP interpreter:
|
||||
|
||||
- `__DIR__`: the directory where the file of the currently executed script is located
|
||||
|
||||
- `__FILE__`: the file path of the currently executed script
|
||||
|
||||
### Git project mode (source)
|
||||
|
||||
Git project mode refers to a framework or program itself stored in plain text in the current folder, and running through `php path/to/entry.php`.
|
||||
|
||||
Assume that your project is stored in the `/home/example/static-php-cli/` directory, or your project is the framework itself,
|
||||
which contains project files such as `composer.json`:
|
||||
|
||||
```
|
||||
composer.json
|
||||
src/App/MyCommand.app
|
||||
vendor/*
|
||||
bin/entry.php
|
||||
```
|
||||
|
||||
We assume that the above constants are obtained from `src/App/MyCommand.php`:
|
||||
|
||||
| Constant | Value |
|
||||
|----------------------|------------------------------------------------------|
|
||||
| `WORKING_DIR` | `/home/example/static-php-cli` |
|
||||
| `SOURCE_ROOT_DIR` | `/home/example/static-php-cli` |
|
||||
| `FRAMEWORK_ROOT_DIR` | `/home/example/static-php-cli` |
|
||||
| `__DIR__` | `/home/example/static-php-cli/src/App` |
|
||||
| `__FILE__` | `/home/example/static-php-cli/src/App/MyCommand.php` |
|
||||
|
||||
In this case, the values of `WORKING_DIR`, `SOURCE_ROOT_DIR`, and `FRAMEWORK_ROOT_DIR` are exactly the same: `/home/example/static-php-cli`.
|
||||
|
||||
The source code of the framework and the source code of the application are both in the current path.
|
||||
|
||||
### Vendor library mode (vendor)
|
||||
|
||||
The vendor library mode generally means that your project is a framework or is installed into the project as a composer dependency by other applications,
|
||||
and the storage location is in the `vendor/author/XXX` directory.
|
||||
|
||||
Suppose your project is `crazywhalecc/static-php-cli`, and you or others install this project in another project using `composer require`.
|
||||
|
||||
We assume that static-php-cli contains all files except the `vendor` directory with the same `Git mode`, and get the constant value from `src/App/MyCommand`,
|
||||
Directory constant should be:
|
||||
|
||||
| Constant | Value |
|
||||
|----------------------|--------------------------------------------------------------------------------------|
|
||||
| `WORKING_DIR` | `/home/example/another-app` |
|
||||
| `SOURCE_ROOT_DIR` | `/home/example/another-app` |
|
||||
| `FRAMEWORK_ROOT_DIR` | `/home/example/another-app/vendor/crazywhalecc/static-php-cli` |
|
||||
| `__DIR__` | `/home/example/another-app/vendor/crazywhalecc/static-php-cli/src/App` |
|
||||
| `__FILE__` | `/home/example/another-app/vendor/crazywhalecc/static-php-cli/src/App/MyCommand.php` |
|
||||
|
||||
Here `SOURCE_ROOT_DIR` refers to the root directory of the project using `static-php-cli`.
|
||||
|
||||
### Git project Phar mode (source-phar)
|
||||
|
||||
Git project Phar mode refers to the mode of packaging the project directory of the Git project mode into a `phar` file. We assume that `/home/example/static-php-cli` will be packaged into a Phar file, and the directory has the following files:
|
||||
|
||||
```
|
||||
composer.json
|
||||
src/App/MyCommand.app
|
||||
vendor/*
|
||||
bin/entry.php
|
||||
```
|
||||
|
||||
When packaged into `app.phar` and stored in the `/home/example/static-php-cli` directory, `app.phar` is executed at this time. Assuming that the `src/App/MyCommand` code is executed, the constant is obtained in the file:
|
||||
|
||||
| Constant | Value |
|
||||
|----------------------|----------------------------------------------------------------------|
|
||||
| `WORKING_DIR` | `/home/example/static-php-cli` |
|
||||
| `SOURCE_ROOT_DIR` | `phar:///home/example/static-php-cli/app.phar/` |
|
||||
| `FRAMEWORK_ROOT_DIR` | `phar:///home/example/static-php-cli/app.phar/` |
|
||||
| `__DIR__` | `phar:///home/example/static-php-cli/app.phar/src/App` |
|
||||
| `__FILE__` | `phar:///home/example/static-php-cli/app.phar/src/App/MyCommand.php` |
|
||||
|
||||
Because the `phar://` protocol is required to read files in the phar itself, the project root directory and the framework directory will be different from `WORKING_DIR`.
|
||||
|
||||
### Vendor Library Phar Mode (vendor-phar)
|
||||
|
||||
Vendor Library Phar Mode means that your project is installed as a framework in other projects and stored in the `vendor` directory.
|
||||
|
||||
We assume that your project directory structure is as follows:
|
||||
|
||||
```
|
||||
composer.json # Composer configuration file of the current project
|
||||
box.json # Configuration file for packaging Phar
|
||||
another-app.php # Entry file of another project
|
||||
vendor/crazywhalecc/static-php-cli/* # Your project is used as a dependent library
|
||||
```
|
||||
|
||||
When packaging these files under the directory `/home/example/another-app/` into `app.phar`, the value of the following constant for your project should be:
|
||||
|
||||
| Constant | Value |
|
||||
|----------------------|------------------------------------------------------------------------------------------------------|
|
||||
| `WORKING_DIR` | `/home/example/another-app` |
|
||||
| `SOURCE_ROOT_DIR` | `phar:///home/example/another-app/app.phar/` |
|
||||
| `FRAMEWORK_ROOT_DIR` | `phar:///home/example/another-app/app.phar/vendor/crazywhalecc/static-php-cli` |
|
||||
| `__DIR__` | `phar:///home/example/another-app/app.phar/vendor/crazywhalecc/static-php-cli/src/App` |
|
||||
| `__FILE__` | `phar:///home/example/another-app/app.phar/vendor/crazywhalecc/static-php-cli/src/App/MyCommand.php` |
|
||||
<!-- TODO: v3 directory layout (bin/, config/pkg/, src/StaticPHP/, src/Package/, etc.).
|
||||
Explain the role of each top-level directory. Internal class structure kept brief;
|
||||
deep dives belong in the Concepts pages. -->
|
||||
|
||||
@@ -1,242 +1,4 @@
|
||||
# Compilation Tools
|
||||
|
||||
static-php-cli uses many system compilation tools when building static PHP. These tools mainly include:
|
||||
|
||||
- `autoconf`: used to generate `configure` scripts.
|
||||
- `make`: used to execute `Makefile`.
|
||||
- `cmake`: used to execute `CMakeLists.txt`.
|
||||
- `pkg-config`: Used to find the installation path of dependent libraries.
|
||||
- `gcc`: used to compile C/C++ projects under Linux.
|
||||
- `clang`: used to compile C/C++ projects under macOS.
|
||||
|
||||
For Linux and macOS operating systems,
|
||||
these tools can usually be installed through the package manager, which is written in the doctor module.
|
||||
Theoretically we can also compile and download these tools manually,
|
||||
but this will increase the complexity of compilation, so we do not recommend this.
|
||||
|
||||
## Linux Compilation Tools
|
||||
|
||||
For Linux systems, different distributions have different installation methods for compilation tools.
|
||||
And for static compilation, the package management of some distributions cannot install libraries and tools for pure static compilation.
|
||||
Therefore, for the Linux platform and its different distributions,
|
||||
we currently provide a variety of compilation environment preparations.
|
||||
|
||||
### Glibc Environment
|
||||
|
||||
The glibc environment refers to the underlying `libc` library of the system
|
||||
(that is, the C standard library that all programs written in C language are dynamically linked to) uses `glibc`,
|
||||
which is the default environment for most distributions.
|
||||
For example: Ubuntu, Debian, CentOS, RHEL, openSUSE, Arch Linux, etc.
|
||||
|
||||
In the glibc environment, the package management and compiler we use point to glibc by default,
|
||||
and glibc cannot be statically linked well.
|
||||
One of the reasons it cannot be statically linked is that its network library `nss` cannot be compiled statically.
|
||||
|
||||
For the glibc environment, in static-php-cli and spc in 2.0-RC8 and later, you can choose two ways to build static PHP:
|
||||
|
||||
1. Use Docker to build, you can use `bin/spc-alpine-docker` to build, it will build an Alpine Linux docker image.
|
||||
2. Use `bin/spc doctor --auto-fix` to install the `musl-wrapper` and `musl-cross-make` packages, and then build directly.
|
||||
([Related source code](https://github.com/crazywhalecc/static-php-cli/blob/main/src/SPC/doctor/item/LinuxMuslCheck.php))
|
||||
|
||||
Generally speaking, the build results in these two environments are consistent, and you can choose according to actual needs.
|
||||
|
||||
In the doctor module, static-php-cli will first detect the current Linux distribution.
|
||||
If the current distribution is a glibc environment, you will be prompted to install the musl-wrapper and musl-cross-make packages.
|
||||
|
||||
The process of installing `musl-wrapper` in the glibc environment is as follows:
|
||||
|
||||
1. Download the specific version of [musl-wrapper source code](https://musl.libc.org/releases/) from the musl official website.
|
||||
2. Use `gcc` installed from the package management to compile the musl-wrapper source code and generate `musl-libc` and other libraries: `./configure --disable-gcc-wrapper && make -j && sudo make install`.
|
||||
3. The musl-wrapper related libraries will be installed in the `/usr/local/musl` directory.
|
||||
|
||||
The process of installing `musl-cross-make` in the glibc environment is as follows:
|
||||
|
||||
1. Download the precompiled [musl-cross-make](https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/) compressed package from dl.static-php.dev .
|
||||
2. Unzip to the `/usr/local/musl` directory.
|
||||
|
||||
::: tip
|
||||
In the glibc environment, static compilation can be achieved by directly installing musl-wrapper,
|
||||
but musl-wrapper only contains `musl-gcc` and not `musl-g++`, which means that C++ code cannot be compiled.
|
||||
So we need musl-cross-make to provide `musl-g++`.
|
||||
|
||||
The reason why the musl-cross-make package cannot be compiled directly locally is that
|
||||
its compilation environment requirements are relatively high (requires more than 36GB of memory, compiled under Alpine Linux),
|
||||
so we provide precompiled binary packages that can be used for all Linux distributions.
|
||||
|
||||
At the same time, the package management of some distributions provides musl-wrapper,
|
||||
but musl-cross-make needs to match the corresponding musl-wrapper version,
|
||||
so we do not use package management to install musl-wrapper.
|
||||
|
||||
Compiling musl-cross-make will be introduced in the **musl-cross-make Toolchain Compilation** section of this chapter.
|
||||
:::
|
||||
|
||||
### Musl Environment
|
||||
|
||||
The musl environment refers to the system's underlying `libc` library that uses `musl`,
|
||||
which is a lightweight C standard library that can be well statically linked.
|
||||
|
||||
For the currently popular Linux distributions, Alpine Linux uses the musl environment,
|
||||
so static-php-cli can directly build static PHP under Alpine Linux.
|
||||
You only need to install basic compilation tools (such as `gcc`, `cmake`, etc.) directly from the package management.
|
||||
|
||||
For other distributions, if your distribution uses the musl environment,
|
||||
you can also use static-php-cli to build static PHP directly after installing the necessary compilation tools.
|
||||
|
||||
::: tip
|
||||
In the musl environment, static-php-cli will automatically skip the installation of musl-wrapper and musl-cross-make.
|
||||
:::
|
||||
|
||||
### Docker Environment
|
||||
|
||||
The Docker environment refers to using Docker containers to build static PHP. You can use `bin/spc-alpine-docker` to build.
|
||||
Before executing this command, you need to install Docker first, and then execute `bin/spc-alpine-docker` in the project root directory.
|
||||
|
||||
After executing `bin/spc-alpine-docker`, static-php-cli will automatically download the Alpine Linux image and then build a `cwcc-spc-x86_64` or `cwcc-spc-aarch64` image.
|
||||
Then all build process is performed within this image, which is equivalent to compiling in Alpine Linux.
|
||||
|
||||
## musl-cross-make Toolchain Compilation
|
||||
|
||||
In Linux, although you do not need to manually compile the musl-cross-make tool,
|
||||
if you want to understand its compilation process, you can refer here.
|
||||
Another important reason is that this may not be compiled using automated tools such as CI and Actions,
|
||||
because the existing CI service compilation environment does not meet the compilation requirements of musl-cross-make,
|
||||
and the configuration that meets the requirements is too expensive.
|
||||
|
||||
The compilation process of musl-cross-make is as follows:
|
||||
|
||||
Prepare an Alpine Linux environment (either directly installed or using Docker).
|
||||
The compilation process requires more than **36GB** of memory,
|
||||
so you need to compile on a machine with larger memory.
|
||||
Without this much memory, compilation may fail.
|
||||
|
||||
Then write the following content into the `config.mak` file:
|
||||
|
||||
```makefile
|
||||
STAT = -static --static
|
||||
FLAG = -g0 -Os -Wno-error
|
||||
|
||||
ifneq ($(NATIVE),)
|
||||
COMMON_CONFIG += CC="$(HOST)-gcc ${STAT}" CXX="$(HOST)-g++ ${STAT}"
|
||||
else
|
||||
COMMON_CONFIG += CC="gcc ${STAT}" CXX="g++ ${STAT}"
|
||||
endif
|
||||
|
||||
COMMON_CONFIG += CFLAGS="${FLAG}" CXXFLAGS="${FLAG}" LDFLAGS="${STAT}"
|
||||
|
||||
BINUTILS_CONFIG += --enable-gold=yes --enable-gprofng=no
|
||||
GCC_CONFIG += --enable-static-pie --disable-cet --enable-default-pie
|
||||
#--enable-default-pie
|
||||
|
||||
CONFIG_SUB_REV = 888c8e3d5f7b
|
||||
GCC_VER = 13.2.0
|
||||
BINUTILS_VER = 2.40
|
||||
MUSL_VER = 1.2.4
|
||||
GMP_VER = 6.2.1
|
||||
MPC_VER = 1.2.1
|
||||
MPFR_VER = 4.2.0
|
||||
LINUX_VER = 6.1.36
|
||||
```
|
||||
|
||||
And also you need to add `gcc-13.2.0.tar.xz.sha1` file, contents here:
|
||||
|
||||
```
|
||||
5f95b6d042fb37d45c6cbebfc91decfbc4fb493c gcc-13.2.0.tar.xz
|
||||
```
|
||||
|
||||
If you are using Docker to build, create a new `Dockerfile` file and write the following content:
|
||||
|
||||
```dockerfile
|
||||
FROM alpine:edge
|
||||
|
||||
RUN apk add --no-cache \
|
||||
gcc g++ git make curl perl \
|
||||
rsync patch wget libtool \
|
||||
texinfo autoconf automake \
|
||||
bison tar xz bzip2 zlib \
|
||||
file binutils flex \
|
||||
linux-headers libintl \
|
||||
gettext gettext-dev icu-libs pkgconf \
|
||||
pkgconfig icu-dev bash \
|
||||
ccache libarchive-tools zip
|
||||
|
||||
WORKDIR /opt
|
||||
|
||||
RUN git clone https://git.zv.io/toolchains/musl-cross-make.git
|
||||
WORKDIR /opt/musl-cross-make
|
||||
COPY config.mak /opt/musl-cross-make
|
||||
COPY gcc-13.2.0.tar.xz.sha1 /opt/musl-cross-make/hashes
|
||||
|
||||
RUN make TARGET=x86_64-linux-musl -j || :
|
||||
RUN sed -i 's/poison calloc/poison/g' ./gcc-13.2.0/gcc/system.h
|
||||
RUN make TARGET=x86_64-linux-musl -j
|
||||
RUN make TARGET=x86_64-linux-musl install -j
|
||||
RUN tar cvzf x86_64-musl-toolchain.tgz output/*
|
||||
```
|
||||
|
||||
If you are using Alpine Linux in a non-Docker environment, you can directly execute the commands in the Dockerfile, for example:
|
||||
|
||||
```bash
|
||||
apk add --no-cache \
|
||||
gcc g++ git make curl perl \
|
||||
rsync patch wget libtool \
|
||||
texinfo autoconf automake \
|
||||
bison tar xz bzip2 zlib \
|
||||
file binutils flex \
|
||||
linux-headers libintl \
|
||||
gettext gettext-dev icu-libs pkgconf \
|
||||
pkgconfig icu-dev bash \
|
||||
ccache libarchive-tools zip
|
||||
|
||||
git clone https://git.zv.io/toolchains/musl-cross-make.git
|
||||
# Copy config.mak to the working directory of musl-cross-make.
|
||||
# You need to replace /path/to/config.mak with your config.mak file path.
|
||||
cp /path/to/config.mak musl-cross-make/
|
||||
cp /path/to/gcc-13.2.0.tar.xz.sha1 musl-cross-make/hashes
|
||||
|
||||
make TARGET=x86_64-linux-musl -j || :
|
||||
sed -i 's/poison calloc/poison/g' ./gcc-13.2.0/gcc/system.h
|
||||
make TARGET=x86_64-linux-musl -j
|
||||
make TARGET=x86_64-linux-musl install -j
|
||||
tar cvzf x86_64-musl-toolchain.tgz output/*
|
||||
```
|
||||
|
||||
::: tip
|
||||
All the above scripts are suitable for x86_64 architecture Linux.
|
||||
If you need to build musl-cross-make for the ARM environment, just replace all `x86_64` above with `aarch64`.
|
||||
:::
|
||||
|
||||
This compilation process may fail due to insufficient memory, network problems, etc.
|
||||
You can try a few more times, or use a machine with larger memory to compile.
|
||||
If you encounter problems or you have better improvement solutions, go to [Discussion](https://github.com/crazywhalecc/static-php-cli-hosted/issues/1).
|
||||
|
||||
## macOS Environment
|
||||
|
||||
For macOS systems, the main compilation tool we use is `clang`,
|
||||
which is the default compiler for macOS systems and is also the compiler of Xcode.
|
||||
|
||||
Compiling under macOS mainly relies on Xcode or Xcode Command Line Tools.
|
||||
You can download Xcode from the App Store,
|
||||
or execute `xcode-select --install` in the terminal to install Xcode Command Line Tools.
|
||||
|
||||
In addition, in the `doctor` environment check module, static-php-cli will check whether Homebrew,
|
||||
compilation tools, etc. are installed on the macOS system.
|
||||
If not, you will be prompted to install them. I will not go into details here.
|
||||
|
||||
## FreeBSD Environment
|
||||
|
||||
FreeBSD is also a Unix system, and its compilation tools are similar to macOS.
|
||||
You can directly use the package management `pkg` to install `clang` and other compilation tools through the `doctor` command.
|
||||
|
||||
## pkg-config Compilation (*nix only)
|
||||
|
||||
If you observe the compilation log when using static-php-cli to build static PHP, you will find that no matter what is compiled,
|
||||
`pkg-config` will be compiled first. This is because `pkg-config` is a library used to find dependencies.
|
||||
In earlier versions of static-php-cli, we directly used the `pkg-config` tool installed by package management,
|
||||
but this would cause some problems, such as:
|
||||
|
||||
- Even if `PKG_CONFIG_PATH` is specified, `pkg-config` will try to find dependent packages from the system path.
|
||||
- Since `pkg-config` will look for dependent packages from the system path,
|
||||
if a dependent package with the same name exists in the system, compilation may fail.
|
||||
|
||||
In order to avoid the above problems, we compile `pkg-config` into `buildroot/bin` in user mode and use it.
|
||||
We use parameters such as `--without-sysroot` to avoid looking for dependent packages from the system path.
|
||||
<!-- TODO: Migrate and update from v2 system-build-tools.md.
|
||||
Cover v3 additions: WindowsCMakeExecutor, vswhere.exe detection, LLVM/Clang for FrankenPHP. -->
|
||||
|
||||
6
docs/en/develop/vendor-mode/annotations.md
Normal file
6
docs/en/develop/vendor-mode/annotations.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Annotations Reference
|
||||
|
||||
<!-- TODO: Complete reference for all v3 PHP attributes.
|
||||
#[Library], #[Extension], #[BuildFor], #[BeforeStage], #[AfterStage],
|
||||
#[PatchBeforeBuild], #[CustomPhpConfigureArg], #[AsCheckItem], #[AsFixItem].
|
||||
Per-attribute: parameters, types, allowed targets, example. -->
|
||||
6
docs/en/develop/vendor-mode/dependency-injection.md
Normal file
6
docs/en/develop/vendor-mode/dependency-injection.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Dependency Injection
|
||||
|
||||
<!-- TODO: How PHP-DI autowiring works in v3.
|
||||
ApplicationContext::get() usage.
|
||||
Registering custom services.
|
||||
Injecting into command classes, build classes, and stage methods. -->
|
||||
6
docs/en/develop/vendor-mode/index.md
Normal file
6
docs/en/develop/vendor-mode/index.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Vendor Mode
|
||||
|
||||
<!-- TODO: What vendor mode is and when to use it.
|
||||
Installation: `composer require crazywhalecc/static-php-cli`.
|
||||
How to register an external registry pointing to your custom package classes.
|
||||
Minimal working example: one Library class, one config YAML, run spc. -->
|
||||
6
docs/en/develop/vendor-mode/lifecycle-hooks.md
Normal file
6
docs/en/develop/vendor-mode/lifecycle-hooks.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Lifecycle Hooks
|
||||
|
||||
<!-- TODO: Detailed explanation of hook execution order and method signatures.
|
||||
#[BeforeStage('lib-name', 'build')], #[AfterStage(...)], #[PatchBeforeBuild].
|
||||
How hooks from different packages are merged and ordered.
|
||||
Common patterns: patching config.m4, injecting compile flags, post-install fixups. -->
|
||||
6
docs/en/develop/vendor-mode/package-classes.md
Normal file
6
docs/en/develop/vendor-mode/package-classes.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Writing Package Classes
|
||||
|
||||
<!-- TODO: Step-by-step guide to writing a Library class and an Extension class.
|
||||
Full annotated code examples using #[Library], #[Extension], #[BuildFor].
|
||||
UnixAutoconfExecutor / UnixCmakeExecutor / WindowsCMakeExecutor usage.
|
||||
File placement (src/Package/Library/, src/Package/Extension/) and autoloading. -->
|
||||
@@ -1,108 +1,10 @@
|
||||
# FAQ
|
||||
# Frequently Asked Questions
|
||||
|
||||
Here will be some questions that you may encounter easily. There are currently many, but I need to take time to organize them.
|
||||
|
||||
## What is the path of php.ini ?
|
||||
|
||||
On Linux, macOS and FreeBSD, the path of `php.ini` is `/usr/local/etc/php/php.ini`.
|
||||
On Windows, the path is `C:\windows\php.ini` or the current directory of `php.exe`.
|
||||
The directory where to look for `php.ini` can be changed on *nix using the manual build option `--with-config-file-path`.
|
||||
|
||||
In addition, on Linux, macOS and FreeBSD, `.ini` files present in the `/usr/local/etc/php/conf.d` directory will also be loaded.
|
||||
On Windows, this path is empty by default.
|
||||
The directory can be changed using the manual build option `--with-config-file-scan-dir`.
|
||||
|
||||
`php.ini` will also be searched for in [the other standard locations](https://www.php.net/manual/configuration.file.php).
|
||||
|
||||
## Can statically-compiled PHP install extensions?
|
||||
|
||||
Because the principle of installing PHP extensions under the normal mode is to use `.so` type dynamic link library to install new extensions,
|
||||
and we use the static link PHP compiled by this project. However, static linking has different definitions in different operating systems.
|
||||
|
||||
First of all, for Linux systems, statically linked binaries will not link the system's dynamic link library.
|
||||
Purely statically linked binaries (`build with -all-static`) cannot load dynamic libraries, so new extensions cannot be added.
|
||||
At the same time, in pure static mode, you cannot use extensions such as `ffi` to load external `.so` modules.
|
||||
|
||||
You can use the command `ldd buildroot/bin/php` to check whether the binary you built under Linux is purely statically linked.
|
||||
|
||||
If you [build GNU libc based PHP](../guide/build-with-glibc), you can use the `ffi` extension to load external `.so` modules and load `.so` extensions with the same ABI.
|
||||
|
||||
For example, you can use the following command to build a static PHP binary dynamically linked with glibc,
|
||||
supporting FFI extensions and loading the `xdebug.so` extension of the same PHP version and the same TS type:
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker download --for-extensions=ffi,xml --with-php=8.4
|
||||
bin/spc-gnu-docker build ffi,xml --build-cli --debug
|
||||
|
||||
buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" --ri xdebug
|
||||
```
|
||||
|
||||
For macOS platform, almost all binaries under macOS cannot be truly purely statically linked, and almost all binaries will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`.
|
||||
So on macOS, you can **directly** use SPC to build statically compiled PHP binaries with dynamically linked extensions:
|
||||
|
||||
1. Build shared extension `xxx.so` using: `--build-shared=XXX` option. e.g. `bin/spc build bcmath,zlib --build-shared=xdebug --build-cli`
|
||||
2. You will get `buildroot/modules/xdebug.so` and `buildroot/bin/php`.
|
||||
3. The `xdebug.so` file could be used for php that version and thread-safe are the same.
|
||||
|
||||
For the Windows platform, since officially built extensions (such as `php_yaml.dll`) force the use of the `php8.dll` dynamic library as a link, and statically built PHP does not include any dynamic libraries other than system libraries,
|
||||
php.exe built by static-php cannot load officially built dynamic extensions. Since static-php-cli does not yet support building dynamic extensions, there is currently no way to load dynamic extensions with static-php.
|
||||
|
||||
However, Windows can normally use the `FFI` extension to load other dll files and call them.
|
||||
|
||||
## Can it support Oracle database extension?
|
||||
|
||||
Some extensions that rely on closed source libraries, such as `oci8`, `sourceguardian`, etc.,
|
||||
they do not provide purely statically compiled dependent library files (`.a`), only dynamic dependent library files (`.so`).
|
||||
These extensions cannot be compiled into static-php-cli using source code, so this project may never support these extensions.
|
||||
However, in theory you can access and use such extensions under macOS and Linux according to the above questions.
|
||||
|
||||
If you have a need for such extensions, or most people have needs for these closed-source extensions,
|
||||
see the discussion on [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58). Welcome to leave a message.
|
||||
|
||||
## Does it support Windows?
|
||||
|
||||
The project currently supports Windows, but the number of supported extensions is small. Windows support is not perfect. There are mainly the following problems:
|
||||
|
||||
1. The compilation process of Windows is different from that of *nix, and the toolchain used is also different. The compilation tools used to compile the dependent libraries of each extension are almost completely different.
|
||||
2. The demand for the Windows version will also be advanced based on the needs of all people who use this project. If many people need it, I will support related extensions as soon as possible.
|
||||
|
||||
## Can I protect my source code with micro?
|
||||
|
||||
You can't. micro.sfx is essentially combining php and php code into one file,
|
||||
there is no process of compiling or encrypting the PHP code.
|
||||
|
||||
First of all, php-src is the official interpreter of PHP code, and there is no PHP compiler compatible with mainstream branches on the market.
|
||||
I saw on the Internet that there is a project called BPC (Binary PHP Compiler?) that can compile PHP into binary,
|
||||
but there are many restrictions.
|
||||
|
||||
The direction of encrypting and protecting the code is not the same as compiling.
|
||||
After compiling, the code can also be obtained through reverse engineering and other methods.
|
||||
The real protection is still carried out by means of packing and encrypting the code.
|
||||
|
||||
Therefore, this project (static-php-cli) and related projects (lwmbs, swoole-cli) all provide a convenient compilation tool for php-src source code.
|
||||
The phpmicro referenced by this project and related projects is only a package of PHP's sapi interface, not a compilation tool for PHP code.
|
||||
The compiler for PHP code is a completely different project, so the extra cases are not taken into account.
|
||||
If you are interested in encryption, you can consider using existing encryption technologies,
|
||||
such as Swoole Compiler, Source Guardian, etc.
|
||||
|
||||
## Unable to use ssl
|
||||
|
||||
**Update: This issue has been fixed in the latest version of static-php-cli, which now reads the system's certificate file by default. If you still have problems, try the solution below.**
|
||||
|
||||
When using curl, pgsql, etc. to request an HTTPS website or establish an SSL connection, there may be an `error:80000002:system library::No such file or directory` error.
|
||||
This error is caused by statically compiled PHP without specifying `openssl.cafile` via `php.ini`.
|
||||
|
||||
You can solve this problem by specifying `php.ini` before using PHP and adding `openssl.cafile=/path/to/your-cert.pem` in the INI.
|
||||
|
||||
For Linux systems, you can download the [cacert.pem](https://curl.se/docs/caextract.html) file from the curl official website, or you can use the certificate file that comes with the system.
|
||||
For the certificate locations of different distros, please refer to [Golang docs](https://go.dev/src/crypto/x509/root_linux.go).
|
||||
|
||||
> INI configuration `openssl.cafile` cannot be set dynamically using the `ini_set()` function, because `openssl.cafile` is a `PHP_INI_SYSTEM` type configuration and can only be set in the `php.ini` file.
|
||||
|
||||
## Why don't we support older versions of PHP?
|
||||
|
||||
Because older versions of PHP have many problems, such as security issues, performance issues, and functional issues.
|
||||
In addition, many older versions of PHP are not compatible with the latest dependency libraries,
|
||||
which is one of the reasons why older versions of PHP are not supported.
|
||||
|
||||
You can use older versions compiled earlier by static-php-cli, such as PHP 8.0, but earlier versions will not be explicitly supported.
|
||||
<!-- TODO: Categorized FAQ.
|
||||
Sections:
|
||||
- Build Issues (common compile errors, missing tools)
|
||||
- Extensions (dynamic loading, closed-source deps, oci8)
|
||||
- Windows (icon embedding, DLL loading, FFI)
|
||||
- Version Compatibility (PHP versions, glibc vs musl)
|
||||
- Source Protection (micro, encryption)
|
||||
Migrate and expand from v2 faq/index.md. -->
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# GitHub Action Build
|
||||
|
||||
Action Build refers to compiling directly using GitHub Action.
|
||||
|
||||
If you don't want to compile it yourself, you can download the artifact from the existing Action in this project,
|
||||
or you can download it from a self-hosted server:[Enter](https://dl.static-php.dev/static-php-cli/common/).
|
||||
|
||||
> Self-hosted binaries are also built from Actions: [repo](https://github.com/static-php/static-php-cli-hosted).
|
||||
> The extensions included are: bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,
|
||||
> pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip
|
||||
|
||||
## Build Guide
|
||||
|
||||
Using GitHub Action makes it easy to build a statically compiled PHP and phpmicro,
|
||||
while also defining the extensions to compile.
|
||||
|
||||
1. Fork project.
|
||||
2. Go to the Actions of the project and select `CI`.
|
||||
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of static extensions. (comma separated, e.g. `bcmath,curl,mbstring`)
|
||||
4. If you need shared extensions (for example `xdebug`), set `shared-extensions` (comma separated, e.g. `xdebug`).
|
||||
5. If you need FrankenPHP, enable `build-frankenphp` and also enable `enable-zts`.
|
||||
6. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
|
||||
|
||||
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
|
||||
|
||||
> If you need to build in other environments, you can use [manual build](./manual-build).
|
||||
|
||||
## Extensions
|
||||
|
||||
You can go to [extensions](./extensions) check here to see if all the extensions you need currently support.
|
||||
and then go to [command generator](./cli-generator) select the extension you need to compile, copy the extensions string to `extensions` option.
|
||||
@@ -1,228 +0,0 @@
|
||||
# Build on Windows
|
||||
|
||||
Because the Windows system is an NT kernel, the compilation tools and operating system interfaces
|
||||
used by Unix-like operating systems are almost completely different,
|
||||
so the build process on Windows will be slightly different from that of Unix systems.
|
||||
|
||||
## GitHub Actions Build
|
||||
|
||||
Building the Windows version of static-php from Actions is now supported.
|
||||
Like Linux and macOS, you need to Fork the static-php-cli repository to your GitHub account first,
|
||||
then you can enter [Extension List](./extensions) to select the extension to be compiled,
|
||||
and then go to your own `CI on Windows` select the PHP version, fill in the extension list (comma separated), and click Run.
|
||||
|
||||
If you're going to develop or build locally, please read on.
|
||||
|
||||
## Requirements
|
||||
|
||||
The tools required to build static PHP on Windows are the same as PHP's official Windows build tools.
|
||||
You can read [Official Documentation](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2).
|
||||
|
||||
To sum up, you need the following environment and tools:
|
||||
|
||||
- Windows 10/11 (requires build 17063 or later)
|
||||
- Visual Studio 2019/2022 (recommended 2022)
|
||||
- C++ desktop development for Visual Studio
|
||||
- Git for Windows
|
||||
- [php-sdk-binary-tools](https://github.com/php/php-sdk-binary-tools) (can be installed automatically using doctor)
|
||||
- strawberry-perl (can be installed automatically using doctor)
|
||||
- nasm (can be installed automatically using doctor)
|
||||
|
||||
::: tip
|
||||
The construction of static-php-cli on Windows refers to using MSVC to build PHP and is not based on MinGW, Cygwin, WSL and other environments.
|
||||
|
||||
If you prefer to use WSL, please refer to the chapter on Building on Linux.
|
||||
:::
|
||||
|
||||
After installing Visual Studio and selecting the C++ desktop development workload,
|
||||
you may download about 8GB of compilation tools, and the download speed depends on your network conditions.
|
||||
|
||||
### Install Git
|
||||
|
||||
Git for Windows can be downloaded and installed from [here](https://git-scm.com/download/win) `Standalone Installer 64-bit` version,
|
||||
installed in the default location (`C:\Program Files\Git\`).
|
||||
If you don't want to download and install manually,
|
||||
you can also use Visual Studio Installer and check Git in the **Individual component** tab.
|
||||
|
||||
### Prepare static-php-cli
|
||||
|
||||
Downloading the static-php-cli project is very simple, just use git clone.
|
||||
It is recommended to place the project in `C:\spc-build\` or a similar directory.
|
||||
It is best **not to have spaces in the path**.
|
||||
|
||||
```shell
|
||||
mkdir "C:\spc-build"
|
||||
cd C:\spc-build
|
||||
git clone https://github.com/crazywhalecc/static-php-cli.git
|
||||
cd static-php-cli
|
||||
```
|
||||
|
||||
It is a bit strange that static-php-cli itself requires a PHP environment,
|
||||
but now you can quickly install the PHP environment through a script.
|
||||
Generally, your computer will not have the Windows version of PHP installed,
|
||||
so we recommend that you use `bin/setup-runtime` directly after downloading static-php-cli to install PHP and Composer in the current directory.
|
||||
|
||||
```shell
|
||||
# Install PHP and Composer to the ./runtime/ directory
|
||||
bin/setup-runtime
|
||||
|
||||
# After installation, if you need to use PHP and Composer in global commands,
|
||||
# use the following command to add the runtime/ directory to PATH
|
||||
bin/setup-runtime -action add-path
|
||||
|
||||
# Delete the runtime/ directory in PATH
|
||||
bin/setup-runtime -action remove-path
|
||||
```
|
||||
|
||||
Finally, now that you have PHP and Composer installed, you need to install static-php-cli's Composer dependencies:
|
||||
|
||||
```shell
|
||||
composer install
|
||||
```
|
||||
|
||||
### Install other Tools (automatic)
|
||||
|
||||
For `php-sdk-binary-tools`, `strawberry-perl`, and `nasm`,
|
||||
we recommend that you directly use the command `bin/spc doctor` to check and install them.
|
||||
|
||||
If doctor successfully installs automatically, please **skip** the steps below to manually install the above tools.
|
||||
|
||||
But if the automatic installation fails, please refer to the manual installation method below.
|
||||
|
||||
### Install php-sdk-binary-tools (manual)
|
||||
|
||||
```shell
|
||||
cd C:\spc-build\static-php-cli
|
||||
git clone https://github.com/php/php-sdk-binary-tools.git
|
||||
```
|
||||
|
||||
> You can also set the global variable `PHP_SDK_PATH` in Windows settings and
|
||||
> clone the project to the path corresponding to the variable.
|
||||
> Under normal circumstances, you don't need to change it.
|
||||
|
||||
### Install strawberry-perl (manual)
|
||||
|
||||
> If you don't need to compile the openssl extension, you don't need to install perl.
|
||||
|
||||
1. Download the latest version of strawberry-perl from [GitHub](https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/).
|
||||
2. Install to the `C:\spc-build\static-php-cli\pkgroot\perl\` directory.
|
||||
|
||||
> You can download the `-portable` version and extract it directly to the above directory.
|
||||
> The last `perl.exe` should be located at `C:\spc-build\static-php-cli\pkgroot\perl\perl\bin\perl.exe`.
|
||||
|
||||
### Install nasm (manual)
|
||||
|
||||
> If you don't need to compile openssl extension, you don't need to install nasm.
|
||||
|
||||
1. Download the nasm tool (x64) from [official website](https://www.nasm.us/pub/nasm/releasebuilds/).
|
||||
2. Place `nasm.exe` and `ndisasm.exe` in the `C:\spc-build\static-php-cli\php-sdk-binary-tools\bin\` directory.
|
||||
|
||||
## Download required sources
|
||||
|
||||
Same as [Manual build - Download](./manual-build.html#command-download)
|
||||
|
||||
## Build PHP
|
||||
|
||||
Use the build command to start building the static php binary.
|
||||
Before executing the `bin/spc build` command, be sure to use the `download` command to download sources.
|
||||
It is recommended to use `doctor` to check the environment.
|
||||
|
||||
### Build SAPI
|
||||
|
||||
You need to go to [Extension List](./extensions) or [Command Generator](./cli-generator) to select the extension you want to add,
|
||||
and then use the command `bin/spc build` to compile.
|
||||
You need to specify targets, choose from the following parameters (at least one):
|
||||
|
||||
- `--build-cli`: Build a cli sapi (command line interface, which can execute PHP code on the command line)
|
||||
- `--build-micro`: Build a micro sapi (used to build a standalone executable binary containing PHP code)
|
||||
|
||||
```shell
|
||||
# Compile PHP with bcmath,openssl,zlib extensions, the compilation target is cli
|
||||
bin/spc build "bcmath,openssl,zlib" --build-cli
|
||||
|
||||
# Compile PHP with phar,curl,posix,pcntl,tokenizer extensions, compile target is micro and cli
|
||||
bin/spc build "bcmath,openssl,zlib" --build-micro --build-cli
|
||||
```
|
||||
|
||||
::: warning
|
||||
In Windows, it is best to use double quotes to wrap parameters containing commas, such as `"bcmath,openssl,mbstring"`.
|
||||
:::
|
||||
|
||||
### Debug
|
||||
|
||||
If you encounter problems during the compilation process, or want to view each executing shell command,
|
||||
you can use `--debug` to enable debug mode and view all terminal logs:
|
||||
|
||||
```shell
|
||||
bin/spc build "openssl" --build-cli --debug
|
||||
```
|
||||
|
||||
### Build Options
|
||||
|
||||
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:
|
||||
|
||||
- `--with-clean`: clean up old make files before compiling PHP
|
||||
- `--enable-zts`: Make compiled PHP thread-safe version (default is NTS version)
|
||||
- `--with-libs=XXX,YYY`: Compile the specified dependent library before compiling PHP, and activate some extension optional functions
|
||||
- `--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)
|
||||
- `--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)
|
||||
- `--with-micro-logo=XXX.ico`: Customize the icon of the `exe` executable file after customizing the micro build (in the format of `.ico`)
|
||||
|
||||
Here is a simple example where we preset a larger `memory_limit` and disable the `system` function:
|
||||
|
||||
```shell
|
||||
bin/spc build "bcmath,openssl" --build-cli -I "memory_limit=4G" -I "disable_functions=system"
|
||||
```
|
||||
|
||||
Another example: Customize our hello-world.exe program logo:
|
||||
|
||||
```shell
|
||||
bin/spc build "ffi,bcmath" --build-micro --with-micro-logo=mylogo.ico --debug
|
||||
bin/spc micro:combine hello.php
|
||||
# Then we got `my-app.exe` with custom logo!
|
||||
my-app.exe
|
||||
```
|
||||
|
||||
## Use php.exe
|
||||
|
||||
After php.exe is compiled, it is located in the `buildroot\bin\` directory. You can copy it to any location for use.
|
||||
|
||||
```shell
|
||||
.\php -v
|
||||
```
|
||||
|
||||
## Use micro.sfx
|
||||
|
||||
> phpmicro is a SelF-extracted eXecutable SAPI module,
|
||||
> provided by [phpmicro](https://github.com/dixyes/phpmicro) project.
|
||||
> But this project is using a [fork](https://github.com/static-php/phpmicro) of phpmicro, because we need to add some features to it.
|
||||
> It can put php runtime and your source code together.
|
||||
|
||||
The final compilation result will output a file named `./micro.sfx`,
|
||||
which needs to be used with your PHP source code like `code.php`.
|
||||
This file will be located in the path `buildroot/bin/micro.sfx`.
|
||||
|
||||
Prepare your project source code, which can be a single PHP file or a Phar file, for use.
|
||||
|
||||
> If you want to combine phar files, you must add `phar` extension when compiling!
|
||||
|
||||
```shell
|
||||
# code.php "<?php echo 'Hello world' . PHP_EOL;"
|
||||
bin/spc micro:combine code.php -O my-app.exe
|
||||
# Run it!!! Copy it to another computer!!!
|
||||
./my-app.exe
|
||||
```
|
||||
|
||||
If you package a PHAR file, just replace `code.php` with the phar file path.
|
||||
You can use [box-project/box](https://github.com/box-project/box) to package your CLI project as Phar,
|
||||
It is then combined with phpmicro to produce a standalone executable binary.
|
||||
|
||||
For more details on the `micro:combine` command, refer to [command](./manual-build) on Unix systems.
|
||||
@@ -1,64 +0,0 @@
|
||||
# Build glibc Compatible Linux Binary
|
||||
|
||||
## Why Build glibc Compatible Binary
|
||||
|
||||
Currently, the binaries built by static-php-cli on Linux by default are based on musl-libc (statically linked).
|
||||
musl-libc is a lightweight libc implementation
|
||||
that aims to be compatible with glibc and provides good support for pure static linking.
|
||||
This means that the compiled static PHP executable can be used on almost any Linux distribution without worrying about the versions of libc, libstdc++, etc.
|
||||
|
||||
However, there are some issues with pure static linking of musl-libc binaries on Linux:
|
||||
|
||||
- The `dl()` function in PHP cannot be used to load dynamic libraries and external PHP extensions.
|
||||
- The FFI extension in PHP cannot be used.
|
||||
- In some extreme cases, performance issues may occur. See [musl-libc performance issues](https://github.com/php/php-src/issues/13648).
|
||||
|
||||
Different Linux distributions use different default libc.
|
||||
For example, Alpine Linux uses musl libc, while most Linux distributions use glibc.
|
||||
However, even so, we cannot directly use any distribution using glibc to build portable static binaries because glibc has some issues:
|
||||
|
||||
- Binaries built with gcc and other tools on newer versions of distributions cannot run on older versions of distributions.
|
||||
- glibc is not recommended to be statically linked because some of its features require the support of dynamic libraries.
|
||||
|
||||
However, we can use Docker to solve this problem.
|
||||
The final output is a binary **dynamically linked with glibc** and some necessary libraries,
|
||||
but **statically linked with all other dependencies**.
|
||||
|
||||
1. Use an older version of a Linux distribution (such as CentOS 7.x), which has an older version of glibc but can run on most modern Linux distributions.
|
||||
2. Build the static binary of PHP in this container so that it can run on most modern Linux distributions.
|
||||
|
||||
> Using glibc static binaries can run on most modern Linux distributions but cannot run on musl libc distributions, such as CentOS 6, Alpine Linux, etc.
|
||||
|
||||
## Build glibc Compatible Linux Binary
|
||||
|
||||
The latest version of static-php-cli includes the `bin/spc-gnu-docker` script,
|
||||
which can create a CentOS 7.x (glibc-2.17) Docker container with one click and build a glibc compatible PHP static binary in the container.
|
||||
|
||||
Then, run the following command once.
|
||||
The first run will take a long time because it needs to download the CentOS 7.x image and some build tools.
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker
|
||||
```
|
||||
|
||||
After the image is built, you will see the same command help menu as `bin/spc`, which means the container is ready.
|
||||
|
||||
After the container is ready, you can refer to the [local build](./manual-build) section to build your PHP static binary.
|
||||
Just replace `bin/spc` or `./spc` with `bin/spc-gnu-docker`.
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker build bcmath,ctype,openssl,pdo,phar,posix,session,tokenizer,xml,zip --build-cli --debug
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
In rare cases, glibc-based static PHP may encounter segment faults and other errors, but there are currently few examples.
|
||||
If you encounter any issues, please submit an issue.
|
||||
|
||||
glibc build is an extended feature and is not part of the default static-php support.
|
||||
If you have related issues or requirements, please indicate that you are building based on glibc when submitting an issue.
|
||||
|
||||
If you need to build glibc-based binaries without using Docker,
|
||||
please refer to the `bin/spc-gnu-docker` script to manually create a similar environment.
|
||||
|
||||
Please keep in mind that we only support glibc build with `bin/spc-gnu-docker`. Compilation on RHEL 9 & 10 has been tested and is stable, but if you run into issues, we may choose not to fix them.
|
||||
@@ -2,15 +2,6 @@
|
||||
aside: false
|
||||
---
|
||||
|
||||
<script setup lang="ts">
|
||||
import CliGenerator from "../../.vitepress/components/CliGenerator.vue";
|
||||
</script>
|
||||
# Build Command Generator
|
||||
|
||||
# CLI Build Command Generator
|
||||
|
||||
::: tip
|
||||
The extensions selected below may contain extensions that are not supported by the selected operating system,
|
||||
which may cause compilation to fail. Please check [Supported Extensions](./extensions) first.
|
||||
:::
|
||||
|
||||
<cli-generator lang="en" />
|
||||
<!-- TODO: Embed CliGenerator Vue component. -->
|
||||
|
||||
6
docs/en/guide/cli-reference.md
Normal file
6
docs/en/guide/cli-reference.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# CLI Reference
|
||||
|
||||
<!-- TODO: Full reference for every spc command and option.
|
||||
One ## section per command: download, build, craft, doctor, check-update, dev:*.
|
||||
Each option: type, default, description, example.
|
||||
Covers platform-specific options (e.g., --embed-icon on Windows). -->
|
||||
@@ -1,26 +1,4 @@
|
||||
---
|
||||
outline: 'deep'
|
||||
---
|
||||
|
||||
# Dependency Table
|
||||
|
||||
When compiling PHP, each extension and library has dependencies, which may be required or optional.
|
||||
You can choose whether to include these optional dependencies.
|
||||
|
||||
For example, when compiling the `gd` extension under Linux,
|
||||
the `zlib,libpng` libraries and the `zlib` extension are forced to be compiled,
|
||||
while the `libavif,libwebp,libjpeg,freetype` libraries are optional libraries and will not be compiled by default
|
||||
unless specified by the `--with-libs=avif,webp,jpeg,freetype` option.
|
||||
|
||||
- For optional extensions (optional features of extensions), you need to specify them manually at compile time, for example, to enable igbinary support for Redis: `bin/spc build redis,igbinary`.
|
||||
- For optional libraries, you need to compile and specify them through the `--with-libs=XXX` option.
|
||||
- If you want to enable all optional extensions, you can use `bin/spc build redis --with-suggested-exts`.
|
||||
- If you want to enable all optional libraries, you can use `--with-suggested-libs`.
|
||||
|
||||
## Extension Dependency Table
|
||||
|
||||
<!--@include: ../../deps-map-ext.md-->
|
||||
|
||||
## Library Dependency Table
|
||||
|
||||
<!--@include: ../../deps-map-lib.md-->
|
||||
<!-- TODO: Auto-generated by `bin/spc dev:gen-ext-dep-docs` and `dev:gen-lib-dep-docs`.
|
||||
Placeholder until commands are implemented in v3. -->
|
||||
|
||||
@@ -1,121 +1,4 @@
|
||||
# Environment variables
|
||||
# Environment Variables
|
||||
|
||||
All environment variables mentioned in the list on this page have default values unless otherwise noted.
|
||||
You can override the default values by setting these environment variables.
|
||||
|
||||
## Environment variables list
|
||||
|
||||
Starting from version 2.3.5, we have centralized the environment variables in the `config/env.ini` file.
|
||||
You can set environment variables by modifying this file.
|
||||
|
||||
We divide the environment variables supported by static-php-cli into three types:
|
||||
|
||||
- Global internal environment variables: declared after static-php-cli starts, you can use `getenv()` to get them internally in static-php-cli, and you can override them before starting static-php-cli.
|
||||
- Fixed environment variables: declared after static-php-cli starts, you can only use `getenv()` to get them, but you cannot override them through shell scripts.
|
||||
- Config file environment variables: declared before static-php-cli build, you can set these environment variables by modifying the `config/env.ini` file or through shell scripts.
|
||||
|
||||
You can read the comments for each parameter in [config/env.ini](https://github.com/crazywhalecc/static-php-cli/blob/main/config/env.ini) to understand its purpose.
|
||||
|
||||
## Custom environment variables
|
||||
|
||||
Generally, you don't need to modify any of the following environment variables as they are already set to optimal values.
|
||||
However, if you have special needs, you can set these environment variables to meet your needs
|
||||
(for example, you need to debug PHP performance under different compilation parameters).
|
||||
|
||||
If you want to use custom environment variables, you can use the `export` command in the terminal or set the environment variables directly before the command, for example:
|
||||
|
||||
```shell
|
||||
# export first
|
||||
export SPC_CONCURRENCY=4
|
||||
bin/spc build mbstring,pcntl --build-cli
|
||||
|
||||
# or direct use
|
||||
SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
|
||||
```
|
||||
|
||||
Or, if you need to modify an environment variable for a long time, you can modify the `config/env.ini` file.
|
||||
|
||||
`config/env.ini` is divided into three sections, `[global]` is globally effective, `[windows]`, `[macos]`, `[linux]` are only effective for the corresponding operating system.
|
||||
|
||||
For example, if you need to modify the `./configure` command for compiling PHP, you can find the `SPC_CMD_PREFIX_PHP_CONFIGURE` environment variable in the `config/env.ini` file, and then modify its value.
|
||||
|
||||
If your build conditions are more complex and require multiple `env.ini` files to switch,
|
||||
we recommend that you use the `config/env.custom.ini` file.
|
||||
In this way, you can specify your environment variables by writing additional override items
|
||||
without modifying the default `config/env.ini` file.
|
||||
|
||||
```ini
|
||||
; This is an example of `config/env.custom.ini` file,
|
||||
; we modify the `SPC_CONCURRENCY` and linux default CFLAGS passing to libs and PHP
|
||||
[global]
|
||||
SPC_CONCURRENCY=4
|
||||
|
||||
[linux]
|
||||
SPC_DEFAULT_C_FLAGS="-O3"
|
||||
```
|
||||
|
||||
## Library environment variables (Unix only)
|
||||
|
||||
Starting from 2.2.0, static-php-cli supports custom environment variables for all compilation dependent library commands of macOS, Linux, FreeBSD and other Unix systems.
|
||||
|
||||
In this way, you can adjust the behavior of compiling dependent libraries through environment variables at any time.
|
||||
For example, you can set the optimization parameters for compiling the xxx library through `xxx_CFLAGS=-O0`.
|
||||
|
||||
Of course, not every library supports the injection of environment variables.
|
||||
We currently provide three wildcard environment variables with the suffixes:
|
||||
|
||||
- `_CFLAGS`: CFLAGS for the compiler
|
||||
- `_LDFLAGS`: LDFLAGS for the linker
|
||||
- `_LIBS`: LIBS for the linker
|
||||
|
||||
The prefix is the name of the dependent library, and the specific name of the library is subject to `lib.json`.
|
||||
Among them, the library name with `-` needs to replace `-` with `_`.
|
||||
|
||||
Here is an example of an optimization option that replaces the openssl library compilation:
|
||||
|
||||
```shell
|
||||
openssl_CFLAGS="-O0"
|
||||
```
|
||||
|
||||
The library name uses the same name listed in `lib.json` and is case-sensitive.
|
||||
|
||||
::: tip
|
||||
When no relevant environment variables are specified, except for the following variables, the remaining values are empty by default:
|
||||
|
||||
| var name | var default value |
|
||||
|-----------------------|-------------------------------------------------------------------------------------------------|
|
||||
| `pkg_config_CFLAGS` | macOS: `$SPC_DEFAULT_C_FLAGS -Wimplicit-function-declaration -Wno-int-conversion`, Other: empty |
|
||||
| `pkg_config_LDFLAGS` | Linux: `--static`, Other: empty |
|
||||
| `imagemagick_LDFLAGS` | Linux: `-static`, Other: empty |
|
||||
| `imagemagick_LIBS` | macOS: `-liconv`, Other: empty |
|
||||
| `ldap_LDFLAGS` | `-L$BUILD_LIB_PATH` |
|
||||
| `openssl_CFLAGS` | Linux: `$SPC_DEFAULT_C_FLAGS`, Other: empty |
|
||||
| others... | empty |
|
||||
:::
|
||||
|
||||
The following table is a list of library names that support customizing the above three variables:
|
||||
|
||||
| lib name |
|
||||
|-------------|
|
||||
| brotli |
|
||||
| bzip |
|
||||
| curl |
|
||||
| freetype |
|
||||
| gettext |
|
||||
| gmp |
|
||||
| imagemagick |
|
||||
| ldap |
|
||||
| libargon2 |
|
||||
| libavif |
|
||||
| libcares |
|
||||
| libevent |
|
||||
| openssl |
|
||||
|
||||
::: tip
|
||||
Because adapting custom environment variables to each library is a particularly tedious task,
|
||||
and in most cases you do not need custom environment variables for these libraries,
|
||||
so we currently only support custom environment variables for some libraries.
|
||||
|
||||
If the library you need to customize environment variables is not listed above,
|
||||
you can submit your request through [GitHub Issue](https://github.com/crazywhalecc/static-php-cli/issues).
|
||||
:::
|
||||
<!-- TODO: Full table of all env vars supported by config/env.ini and config/env.custom.ini.
|
||||
Migrate and update from v2 env-vars.md. -->
|
||||
|
||||
@@ -1,168 +1,3 @@
|
||||
# Extension Notes
|
||||
|
||||
Because it is a static compilation, extensions will not compile 100% perfectly,
|
||||
and different extensions have different requirements for PHP and the environment,
|
||||
which will be listed one by one here.
|
||||
|
||||
## curl
|
||||
|
||||
HTTP3 support is not enabled by default, compile with `--with-libs="nghttp2,nghttp3,ngtcp2"` to enable HTTP3 support for PHP >= 8.4.
|
||||
|
||||
When using curl to request HTTPS, there may be an `error:80000002:system library::No such file or directory` error.
|
||||
For details on the solution, see [FAQ - Unable to use ssl](../faq/#unable-to-use-ssl).
|
||||
|
||||
## phpmicro
|
||||
|
||||
1. Only PHP >= 8.0 is supported.
|
||||
|
||||
## swoole
|
||||
|
||||
1. swoole >= 5.0 Only PHP >= 8.0 is supported.
|
||||
2. swoole Currently, curl hooks are not supported for PHP 8.0.x (which may be fixed in the future).
|
||||
3. When compiling, if only `swoole` extension is included, the supported Swoole database coroutine hook will not be fully enabled.
|
||||
If you need to use it, please add the corresponding `swoole-hook-xxx` extension.
|
||||
4. The `zend_mm_heap corrupted` problem may occur in swoole under some extension combinations. The cause has not yet been found.
|
||||
|
||||
## swoole-hook-pgsql
|
||||
|
||||
swoole-hook-pgsql is not an extension, it's a Hook feature of Swoole.
|
||||
If you use `swoole,swoole-hook-pgsql`, you will enable Swoole's PostgreSQL client and the coroutine mode of the `pdo_pgsql` extension.
|
||||
|
||||
swoole-hook-pgsql conflicts with the `pdo_pgsql` extension. If you want to use Swoole and `pdo_pgsql`, please delete the pdo_pgsql extension and enable `swoole` and `swoole-hook-pgsql`.
|
||||
This extension contains an implementation of the coroutine environment for `pdo_pgsql`.
|
||||
|
||||
On macOS systems, `pdo_pgsql` may not be able to connect to the postgresql server normally, please use it with caution.
|
||||
|
||||
## swoole-hook-mysql
|
||||
|
||||
swoole-hook-mysql is not an extension, it's a Hook feature of Swoole.
|
||||
If you use `swoole,swoole-hook-mysql`, you will enable the coroutine mode of Swoole's `mysqlnd` and `pdo_mysql`.
|
||||
|
||||
## swoole-hook-sqlite
|
||||
|
||||
swoole-hook-sqlite is not an extension, it's a Hook feature of Swoole.
|
||||
If you use `swoole,swoole-hook-sqlite`, you will enable the coroutine mode of Swoole's `pdo_sqlite` (Swoole must be 5.1 or above).
|
||||
|
||||
swoole-hook-sqlite conflicts with the `pdo_sqlite` extension. If you want to use Swoole and `pdo_sqlite`, please delete the pdo_sqlite extension and enable `swoole` and `swoole-hook-sqlite`.
|
||||
This extension contains an implementation of the coroutine environment for `pdo_sqlite`.
|
||||
|
||||
## swoole-hook-odbc
|
||||
|
||||
swoole-hook-odbc is not an extension, it's a Hook feature of Swoole.
|
||||
If you use `swoole,swoole-hook-odbc`, you will enable the coroutine mode of Swoole's `odbc` extension.
|
||||
|
||||
swoole-hook-odbc conflicts with the `pdo_odbc` extension. If you want to use Swoole and `pdo_odbc`, please delete the `pdo_odbc` extension and enable `swoole` and `swoole-hook-odbc`.
|
||||
This extension contains an implementation of the coroutine environment for `pdo_odbc`.
|
||||
|
||||
## swow
|
||||
|
||||
1. Only PHP 8.0+ is supported.
|
||||
|
||||
## imagick
|
||||
|
||||
1. OpenMP support is disabled, this is recommended by the maintainers and also the case system packages.
|
||||
|
||||
## imap
|
||||
|
||||
1. Kerberos is not supported
|
||||
2. ext-imap is not thread safe due to the underlying c-client. It's not possible to use it in `--enable-zts` builds.
|
||||
3. The extension was dropped from php 8.4, we recommend you look for an alternative implementation, such as [Webklex/php-imap](https://github.com/Webklex/php-imap)
|
||||
|
||||
## gd
|
||||
|
||||
1. gd Extension relies on more additional Graphics library. By default,
|
||||
using `bin/spc build gd` directly will not support some Graphics library, such as `libjpeg`, `libavif`, etc.
|
||||
Currently, it supports four libraries: `freetype,libjpeg,libavif,libwebp`.
|
||||
Therefore, the following command can be used to introduce them into the gd library:
|
||||
|
||||
```bash
|
||||
bin/spc build gd --with-libs=freetype,libjpeg,libavif,libwebp --build-cli
|
||||
```
|
||||
|
||||
## mcrypt
|
||||
|
||||
1. Currently not supported, and this extension will not be supported in the future. [#32](https://github.com/crazywhalecc/static-php-cli/issues/32)
|
||||
|
||||
## oci8
|
||||
|
||||
1. oci8 is an extension of the Oracle database, because the library on which the extension provided by Oracle does not provide a statically compiled version (`.a`) or source code,
|
||||
and this extension cannot be compiled into php by static linking, so it cannot be supported.
|
||||
|
||||
## xdebug
|
||||
|
||||
1. Xdebug is only buildable as a shared extension. On Linux, you'll need to use a SPC_TARGET like `native-native -dynamic` or `native-native-gnu`.
|
||||
2. When using Linux/glibc or macOS, you can compile Xdebug as a shared extension using --build-shared="xdebug".
|
||||
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
|
||||
|
||||
## xml
|
||||
|
||||
1. xml includes xml, xmlreader, xmlwriter, xsl, dom, simplexml, etc.
|
||||
When adding xml extensions, it is best to enable these extensions at the same time.
|
||||
2. libxml is included in xml extension. Enabling xml is equivalent to enabling libxml.
|
||||
|
||||
## glfw
|
||||
|
||||
1. glfw depends on OpenGL, and linux environment also needs X11, which cannot be linked statically.
|
||||
2. macOS platform, we can compile and link system builtin OpenGL and related libraries dynamically.
|
||||
|
||||
## rar
|
||||
|
||||
1. The rar extension currently has a problem when compiling phpmicro with the `common` extension collection in the macOS x86_64 environment.
|
||||
|
||||
## pgsql
|
||||
|
||||
~~pgsql ssl connection is not compatible with openssl 3.2.0. See:~~
|
||||
|
||||
- ~~<https://github.com/Homebrew/homebrew-core/issues/155651>~~
|
||||
- ~~<https://github.com/Homebrew/homebrew-core/pull/155699>~~
|
||||
- ~~<https://github.com/postgres/postgres/commit/c82207a548db47623a2bfa2447babdaa630302b9>~~
|
||||
|
||||
pgsql 16.2 has fixed this bug, now it's working.
|
||||
|
||||
When pgsql uses SSL connection, there may be `error:80000002:system library::No such file or directory` error,
|
||||
For details on the solution, see [FAQ - Unable to use ssl](../faq/#unable-to-use-ssl).
|
||||
|
||||
## openssl
|
||||
|
||||
When using openssl-based extensions (such as curl, pgsql and other network libraries),
|
||||
there may be an `error:80000002:system library::No such file or directory` error.
|
||||
For details on the solution, see [FAQ - Unable to use ssl](../faq/#unable-to-use-ssl).
|
||||
|
||||
## password-argon2
|
||||
|
||||
1. password-argon2 is not a standard extension. The algorithm `PASSWORD_ARGON2ID` for the `password_hash` function needs libsodium or libargon2 to work.
|
||||
2. using password-argon2 enables multithread support for this.
|
||||
|
||||
## ffi
|
||||
|
||||
1. Due to the limitation of musl libc's static linkage, you cannot use ffi because dynamic libraries cannot be loaded.
|
||||
If you need to use the ffi extension, see [Compile PHP with GNU libc](./build-with-glibc).
|
||||
2. macOS supports the ffi extension, but errors will occur when some kernels do not contain debugging symbols.
|
||||
3. Windows x64 supports the ffi extension.
|
||||
|
||||
## xhprof
|
||||
|
||||
The xhprof extension consists of three parts: `xhprof_extension`, `xhprof_html`, `xhprof_libs`.
|
||||
Only `xhprof_extension` is included in the compiled binary.
|
||||
If you need to use xhprof,
|
||||
please download the source code from [pecl.php.net/package/xhprof](http://pecl.php.net/package/xhprof) and specify the `xhprof_libs` and `xhprof_html` paths for use.
|
||||
|
||||
## event
|
||||
|
||||
If you enable event extension on macOS, the `openpty` will be disabled due to issue:
|
||||
|
||||
- [static-php-cli#335](https://github.com/crazywhalecc/static-php-cli/issues/335)
|
||||
|
||||
## parallel
|
||||
|
||||
Parallel is only supported on PHP 8.0 ZTS and above.
|
||||
|
||||
## spx
|
||||
|
||||
1. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx).
|
||||
|
||||
## mimalloc
|
||||
|
||||
1. This is not technically an extension, but a library.
|
||||
2. Building with `--with-libs="mimalloc"` on Linux or macOS will override the default allocator.
|
||||
3. This is experimental for now, but is recommended in threaded environments.
|
||||
<!-- TODO: Migrate and update from v2 extension-notes.md. Per-extension special compilation notes. -->
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
<script setup>
|
||||
import SearchTable from "../../.vitepress/components/SearchTable.vue";
|
||||
</script>
|
||||
# Supported Extensions
|
||||
|
||||
# Extensions
|
||||
|
||||
> - `yes`: supported
|
||||
> - _blank_: not supported yet, or WIP
|
||||
> - `no` with issue link: confirmed to be unavailable due to issue
|
||||
> - `partial` with issue link: supported but not perfect due to issue
|
||||
|
||||
<search-table />
|
||||
|
||||
::: tip
|
||||
If an extension you need is missing, you can create a [Feature Request](https://github.com/crazywhalecc/static-php-cli/issues).
|
||||
|
||||
Some extensions or libraries that the extension depends on will have some optional features.
|
||||
For example, the gd library optionally supports libwebp, freetype, etc.
|
||||
If you only use `bin/spc build gd --build-cli` they will not be included (static-php-cli defaults to the minimum dependency principle).
|
||||
|
||||
For more information about optional libraries, see [Extensions, Library Dependency Map](./deps-map).
|
||||
For optional libraries, you can also select an extension from the [Command Generator](./cli-generator) and then select optional libraries.
|
||||
:::
|
||||
<!-- TODO: Auto-generated by `bin/spc dev:gen-ext-docs`. Placeholder until command is implemented in v3. -->
|
||||
|
||||
190
docs/en/guide/first-build.md
Normal file
190
docs/en/guide/first-build.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 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:
|
||||
|
||||
| Approach | When to use |
|
||||
|---|---|
|
||||
| `craft` (one-shot) | Everyday use, getting started quickly |
|
||||
| Step-by-step | CI/CD pipelines, when you need to separate download and build phases |
|
||||
|
||||
## Option 1: One-Shot Build with `craft` (Recommended)
|
||||
|
||||
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.4
|
||||
extensions: bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer
|
||||
sapi:
|
||||
- cli
|
||||
- micro
|
||||
```
|
||||
|
||||
Not sure which extensions you need? Use the [command generator](./cli-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/`:
|
||||
|
||||
| SAPI | Output path |
|
||||
|---|---|
|
||||
| cli | `buildroot/bin/php` (Windows: `buildroot/bin/php.exe`) |
|
||||
| fpm | `buildroot/bin/php-fpm` |
|
||||
| micro | `buildroot/bin/micro.sfx` |
|
||||
| embed | `buildroot/lib/libphp.a` |
|
||||
| frankenphp | `buildroot/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
|
||||
|
||||
```bash
|
||||
# Download only what the chosen extensions need (recommended)
|
||||
spc download --for-extensions=bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer --with-php=8.4
|
||||
|
||||
# Download by specific libraries
|
||||
spc download --for-libs=curl,openssl --with-php=8.4
|
||||
```
|
||||
|
||||
Downloads are cached in `downloads/` and reused across builds automatically.
|
||||
|
||||
```bash
|
||||
# Slow connection? Increase parallelism and retries
|
||||
spc download --for-extensions=bcmath,openssl,curl -P 4 --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,posix,phar,zlib,openssl,curl,fileinfo,tokenizer --build-cli
|
||||
|
||||
# Build multiple SAPIs in one go
|
||||
spc build:php bcmath,posix,phar,zlib,openssl,curl --build-cli --build-micro
|
||||
|
||||
# Build all SAPIs
|
||||
spc build:php bcmath,posix,phar,zlib,openssl,curl --build-all
|
||||
```
|
||||
|
||||
`build:php` will automatically fetch any missing dependencies before building. If you already ran `download`, pass `--no-download` to skip that step:
|
||||
|
||||
```bash
|
||||
spc build:php bcmath,openssl,curl --build-cli --no-download
|
||||
```
|
||||
|
||||
#### Common Build Options
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| `--build-cli` | Build the cli SAPI |
|
||||
| `--build-fpm` | Build php-fpm (not available on Windows) |
|
||||
| `--build-micro` | Build micro.sfx |
|
||||
| `--build-embed` | Build the embed SAPI (not available on Windows) |
|
||||
| `--build-frankenphp` | Build FrankenPHP (not available on Windows) |
|
||||
| `--build-all` | Build all SAPIs |
|
||||
| `--enable-zts` | Enable thread-safe (ZTS) mode |
|
||||
| `--no-strip` | Keep debug symbols; do not strip the binary |
|
||||
| `-I key=value` | Hard-compile an INI option into PHP |
|
||||
| `--with-upx-pack` | Compress 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-all -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
|
||||
```
|
||||
|
||||
- `-v` shows `INFO`-level logs: which modules are running and what build commands are being executed.
|
||||
- `-vv` shows `DEBUG`-level logs: all internal debug output from StaticPHP.
|
||||
- `-vvv` shows `DEBUG`-level logs and also pipes the stdout of every shell command directly to your terminal.
|
||||
|
||||
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](https://github.com/static-php/static-php-cli/issues) and include your `craft.yml` (if any) and a zip of the `log/` directory.
|
||||
|
||||
## What's Next
|
||||
|
||||
- [CLI Reference](./cli-reference) — Full documentation for every command and option
|
||||
- [Extensions](./extensions) — Browse supported extensions and their dependencies
|
||||
- [Troubleshooting](./troubleshooting) — Diagnose common build failures
|
||||
|
||||
@@ -1,50 +1,45 @@
|
||||
# Guide
|
||||
|
||||
Static php cli is a tool used to build statically compiled PHP binaries,
|
||||
currently supporting Linux and macOS systems.
|
||||
## What is StaticPHP?
|
||||
|
||||
In the guide section, you will learn how to use static php cli to build standalone PHP programs.
|
||||
StaticPHP is a build tool that compiles the PHP interpreter together with any extensions you need into a single self-contained binary. The target system doesn't need PHP or any runtime libraries installed — just copy the binary and run it. Builds target Linux, macOS, and Windows.
|
||||
|
||||
- [Build (local)](./manual-build)
|
||||
- [Build (GitHub Actions)](./action-build)
|
||||
- [Supported Extensions](./extensions)
|
||||
## Why bother with a static PHP binary?
|
||||
|
||||
## Compilation Environment
|
||||
A typical PHP installation is tightly coupled to the system: you install PHP, then extensions, then spend time dealing with version mismatches across distros. A static binary sidesteps all of that — what you get is a single executable that runs on any machine of the same architecture, no setup required.
|
||||
|
||||
The following is the architecture support situation, where :gear: represents support for GitHub Action build,
|
||||
:computer: represents support for local manual build, and empty represents temporarily not supported.
|
||||
Common use cases:
|
||||
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|-------------------|-------------------|
|
||||
| macOS | :gear: :computer: | :gear: :computer: |
|
||||
| Linux | :gear: :computer: | :gear: :computer: |
|
||||
| Windows | :gear: :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
- **Distributing CLI tools** — Ship tools like Composer, PHPStan, or your own CLI as a single file. Users don't need PHP installed.
|
||||
- **Leaner containers** — Replace a bloated `php:8.x` base image with a minimal image (or even `FROM scratch`) carrying just a static binary.
|
||||
- **Server applications** — Build a static binary with FPM or FrankenPHP baked in. Deployment becomes a file copy, with no dependency on the host environment.
|
||||
|
||||
Current supported PHP versions for compilation:
|
||||
## phpmicro: ship PHP and your code as one file
|
||||
|
||||
> :warning: Partial support, there may be issues with new beta versions and old versions.
|
||||
>
|
||||
> :heavy_check_mark: Supported
|
||||
>
|
||||
> :x: Not supported
|
||||
[phpmicro](https://github.com/easysoft/phpmicro) is a third-party PHP SAPI that StaticPHP supports out of the box. It merges the PHP interpreter with your `.php` source or `.phar` archive into a single self-extracting executable (`.sfx`).
|
||||
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|-------------------------------------------------------------------------------------------------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :x: | phpmicro and many extensions do not support 7.3, 7.4 versions |
|
||||
| 7.4 | :x: | phpmicro and many extensions do not support 7.3, 7.4 versions |
|
||||
| 8.0 | :warning: | PHP official has stopped maintaining 8.0, we no longer handle 8.0 related backport support |
|
||||
| 8.1 | :warning: | PHP official only provides security updates for 8.1, we no longer handle 8.1 related backport support after 8.5 release |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
| 8.4 | :heavy_check_mark: | |
|
||||
| 8.5 (beta) | :warning: | PHP 8.5 is currently in beta stage |
|
||||
```
|
||||
micro.sfx + your-app.phar = your-app # one file, zero dependencies
|
||||
```
|
||||
|
||||
> This table shows the support status of static-php-cli for building corresponding versions, not the PHP official support status for that version.
|
||||
This is ideal for distributing PHP-based CLI tools: the end user just gets an ordinary executable with no idea PHP is involved.
|
||||
|
||||
## PHP Support Versions
|
||||
## Improving how you ship and deploy PHP projects
|
||||
|
||||
Currently, static-php-cli supports PHP versions 8.2 ~ 8.5, and theoretically supports PHP 8.1 and earlier versions, just select the earlier version when downloading.
|
||||
However, due to some extensions and special components that have stopped supporting earlier versions of PHP, static-php-cli will not explicitly support earlier versions.
|
||||
We recommend that you compile the latest PHP version possible for a better experience.
|
||||
**Drop the heavy Docker base image**
|
||||
|
||||
The official `php:8.x` image can be hundreds of megabytes, most of which is just the PHP runtime. Swap it for a static PHP binary with a minimal base image — or `FROM scratch` — and you can get container sizes down to single-digit megabytes with noticeably faster startup times.
|
||||
|
||||
**Ship PHP CLI tools like native binaries**
|
||||
|
||||
Build your CLI with [symfony/console](https://symfony.com/doc/current/components/console.html) or [Laravel Zero](https://laravel-zero.com), bundle it into a `.phar` with [Box](https://github.com/box-project/box), then merge it with phpmicro. The result is a single distributable executable — the same experience users expect from Go or Rust tools, with no PHP runtime required on their end.
|
||||
|
||||
**Single-file web apps with FrankenPHP**
|
||||
|
||||
[FrankenPHP](https://frankenphp.dev) is a modern PHP app server with built-in HTTP/2, HTTP/3, and automatic HTTPS. StaticPHP can compile FrankenPHP together with your chosen extensions into one binary. The result is a complete web server in a single file — no Nginx, no PHP-FPM, just deploy and run.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Installation](./installation) — Get the StaticPHP build tool
|
||||
- [First Build](./first-build) — Full walkthrough: from downloading sources to a working executable
|
||||
- [CLI Reference](./cli-reference) — Every command and option, in one place
|
||||
|
||||
121
docs/en/guide/installation.md
Normal file
121
docs/en/guide/installation.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Installation
|
||||
|
||||
## Requirements
|
||||
|
||||
| Platform | Architecture | Notes |
|
||||
|---|---|---|
|
||||
| Linux | x86_64, aarch64 | Major distros supported (Alpine, Debian/Ubuntu, RHEL/CentOS, etc.) |
|
||||
| macOS | x86_64 (Intel), arm64 (Apple Silicon) | macOS 12 or later |
|
||||
| Windows | x86_64 | Windows 10 Build 17063 or later |
|
||||
|
||||
::: tip
|
||||
Both glibc-based distros (Debian, Ubuntu, Arch, etc.) and musl-based ones (Alpine) are supported on Linux.
|
||||
The `doctor` command will detect your environment and guide you through installing the right toolchain if needed.
|
||||
:::
|
||||
|
||||
Pick the installation method that fits your use case:
|
||||
|
||||
| Method | Best for |
|
||||
|---|---|
|
||||
| Pre-built binary | Most users — download and run, no dependencies |
|
||||
| From source | Contributors, or anyone who needs to modify core build logic |
|
||||
| Vendor mode | Integrating StaticPHP into an existing PHP project |
|
||||
|
||||
## Pre-built binary
|
||||
|
||||
`spc` has no runtime dependencies — download the binary for your platform and it's ready to go.
|
||||
|
||||
> Fun fact: `spc` itself is a static PHP binary built with StaticPHP. We use StaticPHP to build StaticPHP's own build tool.
|
||||
|
||||
```shell
|
||||
# Linux x86_64
|
||||
curl -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-linux-x86_64 -o spc
|
||||
# Linux arm64
|
||||
curl -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-linux-aarch64 -o spc
|
||||
# macOS x86_64 (Intel)
|
||||
curl -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-macos-x86_64 -o spc
|
||||
# macOS arm64 (Apple Silicon)
|
||||
curl -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-macos-aarch64 -o spc
|
||||
# Windows x86_64 (PowerShell)
|
||||
curl.exe -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x86_64.exe -o spc.exe
|
||||
```
|
||||
|
||||
On Linux and macOS, mark the binary as executable before running it:
|
||||
|
||||
```bash
|
||||
chmod +x spc && ./spc --version
|
||||
```
|
||||
|
||||
## From source
|
||||
|
||||
This is the right path if you want to contribute to StaticPHP, or need to modify the core registry and build scripts. You'll need PHP >= 8.4, Composer, and the `mbstring,posix,pcntl,iconv,phar,zlib` extensions.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/crazywhalecc/static-php-cli.git --branch v3
|
||||
cd static-php-cli
|
||||
composer install
|
||||
```
|
||||
|
||||
If you don't have PHP or Composer installed, use the bundled setup script to install a self-contained runtime:
|
||||
|
||||
::: code-group
|
||||
```bash [Linux / macOS]
|
||||
bin/setup-runtime
|
||||
```
|
||||
```powershell [Windows]
|
||||
.\bin\setup-runtime.ps1
|
||||
.\bin\setup-runtime.ps1 add-path # add runtime/ to PATH
|
||||
```
|
||||
:::
|
||||
|
||||
The script downloads `php` and `composer` into a `runtime/` subdirectory. You then have two options:
|
||||
|
||||
1. **Call them directly** (no PATH changes needed):
|
||||
```bash
|
||||
runtime/php bin/spc --help
|
||||
runtime/php runtime/composer install
|
||||
```
|
||||
|
||||
2. **Add `runtime/` to your PATH** so you can use `php`, `composer`, and `bin/spc` without prefixes:
|
||||
```bash
|
||||
export PATH="/path/to/static-php-cli/runtime:$PATH"
|
||||
# Add this to ~/.bashrc or ~/.zshrc to make it permanent
|
||||
```
|
||||
|
||||
::: tip
|
||||
In regions with restricted access to GitHub or getcomposer.org, pass `--mirror china` to use a mirror:
|
||||
```bash
|
||||
bin/setup-runtime --mirror china
|
||||
```
|
||||
:::
|
||||
|
||||
## Vendor mode
|
||||
|
||||
If you already have a PHP project and want to call StaticPHP's build APIs directly, or use a custom registry to support private libraries and extensions, pull it in as a Composer dependency:
|
||||
|
||||
```bash
|
||||
composer require crazywhalecc/static-php-cli
|
||||
```
|
||||
|
||||
See the [Vendor Mode guide](../develop/vendor-mode/) for details.
|
||||
|
||||
## Verify your build environment
|
||||
|
||||
> **Vendor mode users can skip this step.**
|
||||
|
||||
Once installed, run `doctor` to check that your system has the required build tools (cmake, make, a C compiler, etc.):
|
||||
|
||||
```bash
|
||||
# Using the spc binary
|
||||
./spc doctor
|
||||
# From source
|
||||
bin/spc doctor
|
||||
```
|
||||
|
||||
If anything is missing, `--auto-fix` will attempt to install it for you:
|
||||
|
||||
```bash
|
||||
./spc doctor --auto-fix
|
||||
```
|
||||
|
||||
Once `doctor` reports everything is good, head over to [First Build](./first-build).
|
||||
@@ -1,705 +0,0 @@
|
||||
---
|
||||
outline: 'deep'
|
||||
---
|
||||
|
||||
# Build (Linux, macOS, FreeBSD)
|
||||
|
||||
This section covers the build process for Linux, macOS, and FreeBSD. If you want to build on Windows,
|
||||
also need to read [Build on Windows](./build-on-windows).
|
||||
|
||||
### Build locally (using SPC binary) (recommended)
|
||||
|
||||
This project provides a binary file of static-php-cli.
|
||||
You can directly download the binary file of the corresponding platform and then use it to build static PHP.
|
||||
Currently, the platforms supported by `spc` binary are Linux and macOS.
|
||||
|
||||
Here's how to download from self-hosted server:
|
||||
|
||||
```bash
|
||||
# Download from self-hosted nightly builds (sync with main branch)
|
||||
# For Linux x86_64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
|
||||
# For Linux aarch64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
# Windows (x86_64, win10 build 17063 or later)
|
||||
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
|
||||
# Add execute perm (Linux and macOS only)
|
||||
chmod +x ./spc
|
||||
|
||||
# Run (Linux and macOS)
|
||||
./spc --version
|
||||
# Run (Windows powershell)
|
||||
.\spc.exe --version
|
||||
```
|
||||
|
||||
> If you are using the packaged `spc` binary, you will need to replace the leading `bin/spc` with `./spc` in all the commands below.
|
||||
|
||||
### Build locally (using source code)
|
||||
|
||||
If you have problems using the spc binary, or if you need to modify the static-php-cli source code, download static-php-cli from the source code.
|
||||
|
||||
Currently, it supports building on macOS and Linux.
|
||||
macOS supports the latest version of the operating system and two architectures,
|
||||
while Linux supports Debian and derivative distributions, as well as Alpine Linux.
|
||||
|
||||
Because this project itself is developed using PHP,
|
||||
it is also necessary to install PHP on the system during compilation.
|
||||
This project also provides static binary PHP suitable for this project,
|
||||
which can be selected and used according to actual situations.
|
||||
|
||||
```bash
|
||||
# clone repo
|
||||
git clone https://github.com/crazywhalecc/static-php-cli.git --depth=1
|
||||
cd static-php-cli
|
||||
|
||||
# You need to install the PHP environment first before running Composer and this project. The installation method can be referred to below.
|
||||
composer update
|
||||
```
|
||||
|
||||
### Use Precompiled Static PHP Binaries
|
||||
|
||||
If you don't want to use Docker and install PHP in the system,
|
||||
you can directly download the php binary cli program compiled by this project itself. The usage process is as follows:
|
||||
|
||||
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).
|
||||
|
||||
::: tip
|
||||
Using precompiled static PHP binaries is currently only supported on Linux and macOS.
|
||||
The FreeBSD environment is currently not supported due to the lack of an automated build environment.
|
||||
:::
|
||||
|
||||
```bash
|
||||
bin/setup-runtime
|
||||
|
||||
# For users with special network environments such as mainland China, you can use mirror sites (aliyun) to speed up the download speed
|
||||
bin/setup-runtime --mirror china
|
||||
```
|
||||
|
||||
This script will download two files in total: `bin/php` and `bin/composer`. After the download is complete, there are two ways to use it:
|
||||
|
||||
1. Add the `bin/` directory to the PATH: `export PATH="/path/to/your/static-php-cli/bin:$PATH"`, after adding the path,
|
||||
it is equivalent to installing PHP in the system, you can directly Use commands such as `composer`, `php -v`, or directly use `bin/spc`.
|
||||
2. Direct call, such as executing static-php-cli command: `bin/php bin/spc --help`, executing Composer: `bin/php bin/composer update`.
|
||||
|
||||
### Use Docker
|
||||
|
||||
If you don't want to install PHP and Composer runtime environment on your system, you can use the built-in Docker environment build script.
|
||||
|
||||
```bash
|
||||
# To use directly, replace `bin/spc` with `bin/spc-alpine-docker` in all used commands
|
||||
bin/spc-alpine-docker
|
||||
```
|
||||
|
||||
The first time the command is executed, `docker build` will be used to build a Docker image.
|
||||
The default built Docker image is the `x86_64` architecture, and the image name is `cwcc-spc-x86_64`.
|
||||
|
||||
If you want to build `aarch64` static-php-cli in `x86_64` environment,
|
||||
you can use qemu to emulate the arm image to run Docker, but the speed will be very slow.
|
||||
Use command: `SPC_USE_ARCH=aarch64 bin/spc-alpine-docker`.
|
||||
|
||||
If it prompts that sudo is required to run after running,
|
||||
execute the following command once to grant static-php-cli permission to execute sudo:
|
||||
|
||||
```bash
|
||||
export SPC_USE_SUDO=yes
|
||||
```
|
||||
|
||||
### Use System PHP
|
||||
|
||||
Below are some example commands for installing PHP and Composer in the system.
|
||||
It is recommended to search for the specific installation method yourself or ask the AI search engine to obtain the answer,
|
||||
which will not be elaborated here.
|
||||
|
||||
```bash
|
||||
# [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.
|
||||
brew install php wget
|
||||
wget https://getcomposer.org/download/latest-stable/composer.phar -O /path/to/your/bin/composer && chmod +x /path/to/your/bin/composer
|
||||
|
||||
# [Debian], you need to make sure your php version >= 8.1 and composer >= 2.0
|
||||
sudo apt install php-cli composer php-tokenizer
|
||||
|
||||
# [Alpine]
|
||||
apk add bash file wget xz php81 php81-common php81-pcntl php81-tokenizer php81-phar php81-posix php81-xml composer
|
||||
```
|
||||
|
||||
::: tip
|
||||
Currently, some versions of Ubuntu install older PHP versions,
|
||||
so no installation commands are provided. If necessary, it is recommended to add software sources such as ppa first,
|
||||
and then install the latest version of PHP and tokenizer, XML, and phar extensions.
|
||||
|
||||
Older versions of Debian may have an older (<= 7.4) version of PHP installed by default, it is recommended to upgrade Debian first.
|
||||
:::
|
||||
|
||||
## Build with craft (recommended)
|
||||
|
||||
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`:
|
||||
|
||||
```yaml
|
||||
# path/to/craft.yml
|
||||
php-version: 8.4
|
||||
extensions: bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer
|
||||
sapi:
|
||||
- cli
|
||||
- fpm
|
||||
```
|
||||
|
||||
Then use the `bin/spc craft` command to compile:
|
||||
|
||||
```bash
|
||||
bin/spc craft --debug
|
||||
```
|
||||
|
||||
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).
|
||||
- frankenphp: The build result is `buildroot/bin/frankenphp`.
|
||||
|
||||
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 `./log` archive.
|
||||
|
||||
## 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.
|
||||
|
||||
### Command download - Download dependency packages
|
||||
|
||||
Use the command `bin/spc download` to download the source code required for compilation,
|
||||
including php-src and the source code of various dependent libraries.
|
||||
|
||||
```bash
|
||||
# Download all dependencies, defaults to php 8.4
|
||||
bin/spc download --all
|
||||
|
||||
# Download all dependent packages, and specify the main version of PHP to download, optional: 8.1, 8.2, 8.3, 8.4
|
||||
# Also supports specific version of php release: 8.3.10, 8.2.22, etc.
|
||||
bin/spc download --all --with-php=8.3
|
||||
|
||||
# Show download progress bar while downloading (curl)
|
||||
bin/spc download --all --debug
|
||||
|
||||
# Delete old download data
|
||||
bin/spc download --clean
|
||||
|
||||
# Download specified dependencies
|
||||
bin/spc download php-src,micro,zstd,ext-zstd
|
||||
|
||||
# Download only extensions and libraries to be compiled (use extensions, including suggested libraries)
|
||||
bin/spc download --for-extensions=openssl,swoole,zip,pcntl,zstd
|
||||
|
||||
# Download resources, prefer to download dependencies with pre-built packages (reduce the time to compile dependencies)
|
||||
bin/spc download --for-extensions="curl,pcntl,xml,mbstring" --prefer-pre-built
|
||||
|
||||
# Download only the extensions and dependent libraries to be compiled (use extensions, excluding suggested libraries)
|
||||
bin/spc download --for-extensions=openssl,swoole,zip,pcntl --without-suggestions
|
||||
|
||||
# Download only libraries to be compiled (use libraries, including suggested libraries and required libraries, can use --for-extensions together)
|
||||
bin/spc download --for-libs=liblz4,libevent --for-extensions=pcntl,rar,xml
|
||||
|
||||
# Download only libraries to be compiled (use libraries, excluding suggested libraries)
|
||||
bin/spc download --for-libs=liblz4,libevent --without-suggestions
|
||||
|
||||
# When downloading sources, ignore some source caches (always force download, e.g. switching PHP version)
|
||||
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3.10
|
||||
|
||||
# Set retry times (default is 0)
|
||||
bin/spc download --all --retry=2
|
||||
```
|
||||
|
||||
If the network in your area is not good, or the speed of downloading the dependency package is too slow,
|
||||
you can download `download.zip` which is packaged regularly every week from GitHub Action,
|
||||
and use the command to directly use the zip archive as a dependency.
|
||||
|
||||
Dependent packages can be downloaded locally from [Action](https://github.com/static-php/static-php-cli-hosted/actions/workflows/download-cache.yml).
|
||||
Enter Action and select the latest Workflow that has been successfully run, and download `download-files-x.y`.
|
||||
|
||||
```bash
|
||||
bin/spc download --from-zip=/path/to/your/download.zip
|
||||
```
|
||||
|
||||
If a source cannot be downloaded all the time, or you need to download some specific version of the package,
|
||||
such as downloading the beta version of PHP, the old version of the library, etc.,
|
||||
you can use the parameter `-U` or `--custom-url` to rewrite the download link,
|
||||
Make the downloader force the link you specify to download packages from this source.
|
||||
The method of use is `{source-name}:{url}`, which can rewrite the download URLs of multiple libraries at the same time.
|
||||
Also, it is available when downloading with the `--for-extensions` option.
|
||||
|
||||
|
||||
```bash
|
||||
# Specifying to download a alpha version of PHP 8.5
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"
|
||||
|
||||
# Specifying to download an older version of the curl library
|
||||
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
|
||||
```
|
||||
|
||||
If the source you download is not a link, but a git repository, you can use `-G` or `--custom-git` to rewrite the download link,
|
||||
so that the downloader can force the use of the specified git repository to download packages from this source.
|
||||
The usage method is `{source-name}:{branch}:{url}`, which can rewrite the download link of multiple libraries at the same time.
|
||||
It is also available when downloading with the `--for-extensions` option.
|
||||
|
||||
```bash
|
||||
# Specifying to download the source code of the PHP extension from the specified branch of the git repository
|
||||
bin/spc download --for-extensions=redis -G "php-src:master:https://github.com/php/php-src.git"
|
||||
|
||||
# Download the latest code from the master branch of the swoole-src repository instead of PECL release version
|
||||
bin/spc download --for-extensions=swoole -G "swoole:master:https://github.com/swoole/swoole-src.git"
|
||||
```
|
||||
|
||||
### Command - doctor
|
||||
|
||||
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)
|
||||
bin/spc doctor --auto-fix
|
||||
```
|
||||
|
||||
### Command - build
|
||||
|
||||
Use the build command to start building the static php binary.
|
||||
Before executing the `bin/spc build` command, be sure to use the `download` command to download sources.
|
||||
It is recommended to use `doctor` to check the environment.
|
||||
|
||||
#### Basic build
|
||||
|
||||
You need to go to [Extension List](./extensions) or [Command Generator](./cli-generator) to select the extension you want to add,
|
||||
and then use the command `bin/spc build` to compile.
|
||||
You need to specify a compilation target, choose from the following parameters:
|
||||
|
||||
- `--build-cli`: Build a cli sapi (command line interface, which can execute PHP code on the command line)
|
||||
- `--build-fpm`: Build a fpm sapi (php-fpm, used in conjunction with other traditional fpm architecture software such as nginx)
|
||||
- `--build-cgi`: Build a cgi sapi (cgi, rarely used)
|
||||
- `--build-micro`: Build a micro sapi (used to build a standalone executable binary containing PHP code)
|
||||
- `--build-embed`: Build an embed sapi (used to embed into other C language programs)
|
||||
- `--build-frankenphp`: Build a [FrankenPHP](https://github.com/php/frankenphp) executable
|
||||
- `--build-all`: build all above sapi
|
||||
|
||||
```bash
|
||||
# Compile PHP with bcmath,curl,openssl,ftp,posix,pcntl extensions, the compilation target is cli
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
|
||||
# Compile PHP with phar,curl,posix,pcntl,tokenizer extensions, compile target is micro
|
||||
bin/spc build phar,curl,posix,pcntl,tokenizer --build-micro
|
||||
```
|
||||
|
||||
::: tip
|
||||
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:
|
||||
|
||||
```shell
|
||||
# remove
|
||||
rm -rf buildroot source
|
||||
# build again
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
```
|
||||
:::
|
||||
|
||||
::: tip
|
||||
If you want to build multiple versions of PHP and don't want to build other dependent libraries repeatedly each time,
|
||||
you can use `switch-php-version` to quickly switch to another version and compile after compiling one version:
|
||||
|
||||
```shell
|
||||
# switch to 8.4
|
||||
bin/spc switch-php-version 8.4
|
||||
# build
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
# switch to 8.1
|
||||
bin/spc switch-php-version 8.1
|
||||
# build
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
```
|
||||
:::
|
||||
|
||||
#### Build Options
|
||||
|
||||
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
|
||||
- `--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)
|
||||
- `--build-shared=XXX,YYY`: compile the specified extension into a shared library (the default is to compile into a static library)
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
bin/spc build bcmath,pcntl,posix --build-all -I "memory_limit=4G" -I "disable_functions=system"
|
||||
```
|
||||
|
||||
## Debug
|
||||
|
||||
If you encounter problems during the compilation process, or want to view each executing shell command,
|
||||
you can use `--debug` to enable debug mode and view all terminal logs:
|
||||
|
||||
```bash
|
||||
bin/spc build mysqlnd,pdo_mysql --build-all --debug
|
||||
```
|
||||
|
||||
## Command - micro:combine
|
||||
|
||||
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
|
||||
bin/spc micro:combine a.app --with-micro=/path/to/your/micro.sfx
|
||||
```
|
||||
|
||||
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)
|
||||
bin/spc micro:combine a.php -N /path/to/your/custom.ini
|
||||
```
|
||||
|
||||
::: warning
|
||||
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
|
||||
bin/spc extract php-src,libxml2
|
||||
```
|
||||
|
||||
## Command - dump-extensions
|
||||
|
||||
Use the command `bin/spc dump-extensions` to export required extensions of the current project.
|
||||
|
||||
```bash
|
||||
# Print the extension list of the project, pass in the root directory of the project containing composer.json
|
||||
bin/spc dump-extensions /path/to/your/project/
|
||||
|
||||
# Print the extension list of the project, excluding development dependencies
|
||||
bin/spc dump-extensions /path-to/tour/project/ --no-dev
|
||||
|
||||
# Output in the extension list format acceptable to the spc command (comma separated)
|
||||
bin/spc dump-extensions /path-to/tour/project/ --format=text
|
||||
|
||||
# Output as a JSON list
|
||||
bin/spc dump-extensions /path-to/tour/project/ --format=json
|
||||
|
||||
# When the project does not have any extensions, output the specified extension combination instead of returning failure
|
||||
bin/spc dump-extensions /path-to/your/project/ --no-ext-output=mbstring,posix,pcntl,phar
|
||||
|
||||
# Do not exclude extensions not supported by spc when outputting
|
||||
bin/spc dump-extensions /path/to/your/project/ --no-spc-filter
|
||||
```
|
||||
It should be noted that the project directory must contain the `vendor/installed.json` and `composer.lock` files, otherwise they cannot be found normally.
|
||||
|
||||
## Dev Command - dev
|
||||
|
||||
Debug commands refer to a collection of commands that can assist in outputting some information
|
||||
when you use static-php-cli to build PHP or modify and enhance the static-php-cli project itself.
|
||||
|
||||
- `dev:extensions`: output all currently supported extension names, or output the specified extension information
|
||||
- `dev:php-version`: output the currently compiled PHP version (by reading `php_version.h`)
|
||||
- `dev:sort-config`: Sort the list of configuration files in the `config/` directory in alphabetical order
|
||||
- `dev:lib-ver <lib-name>`: Read the version from the source code of the dependency library (only available for specific dependency libraries)
|
||||
- `dev:ext-ver <ext-name>`: Read the corresponding version from the source code of the extension (only available for specific extensions)
|
||||
- `dev:pack-lib <lib-name>`: Package the specified library into a tar.gz file (maintainer only)
|
||||
- `dev:gen-ext-docs`: Generate extension documentation (maintainer only)
|
||||
|
||||
```bash
|
||||
# output all extensions information
|
||||
bin/spc dev:extensions
|
||||
|
||||
# Output the meta information of the specified extension
|
||||
bin/spc dev:extensions mongodb,curl,openssl
|
||||
|
||||
# Output the specified columns
|
||||
# Available column name: lib-depends, lib-suggests, ext-depends, ext-suggests, unix-only, type
|
||||
bin/spc dev:extensions --columns=lib-depends,type,ext-depends
|
||||
|
||||
# Output the currently compiled PHP version
|
||||
# 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`
|
||||
- Download and install nasm (Windows only): `bin/spc install-pkg nasm`
|
||||
- Download and install go-xcaddy: `bin/spc install-pkg go-xcaddy`
|
||||
|
||||
## 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:
|
||||
|
||||
| Event name | Event description |
|
||||
|---------------------------------|----------------------------------------------------------------------------------------------------|
|
||||
| before-libs-extract | Triggered before the dependent libraries extracted |
|
||||
| after-libs-extract | Triggered after the compiled dependent libraries extracted |
|
||||
| before-php-extract | Triggered before PHP source code extracted |
|
||||
| after-php-extract | Triggered after PHP source code extracted |
|
||||
| before-micro-extract | Triggered before phpmicro extract |
|
||||
| after-micro-extract | Triggered after phpmicro extracted |
|
||||
| before-exts-extract | Triggered before the extension (to be compiled) extracted to the PHP source directory |
|
||||
| after-exts-extract | Triggered after the extension extracted to the PHP source directory |
|
||||
| before-library[*name*]-build | Triggered before the library named `name` is compiled (such as `before-library[postgresql]-build`) |
|
||||
| after-library[*name*]-build | Triggered after the library named `name` is compiled |
|
||||
| after-shared-ext[*name*]-build | Triggered after the shared extension named `name` is compiled |
|
||||
| before-shared-ext[*name*]-build | Triggered before the shared extension named `name` is compiled |
|
||||
| before-php-buildconf | Triggered before compiling PHP command `./buildconf` |
|
||||
| before-php-configure | Triggered before compiling PHP command `./configure` |
|
||||
| before-php-make | Triggered before compiling PHP command `make` |
|
||||
| before-sanity-check | Triggered after compiling PHP but before running extended checks |
|
||||
|
||||
The following is a simple example of temporarily modifying the PHP source code.
|
||||
Enable the CLI function to search for the `php.ini` configuration in the current working directory:
|
||||
|
||||
```php
|
||||
// a.php
|
||||
<?php
|
||||
// patch it before `./buildconf` executed
|
||||
if (patch_point() === 'before-php-buildconf') {
|
||||
\SPC\store\FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/sapi/cli/php_cli.c',
|
||||
'sapi_module->php_ini_ignore_cwd = 1;',
|
||||
'sapi_module->php_ini_ignore_cwd = 0;'
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
bin/spc build mbstring --build-cli -P a.php
|
||||
# Write in ./
|
||||
echo 'memory_limit=8G' > ./php.ini
|
||||
```
|
||||
|
||||
```
|
||||
$ buildroot/bin/php -i | grep Loaded
|
||||
Loaded Configuration File => /Users/jerry/project/git-project/static-php-cli/php.ini
|
||||
|
||||
$ buildroot/bin/php -i | grep memory
|
||||
memory_limit => 8G => 8G
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
- `SPC\store\FileSystem`: file management class
|
||||
- `::replaceFileStr(string $filename, string $search, $replace)`: Replace file string content
|
||||
- `::replaceFileStr(string $filename, string $pattern, $replace)`: Regularly replace file content
|
||||
- `::replaceFileUser(string $filename, $callback)`: User-defined function replaces file content
|
||||
- `::copyDir(string $from, string $to)`: Recursively copy a directory to another location
|
||||
- `::convertPath(string $path)`: Convert the path delimiter to the current system delimiter
|
||||
- `::scanDirFiles(string $dir, bool $recursive = true, bool|string $relative = false, bool $include_dir = false)`: Traverse directory files
|
||||
- `SPC\builder\BuilderBase`: Build object
|
||||
- `->getPatchPoint()`: Get the current injection point name
|
||||
- `->getOption(string $key, $default = null)`: Get command line and compile-time options
|
||||
- `->getPHPVersionID()`: Get the currently compiled PHP version ID
|
||||
- `->getPHPVersion()`: Get the currently compiled PHP version number
|
||||
- `->setOption(string $key, $value)`: Set options
|
||||
- `->setOptionIfNotExists(string $key, $value)`: Set option if option does not exist
|
||||
|
||||
::: tip
|
||||
static-php-cli has many open methods, which cannot be listed in the docs,
|
||||
but as long as it is a `public function` and is not marked as `@internal`, it theoretically can be called.
|
||||
:::
|
||||
|
||||
## Multiple builds
|
||||
|
||||
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.
|
||||
|
||||
## embed usage
|
||||
|
||||
If you want to embed static-php into other C language programs, you can use `--build-embed` to build an embed version of PHP.
|
||||
|
||||
```bash
|
||||
bin/spc build {your extensions} --build-embed --debug
|
||||
```
|
||||
|
||||
Under normal circumstances, PHP embed will generate `php-config` after compilation.
|
||||
For static-php, we provide `spc-config` to obtain the parameters during compilation.
|
||||
In addition, when using embed SAPI (libphp.a), you need to use the same compiler as libphp, otherwise there will be a link error.
|
||||
|
||||
Here is the basic usage of spc-config:
|
||||
|
||||
```bash
|
||||
# output all flags and options
|
||||
bin/spc spc-config curl,zlib,phar,openssl
|
||||
|
||||
# output libs
|
||||
bin/spc spc-config curl,zlib,phar,openssl --libs
|
||||
|
||||
# output includes
|
||||
bin/spc spc-config curl,zlib,phar,openssl --includes
|
||||
```
|
||||
|
||||
By default, static-php uses the following compilers on different systems:
|
||||
|
||||
- macOS: `clang`
|
||||
- Linux (Alpine Linux): `gcc`
|
||||
- Linux (glibc based distros, x86_64): `/usr/local/musl/bin/x86_64-linux-musl-gcc`
|
||||
- Linux (glibc based distros, aarch64): `/usr/local/musl/bin/aarch64-linux-musl-gcc`
|
||||
- FreeBSD: `clang`
|
||||
|
||||
Here is an example of using embed SAPI:
|
||||
|
||||
```c
|
||||
// embed.c
|
||||
#include <sapi/embed/php_embed.h>
|
||||
|
||||
int main(int argc,char **argv){
|
||||
|
||||
PHP_EMBED_START_BLOCK(argc,argv)
|
||||
|
||||
zend_file_handle file_handle;
|
||||
|
||||
zend_stream_init_filename(&file_handle,"embed.php");
|
||||
|
||||
if(php_execute_script(&file_handle) == FAILURE){
|
||||
php_printf("Failed to execute PHP script.\n");
|
||||
}
|
||||
|
||||
PHP_EMBED_END_BLOCK()
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```php
|
||||
<?php
|
||||
// embed.php
|
||||
echo "Hello world!\n";
|
||||
```
|
||||
|
||||
```bash
|
||||
# compile in debian/ubuntu x86_64
|
||||
/usr/local/musl/bin/x86_64-linux-musl-gcc embed.c $(bin/spc spc-config bcmath,zlib) -static -o embed
|
||||
# compile in macOS/FreeBSD
|
||||
clang embed.c $(bin/spc spc-config bcmath,zlib) -o embed
|
||||
|
||||
./embed
|
||||
# out: Hello world!
|
||||
```
|
||||
@@ -1,42 +1,5 @@
|
||||
# Troubleshooting
|
||||
|
||||
Various failures may be encountered in the process of using static-php-cli,
|
||||
here will describe how to check the errors by yourself and report Issue.
|
||||
|
||||
## Download Failure
|
||||
|
||||
Problems with downloading resources are one of the most common problems with spc.
|
||||
The main reason is that the addresses used for SPC download resources are generally the official website of the corresponding project or GitHub, etc.,
|
||||
and these websites may occasionally go down and block IP addresses.
|
||||
After encountering a download failure,
|
||||
you can try to call the download command multiple times.
|
||||
|
||||
When downloading extensions, you may eventually see errors like `curl: (56) The requested URL returned error: 403` which are often caused by github rate limiting.
|
||||
You can verify this by adding `--debug` to the command and will see something like `[DEBU] Running command (no output) : curl -sfSL "https://api.github.com/repos/openssl/openssl/releases"`.
|
||||
|
||||
To fix this, [create](https://github.com/settings/tokens) a personal access token on GitHub and set it as an environment variable `GITHUB_TOKEN=<XXX>`.
|
||||
|
||||
If you confirm that the address is indeed inaccessible,
|
||||
you can submit an Issue or PR to update the url or download type.
|
||||
|
||||
## Doctor Can't Fix Something
|
||||
|
||||
In most cases, the doctor module can automatically repair and install missing system environments,
|
||||
but there are also special circumstances where the automatic repair function cannot be used normally.
|
||||
|
||||
Due to system limitations (for example, software such as Visual Studio cannot be automatically installed under Windows),
|
||||
the automatic repair function cannot be used for some projects.
|
||||
When encountering a function that cannot be automatically repaired,
|
||||
if you encounter the words `Some check items can not be fixed`,
|
||||
it means that it cannot be automatically repaired.
|
||||
Please submit an issue according to the method displayed on the terminal or repair the environment yourself.
|
||||
|
||||
## Compile Error
|
||||
|
||||
When you encounter a compilation error, if the `--debug` log is not enabled, please enable the debug log first,
|
||||
and then determine the command that reported the error.
|
||||
The error terminal output is very important for fixing compilation errors.
|
||||
When submitting an issue, please upload the last error fragment of the terminal log (or the entire terminal log output),
|
||||
and include the `spc` command and parameters used.
|
||||
|
||||
If you are rebuilding, please refer to the [Local Build - Multiple Builds](./manual-build#multiple-builds) section.
|
||||
<!-- TODO: Categorized common build failures and fixes.
|
||||
Sections: Download issues / Compilation errors / Extension conflicts / Windows-specific / glibc Linux.
|
||||
Migrate and expand from v2 troubleshooting.md. -->
|
||||
|
||||
Reference in New Issue
Block a user