|
1 | 1 | # Package Model |
2 | 2 |
|
3 | | -<!-- TODO: Explain the unified package model: library / php-extension / target types. |
4 | | - Cover the per-package YAML format (config/pkg/), the `depends` field, |
5 | | - platform overrides (@windows / @unix notation), artifact.source and artifact.binary. |
6 | | - Show annotated example YAML for a library and an extension. --> |
| 3 | +## Package Definition |
| 4 | + |
| 5 | +A Package is the core concept in StaticPHP's build system, representing a buildable/installable unit such as a PHP extension, library, or build target. |
| 6 | + |
| 7 | +Each Package contains build information, dependencies, and build logic, forming StaticPHP's build model. Package definitions are primarily implemented through YAML/JSON configuration files. The package configuration files for the `core` registry are located in the `config/pkg/` directory, and the corresponding build classes are in the `src/Package/` directory. |
| 8 | + |
| 9 | +Packages are primarily divided into four types: |
| 10 | + |
| 11 | +- **php-extension**: A PHP extension package containing build information and logic for a PHP extension. |
| 12 | +- **library**: A library package containing build information and logic for build tools, dependency libraries, etc. |
| 13 | +- **target**: A build target package representing the final build artifact, such as a PHP binary or curl binary. Inherits from the `library` package type. |
| 14 | +- **virtual-target**: A virtual build target package representing an abstract build target that doesn't directly correspond to a build artifact, primarily used for dependency management and build scheduling. |
| 15 | + |
| 16 | +```yaml |
| 17 | +{pkg-name}: |
| 18 | + type: {pkg-type} |
| 19 | + ... |
| 20 | +``` |
| 21 | + |
| 22 | +## Artifact Definition |
| 23 | + |
| 24 | +An Artifact is a definition independent of Packages. It contains the source archive file or pre-built binary for building packages. Each Artifact defines download URLs, extraction methods, and build artifact file paths. Packages can reference one or more Artifacts via the `artifact` field to obtain the source or binaries needed for building. |
| 25 | + |
| 26 | +In simple terms, by default one Package corresponds to one Artifact; if multiple Packages share the same source, you can define a single Artifact for multiple Packages to reference. Artifact definitions are located in the `config/artifact/` directory, and the corresponding custom download/extract logic classes are in the `src/Package/Artifact/` directory. For special package types like virtual targets and PHP built-in extensions, a Package may also omit the Artifact field entirely. |
| 27 | + |
| 28 | +Assuming `example-library-package` is a dependency library whose source archive is hosted at `https://example.com/example-library.tar.gz`, its Package and Artifact definitions would look like this: |
| 29 | + |
| 30 | +```yaml |
| 31 | +example-library-package: |
| 32 | + type: library |
| 33 | + artifact: |
| 34 | + source: |
| 35 | + type: url |
| 36 | + url: 'https://example.com/example-library.tar.gz' |
| 37 | +``` |
| 38 | +
|
| 39 | +For more on Artifact definitions, see the [Artifact Model](./artifact-model) chapter. |
| 40 | +
|
| 41 | +## php-extension Package Type |
| 42 | +
|
| 43 | +A php-extension package represents a PHP extension. Its configuration file is located in the `config/pkg/ext/` directory, and its build class inherits from `PhpExtensionPackage` in the `src/Package/Extension/` directory. PHP extension package configurations include extension name, version, dependencies, build options, and more. |
| 44 | + |
| 45 | +```yaml |
| 46 | +ext-lz4: |
| 47 | + type: php-extension |
| 48 | + artifact: |
| 49 | + source: |
| 50 | + type: git |
| 51 | + url: 'https://github.com/kjdev/php-ext-lz4.git' |
| 52 | + rev: master |
| 53 | + extract: php-src/ext/lz4 |
| 54 | + metadata: |
| 55 | + license-files: [LICENSE] |
| 56 | + license: MIT |
| 57 | + depends: |
| 58 | + - liblz4 |
| 59 | + php-extension: |
| 60 | + arg-type@unix: '--enable-lz4=@shared_suffix@ --with-lz4-includedir=@build_root_path@' |
| 61 | + arg-type@windows: '--enable-lz4' |
| 62 | +``` |
| 63 | + |
| 64 | +Allowed fields for `php-extension`: |
| 65 | + |
| 66 | +```yaml |
| 67 | +ext-{ext-name}: # Package name must start with ext- prefix |
| 68 | + type: php-extension |
| 69 | +
|
| 70 | + # ── Common Fields ──────────────────────────────────────────────────────── |
| 71 | + description: '..' # Optional, human-readable package description |
| 72 | + lang: c # Optional, implementation language of the extension (c / c++ etc.) |
| 73 | + frameworks: [] # Optional, list of related macOS framework dependencies |
| 74 | +
|
| 75 | + artifact: '{artifact-name}' # Optional; when a string, references an Artifact definition |
| 76 | + # with the same name; when an object, is an inline Artifact |
| 77 | + # (built-in extensions don't need this field) |
| 78 | +
|
| 79 | + # depends / suggests support @windows / @unix / @linux / @macos suffixes |
| 80 | + depends: [] # Optional, hard dependency list (library names as-is, PHP extensions need ext- prefix) |
| 81 | + depends@unix: [] # Optional, hard dependencies only effective on Unix platforms |
| 82 | + depends@windows: [] # Optional, hard dependencies only effective on Windows platforms |
| 83 | + suggests: [] # Optional, optional dependency list (same format as depends) |
| 84 | + suggests@unix: [] |
| 85 | +
|
| 86 | + # ── php-extension Specific Fields (nested under php-extension: object) ──── |
| 87 | + php-extension: |
| 88 | + # arg-type determines the form of arguments passed to ./configure, supports platform suffixes |
| 89 | + # Supported platform suffixes: @unix (Linux + macOS), @linux, @macos, @windows |
| 90 | + # Priority (using Linux as example): arg-type@linux > arg-type@unix > arg-type (no suffix) |
| 91 | + # Built-in keywords: |
| 92 | + # enable → --enable-{extname} (default value, used when not configured) |
| 93 | + # enable-path → --enable-{extname}={buildroot} |
| 94 | + # with → --with-{extname} |
| 95 | + # with-path → --with-{extname}={buildroot} |
| 96 | + # custom/none → Pass no arguments (handled by the #[CustomPhpConfigureArg] method in the PHP class) |
| 97 | + # You can also write the full argument string directly, supporting the following placeholders: |
| 98 | + # @build_root_path@ → BUILD_ROOT_PATH (absolute path of buildroot) |
| 99 | + # @shared_suffix@ → Expands to =shared in shared builds, empty in static builds |
| 100 | + # @shared_path_suffix@ → Expands to =shared,{buildroot} in shared builds, |
| 101 | + # expands to ={buildroot} in static builds |
| 102 | + arg-type: enable |
| 103 | + arg-type@unix: '--enable-{extname}=@shared_suffix@' |
| 104 | + arg-type@windows: with-path |
| 105 | +
|
| 106 | + zend-extension: false # Optional, true indicates this is a Zend extension (e.g., opcache, xdebug) |
| 107 | + build-shared: true # Optional, whether building as a shared extension (.so) is allowed, default true |
| 108 | + build-static: true # Optional, whether inline static building (compiled into PHP) is allowed, default true |
| 109 | + build-with-php: true # Optional, true means the extension is built together via the PHP source tree |
| 110 | + # (used for built-in extensions) |
| 111 | +
|
| 112 | + # display-name affects the php --ri argument in smoke tests and the license export display name |
| 113 | + # If not set, defaults to the extension name (the part after ext-); if set to empty string, skips --ri check |
| 114 | + display-name: 'My Extension' |
| 115 | +
|
| 116 | + # os restricts the extension to be available only on specified platforms; |
| 117 | + # platforms not in the list will be rejected for building |
| 118 | + # Allowed values: Linux, Darwin, Windows |
| 119 | + os: [Linux, Darwin] |
| 120 | +``` |
| 121 | + |
| 122 | +## library Package Type |
| 123 | + |
| 124 | +A library package represents a dependency library that needs to be compiled from source (such as openssl, zlib, etc.). Its configuration file is located in the `config/pkg/lib/` directory, and its build class inherits from `LibraryPackage` in the `src/Package/Library/` directory. |
| 125 | + |
| 126 | +Taking openssl as an example: |
| 127 | + |
| 128 | +```yaml |
| 129 | +openssl: |
| 130 | + type: library |
| 131 | + artifact: |
| 132 | + source: |
| 133 | + type: ghrel |
| 134 | + repo: openssl/openssl |
| 135 | + match: openssl.+\.tar\.gz |
| 136 | + prefer-stable: true |
| 137 | + binary: hosted |
| 138 | + metadata: |
| 139 | + license-files: [LICENSE.txt] |
| 140 | + license: OpenSSL |
| 141 | + depends: |
| 142 | + - zlib |
| 143 | + depends@windows: |
| 144 | + - zlib |
| 145 | + - jom |
| 146 | + headers: |
| 147 | + - openssl |
| 148 | + static-libs@unix: |
| 149 | + - libssl.a |
| 150 | + - libcrypto.a |
| 151 | + static-libs@windows: |
| 152 | + - libssl.lib |
| 153 | + - libcrypto.lib |
| 154 | +``` |
| 155 | + |
| 156 | +Allowed fields for `library`: |
| 157 | + |
| 158 | +```yaml |
| 159 | +{lib-name}: |
| 160 | + type: library # library or target (target inherits all fields from library) |
| 161 | +
|
| 162 | + # ── Common Fields ───────────────────────────────────────────────────────── |
| 163 | + description: '..' # Optional, human-readable package description |
| 164 | + license: MIT # Optional, SPDX license identifier (for license export) |
| 165 | + lang: c # Optional, implementation language of the library (c / c++ etc.) |
| 166 | + frameworks: [] # Optional, list of related framework tags |
| 167 | +
|
| 168 | + artifact: '{artifact-name}' # Required; when a string, references an Artifact definition |
| 169 | + # with the same name; when an object, is an inline Artifact |
| 170 | +
|
| 171 | + # depends / suggests support @windows / @unix / @linux / @macos suffixes |
| 172 | + depends: [] # Optional, hard dependency list (library names or PHP extension names with ext- prefix) |
| 173 | + depends@unix: [] |
| 174 | + depends@windows: [] |
| 175 | + suggests: [] # Optional, optional dependency list (same format as depends) |
| 176 | +
|
| 177 | + # ── library / target Specific Fields ─────────────────────────────────────── |
| 178 | + # The following fields are used to verify that artifacts have been correctly |
| 179 | + # installed after the build. They support @unix / @windows / @linux / @macos suffixes. |
| 180 | +
|
| 181 | + # Verify that specified header files or directories exist under buildroot/include/ |
| 182 | + # Relative paths are based on buildroot/include/, absolute paths are used directly |
| 183 | + headers: |
| 184 | + - openssl # Corresponds to buildroot/include/openssl/ |
| 185 | + - zlib.h # Corresponds to buildroot/include/zlib.h |
| 186 | + headers@unix: |
| 187 | + - ffi.h |
| 188 | +
|
| 189 | + # Verify that specified static library files exist under buildroot/lib/ |
| 190 | + # Relative paths are based on buildroot/lib/, absolute paths are used directly |
| 191 | + static-libs@unix: |
| 192 | + - libssl.a |
| 193 | + static-libs@windows: |
| 194 | + - libssl.lib |
| 195 | +
|
| 196 | + # Verify that specified .pc files exist under buildroot/lib/pkgconfig/ |
| 197 | + # Only checked on non-Windows platforms (pkg-config is not applicable on Windows) |
| 198 | + pkg-configs: |
| 199 | + - openssl # Corresponds to buildroot/lib/pkgconfig/openssl.pc |
| 200 | + - libssl # Auto-completes .pc suffix |
| 201 | +
|
| 202 | + # Verify that specified executable files exist under buildroot/bin/ |
| 203 | + # Relative paths are based on buildroot/bin/, absolute paths are used directly |
| 204 | + static-bins: |
| 205 | + - my-tool |
| 206 | +
|
| 207 | + # List of directories injected into the global PATH after the package is installed. |
| 208 | + # Path placeholders are supported (see below for details). |
| 209 | + path: |
| 210 | + - '{pkg_root_path}/rust/bin' |
| 211 | +
|
| 212 | + # Environment variables set after the package is installed (overwrites existing values). |
| 213 | + # Path placeholders are supported. |
| 214 | + env: |
| 215 | + MY_VAR: '{build_root_path}/lib' |
| 216 | +
|
| 217 | + # Values appended to the end of existing environment variables after the package is installed. |
| 218 | + # Path placeholders are supported. |
| 219 | + append-env: |
| 220 | + CFLAGS: ' -I{build_root_path}/include' |
| 221 | +``` |
| 222 | + |
| 223 | +The following path placeholders are supported in string values of the `path`, `env`, and `append-env` fields: |
| 224 | + |
| 225 | +| Placeholder | Actual Path | |
| 226 | +|---|---| |
| 227 | +| `{build_root_path}` | buildroot directory (`buildroot/`) | |
| 228 | +| `{pkg_root_path}` | pkgroot directory (`pkgroot/`) | |
| 229 | +| `{working_dir}` | Working directory (project root) | |
| 230 | +| `{download_path}` | Download cache directory (`downloads/`) | |
| 231 | +| `{source_path}` | Extracted source directory (`source/`) | |
| 232 | +| `{php_sdk_path}` | Windows PHP SDK directory | |
| 233 | + |
| 234 | +## target Package Type |
| 235 | + |
| 236 | +A `target` package represents a final build artifact. It inherits from `library`, so it includes all definition fields of `library`. The configuration file for `target` packages is located in the `config/pkg/target/` directory, and its build class inherits from `TargetPackage` in the `src/Package/Target/` directory. |
| 237 | + |
| 238 | +The only difference from `library` is that a `target` package can be registered as a build target and automatically registers the build command `spc build:{target-name}`. |
| 239 | + |
| 240 | +## virtual-target Package Type |
| 241 | + |
| 242 | +Unlike `target`, a `virtual-target` may not include an `artifact`, meaning it doesn't directly correspond to a buildable entity but is instead an abstract build target, primarily used for dependency management and build scheduling. The configuration file for `virtual-target` is located in the `config/pkg/target/` directory, and its build class inherits from `TargetPackage` in the `src/Package/Target/` directory. Its definition is essentially the same as `target`, but the `artifact` field is optional and typically not set. `virtual-target` is primarily used in the following scenarios: |
| 243 | + |
| 244 | +- Defining an abstract build target for other packages to depend on, without directly corresponding to a buildable entity. |
| 245 | +- Serving as a common dependency for multiple `target` packages, simplifying dependency management. |
| 246 | + |
| 247 | +A typical example is the `php-cli`, `php-fpm` build targets for PHP. They have no independent source code and depend on `php-src`, with the final build outcome (CLI or FPM binary) determined through build scheduling. |
0 commit comments