mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-06 16:25:39 +08:00
Temp
This commit is contained in:
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. -->
|
||||
Reference in New Issue
Block a user