static-php-cli

repository·v3·Indexed 23 days ago

https://github.com/crazywhalecc/static-php-cli

A toolset for building static PHP binaries with a focus on the micro SAPI and static linking of extensions and dependencies. It includes the spc CLI for managing builds, a YAML-based configuration system (deps-craft.yml) for defining PHP versions and SAPIs, and an artifact model for managing source archives and pre-built binaries across various download types such as GitHub Releases, PECL, and Git.

Tokens
34.7K
Snippets
77
Records
155
Agent score
73%

What's inside static-php-cli

  1. Overview of StaticPHP capabilities

    v3

    StaticPHP is a tool for building portable executables. It allows developers to compile standalone PHP binaries and specialized executables with integrated dependencies. Key capabilities include:

    • Static PHP Binary: Compile standalone PHP binaries for various SAPIs, including cli, fpm, cgi, and frankenphp.
    • Micro Self-Extracted Executable: Build self-extracted executables that include your PHP source code using the micro SAPI.
    • Dependency Management: Manage and install different types of PHP extensions, packages, and libraries directly into the build.
  2. What is StaticPHP?

    v3

    StaticPHP is a build tool that compiles the PHP interpreter and required extensions into a single, self-contained binary. The resulting binary targets Linux, macOS, and Windows and can run on target systems without any pre-installed PHP or runtime libraries.

    Beyond PHP, the underlying infrastructure can also be used to compile standalone static binaries for other tools like curl, pkg-config, and htop.

  3. Overview of supported PHP SAPIs

    v3

    StaticPHP supports several SAPIs (Server APIs), each with specific build flags and output paths. Choose the SAPI that matches your deployment needs:

    SAPIBuild flagLinux/macOS OutputWindows OutputPlatform Support
    cli--build-clibuildroot/bin/phpbuildroot/bin/php.exeLinux, macOS, Windows
    fpm--build-fpmbuildroot/bin/php-fpmN/ALinux, macOS
    micro--build-microbuildroot/bin/micro.sfxbuildroot/bin/micro.sfxLinux, macOS, Windows
    embed--build-embedbuildroot/lib/libphp.abuildroot/lib/php8embed.libLinux, macOS, Windows
    frankenphp--build-frankenphpbuildroot/bin/frankenphpbuildroot/bin/frankenphp.exeLinux, macOS, Windows
  4. What is an Artifact in the StaticPHP build system

    v3
    An Artifact is a core abstraction representing a source archive or a pre-built binary required to build a package. It defines the location of the file (download source), the extraction process, and the resulting file system layout. Packages consume artifacts via an artifact field to acquire their necessary source code or binaries.
  5. Understand the StaticPHP core concepts and modules

    v3

    StaticPHP is a CLI application built on symfony/console. The core logic resides in src/StaticPHP and is organized into several functional modules:

    • Registry: Manages registry data. A registry contains multiple Packages. The project includes a built-in core registry containing PHP and its dependencies.
    • Package: Represents a single unit of build. There are four types: php-extension, library, target, and virtual-target. Each contains build info and dependency data.
    • Installer/Builder: Executes build commands, extracts artifacts, and processes build results.
    • Doctor: Handles system environment verification and installs/verifies dependencies like make, cmake, or autoconf.
    • Runtime/Executor: Provides utilities for executing shell commands and CMake builds.
    • Toolchain: Provides abstraction interfaces to handle OS-specific differences (e.g., different compilers or build environments) during the build process.
    • DependencyResolver: Calculates the build order by resolving dependencies between packages.
    • Utils: General utilities for file system operations, logging, and OS helpers.
  6. Define target and virtual-target Package Types

    v3

    target

    A target package represents a final build artifact. It inherits all fields from library.

    • Location: Configuration in config/pkg/target/.
    • Recipes: Place in src/Package/Target/ and register with #[Target]. Recipes receive a TargetPackage.
    • Feature: Automatically registers the build command spc build:{target-name}.

    virtual-target

    A virtual-target is an abstract build target used for dependency management and build scheduling. It is similar to target but typically omits the artifact field.

    • Use Cases:
      • Defining an abstract target for other packages to depend on.
      • Serving as a common dependency for multiple target packages (e.g., php-cli and php-fpm depending on a php target).
    • Location/Recipes: Uses the same directories and #[Target] registration as target.
  7. How the Registry & Plugin System works

    v3

    The Registry is the core extension mechanism in StaticPHP. It acts as a "plugin package" that describes how to build packages (libraries, extensions, or targets) and artifacts.

    A Registry consists of:

    1. A declaration file (spc.registry.yml) in its root.
    2. Configuration files (YAML/JSON) defining package/artifact properties.
    3. PHP classes providing the actual build logic.

    At startup, StaticPHP loads all registered Registries and merges their package definitions. The built-in core registry contains all default PHP and extension definitions. External Registries can only define new packages; they cannot override or modify existing core definitions.

    There are three ways to extend StaticPHP:

    • Modify the core registry: Edit files in src/Package and config/pkg/ directly (best for contributing to the mainline).
    • Vendor Mode: Package custom logic as a standalone sub-registry distributed via Composer (best for private/reusable libraries).
    • External Registry: Use the SPC_REGISTRIES environment variable to point to external registry file paths (best for temporary extensions).
  8. Define a library Package Type

    v3

    A library package represents a dependency library (e.g., openssl, zlib) installed from source or a pre-built binary. Configuration files for libraries are located in config/pkg/lib/.

    If you are writing custom recipe classes for libraries, place them in src/Package/Library/ and register them with #[Library]. These classes receive a LibraryPackage through the callback context but do not need to inherit from it.

    Key characteristics:

    • Uses the type: library field.
    • Requires an artifact field (either a string referencing a named Artifact or an inline object).
    • Supports platform-specific dependencies using suffixes like @windows, @unix, @linux, or @macos on depends, suggests, and tools fields.
    openssl:
      type: library
      artifact:
        source:
          type: ghrel
          repo: openssl/openssl
          match: openssl.+\.tar\.gz
          prefer-stable: true
        binary: hosted
        metadata:
          license-files: [LICENSE.txt]
          license: OpenSSL
      depends:
        - zlib
      depends@windows:
        - zlib
        - jom
      headers:
        - openssl
      static-libs@unix:
        - libssl.a
        - libcrypto.a
      static-libs@windows:
        - libssl.lib
        - libcrypto.lib
  9. Use Swoole coroutine hooks for PostgreSQL, MySQL, SQLite, and ODBC

    v3

    To enable coroutine mode for specific database drivers in Swoole, use the following hook features. Note that these hooks often conflict with the standard PDO extensions and require you to remove the standard extension to work correctly.

    PostgreSQL

    Use swoole,swoole-hook-pgsql. This enables Swoole's PostgreSQL client and the coroutine mode of pdo_pgsql. Conflict: You must delete the pdo_pgsql extension and enable swoole and swoole-hook-pgsql instead.

    MySQL

    Use swoole,swoole-hook-mysql. This enables the coroutine mode of Swoole's mysqlnd and pdo_mysql.

    SQLite

    Use swoole,swoole-hook-sqlite (requires Swoole 5.1+). This enables the coroutine mode of pdo_sqlite. Conflict: You must delete the pdo_sqlite extension and enable swoole and swoole-hook-sqlite instead.

    ODBC

    Use swoole,swoole-hook-odbc. This enables the coroutine mode of Swoole's odbc extension. Conflict: You must delete the pdo_odbc extension and enable swoole and swoole-hook-odbc instead.

  10. Include optional dependencies for extensions

    v3
    By default, static-php-cli follows a minimal-dependency principle. When building an extension that has optional features or library dependencies (for example, gd optionally using libwebp or freetype), simply running bin/spc build <extension> --build-cli will not include those optional features. You must ensure the build configuration accounts for these specific dependencies if they are required for your use case.
  11. Define a tool Package Type

    v3

    A tool package represents an executable required during the build process of another package, rather than a library linked into the final target. Tool dependencies are resolved via the tools field and are independent of depends or suggests.

    Configuration files for tools are defined using type: tool. The nested tool object allows you to specify:

    • provides: (Required) Executable filenames used to determine if the tool is installed. Supports platform suffixes (e.g., provides@windows).
    • binary-subdir: Directory below the installation root containing the executables (defaults to the install root).
    • install-root: The installation root (defaults to PKG_ROOT_PATH).
    • min-version: Declared minimum version metadata (not currently enforced by the installer).
    nasm:
      type: tool
      artifact:
        binary:
          windows-x86_64:
            type: url
            url: 'https://example.com/nasm-win64.zip'
            extract:
              nasm.exe: '{pkg_root_path}/bin/nasm.exe'
              ndisasm.exe: '{pkg_root_path}/bin/ndisasm.exe'
      tool:
        provides: [nasm.exe, ndisasm.exe]
        binary-subdir: bin
        min-version: '2.16'
  12. Understand the Package Model

    v3

    A Package is the fundamental unit in the StaticPHP build system, representing anything that can be built or installed (e.g., PHP extensions, libraries, or final binaries).

    Packages are defined using YAML/JSON configuration files. The core registry definitions are located in config/pkg/, while custom recipe logic resides in src/Package/.

    There are five distinct package types:

    • php-extension: Contains build logic for a PHP extension.
    • library: A dependency library typically installed into buildroot/ for linking.
    • target: A final build artifact (like a PHP binary). Inherits from library.
    • virtual-target: An abstract target used for dependency management and build scheduling; it does not correspond to a physical artifact.
    • tool: A host-side build tool installed under pkgroot/ rather than as a link-time dependency.
    {pkg-name}:
      type: {pkg-type}
      ...