- Add downloadProxy property to CompilerBase with null default
- Register proxy command line option in Constants.php with description
- Create new Downloader class with proxy handling capabilities
- Integrate Downloader into LibPhpInstaller and OfficialPhpSource
- Remove old downloadText/downloadFile methods from installer classes
- Add proxy parameter to Installer and Builder constructors
- Update SapiPhpBuilder to pass proxy to OfficialPhpSource
- Modify Translator to parse and validate --proxy command line argument
- Skip proxy arguments during path detection in Translator
- Support both HTTP and SOCKS proxy protocols via curl and streams
- Add BUILD_MODE_SAPI constant and related methods for SAPI-specific builds
- Introduce sapiTargets, sapiEntryFile, and other SAPI-related configuration options
- Enhance Android platform with allowTargetVersion parameter in buildPhpIncludePaths
- Reorganize imports in CompilerBase with better grouping and ordering
- Add isSapiBuild() and getSapiTargets() methods for SAPI detection and management
- Update build mode logic to include SAPI in embed builds
- Refine expression type checking with shorter namespace references
- Add comprehensive SAPI build tests including target configuration scenarios
- Improve class property access in tests with parent class traversal support
- Standardize namespace separator handling in various compiler operations
- Add proper escaping and formatting in generated C++ code strings
- Implement SAPI-specific project parsing and validation rules
- Update test assertions to handle new namespace separator format
- Add error handling improvements for unsupported source conditions
- Enhance type checker generator
- Add embedded-files configuration option for packaging Composer vendor files and PHP fallback files
- Implement OPcache bytecode generation for embedded PHP files during build process
- Update GitHub Actions workflows to handle PHP version-specific release packaging
- Modify package.php to embed Composer runtime dependencies directly in compiler binaries
- Remove vendor directory from release packages since dependencies are now embedded
- Add comprehensive documentation for embedded-files feature in English and Chinese
- Update README files to include embedded dependencies documentation links
- Implement PHP ABI versioning in package filenames to distinguish different PHP builds
- Add verification mechanism to ensure embedded Composer runtime functions correctly
- Create detailed guides covering recommended setup, performance considerations, and build requirements
- Update project.yml version from 0.9.1 to 0.9.2
- Update project.yml file-version from 0.9.1.1112 to 0.9.2.1112
- Update project.yml product-version from 0.9.1 to 0.9.2
- Update Translator.php VERSION constant from 0.9.1 to 0.9.2
* fix(compiler): apply unary plus numeric conversion
* fix(compiler): infer unary plus assignments from target type
* fix(compiler): retain unary plus inference for fresh locals
* fix(compiler): resolve existing unary assignment locals by compiled name
- Updated swoole/phpx from ~2.9.0 to ~2.9.1 in composer.json
- Bumped minor version for bug fixes and improvements
- Maintained compatibility with existing codebase
- Resolved potential security vulnerabilities in older version
- Update main project version from 0.9.0 to 0.9.1
- Update file version from 0.9.0.1112 to 0.9.1.1112
- Update product version from 0.9.0 to 0.9.1
- Move optimize setting from project.yml to project-release.yml
- Remove Wall compiler flag from cxx-flags list
Composer path repositories install a package as a symlink, so a source
directory reached through one contributed no files at all: PHP's
RecursiveDirectoryIterator does not descend into symlinked directories
unless asked, because RecursiveIteratorIterator calls hasChildren() and
its $allowLinks argument defaults to false.
The build still reported success, and the missing classes only surfaced
at runtime as `class 'X' is undefined`.
Scan with FilesystemIterator::FOLLOW_SYMLINKS. A linked directory is an
ordinary source entry with no setting of its own; what is compiled stays
with `sources` and `ignore`.
Exclusions match the path that reached a file, the one the project wrote
and the scanner traversed. An `ignore` entry is no longer resolved to its
link target, which compared a real path against a linked one and so never
matched.
Real paths are kept for identity alone. A link is refused when it closes
the branch that reached it, so a link to one of its own ancestors cannot
recurse; files reachable through several links are reduced to one path
after exclusions have run, since deduplicating before that would drop an
allowed alias along with an excluded one.
* fix(installer): keep the embed build inside its own prefix
The libphp.so installer reuses the configure options of the PHP already on
the machine so the private build matches it feature for feature. A
distribution build records where *it* installs, though, and those paths are
absolute. On Debian and Ubuntu the options carry --mandir=/usr/share/man,
--includedir=/usr/include, --libdir, --libexecdir, --sysconfdir and
--localstatedir. Inherited unchanged, they survive the --prefix rewrite, and
`make install` tries to write into system directories:
Installing PHP CLI man page: /usr/share/man/man1/
cp: cannot create regular file '/usr/share/man/man1/#INST@3023727#': Permission denied
make: *** [Makefile:265: install-cli] Error 1
Fatal error: Unable to install libphp.so: Command failed: make install
So the build only completed for root, or inside a container where the user
owns /usr. Everyone else got a PHP compiled from scratch and then thrown
away at the last step.
Two further options escape the same way. --program-suffix=8.3 installs the
binaries as php8.3 and php-config8.3, but LibPhpInstaller::installedVersion(),
writePhpIni() and UnixPlatform::findPhpConfig() all look for the plain names,
so a build that got past `make install` still looked like it had produced
nothing. --cache-file points at the distribution's build directory
(/tmp/buildd/nonexistent/config.cache), a path that does not exist here and
whose answers were recorded for a different prefix.
Drop all of them. Autoconf derives every installation directory from --prefix
when it is absent, so the private build lands entirely under the requested
prefix: bin/php, lib/libphp.so, include/php and share/man/man1. Options that
name a *dependency* rather than a destination, such as --with-zlib=/usr and
--with-layout=GNU, are untouched; the built PHP still matches the one it was
derived from.
* fix(installer): offer an existing build before asking to make one
Running a build twice asked four questions to arrive at the answer it
already had:
The current PHP installation does not provide libphp.so: /usr
Build a private PHP embed library now? [Y/n]
PHP version [8.5.10]:
Install directory [/home/alganet/.typephp]:
PHP 8.5.10 with libphp.so already exists in /home/alganet/.typephp; use it? [Y/n]
The reuse check sat at the bottom because it needs a version and a
directory, and those were read from the prompts. But both have defaults
that are known without asking anyone: the directory this installer always
proposes, and the PHP that is running it. That is the case being answered
here, so it can be offered first.
Ask it up front. Accepting now ends the exchange at one question, and the
`--prefix` rewrite no longer has to be reasoned about at all. The later
check stays for a directory or version typed by hand, and is skipped when
the answers repeat the defaults, so the same question is never asked twice.
ensure() also fetched the release list from php.net before looking for an
existing build, so the reuse path made a network round trip to learn the
URL of an archive it was not going to download. Move the fetch next to the
install that needs it.
Nothing recorded PHP_HOME anywhere but this process, and that has not
changed: a fresh run still has to rediscover the build. Being asked once
instead of four times is the part that is worth fixing separately.
A program built on Linux does not start:
./main: error while loading shared libraries: libphpx.so:
cannot open shared object file: No such file or directory
libphpx.so sits beside the phpx checkout and libphp.so under the prefix the
libphp installer chose. The link line names both with -L, which tells the
linker where to look and the loader nothing, and neither directory is on the
default search path. The binary carries no RPATH or RUNPATH at all, so it
only runs under LD_LIBRARY_PATH.
Every part of the mechanism is already present and already reached on Linux.
NativeCommandOptionsTrait asks the platform for getDefaultRpaths() on every
non-nano build, and GccLikeBackend emits -Wl,-rpath for each entry it gets
back. Only the list is missing: PlatformBase returns an empty one, Macos
overrides it with the phpx and PHP library directories, and Linux never
overrode anything.
Move that override up to UnixPlatform, where Linux inherits it. The two
directories are the same ones the -L flags already name, each still guarded
by is_dir(), so macOS keeps the behavior it has today.
Android and Ios return an empty list on purpose: a path on the build host
means nothing on the device that runs the output. Wasi is a cross target too
and had been relying on the inherited default, so it states the same thing
explicitly rather than acquiring host paths from this move.
The recorded paths are absolute, matching what macOS has always emitted. That
is enough to run where the program was built, which is what an embed build
against a private PHP prefix can do in any case. Relocatable output needs
$ORIGIN and the libraries shipped alongside, or --full-static, and neither is
decided here.
- Clarified that release binaries embed production Composer runtime as opcodes
- Updated project-release.yml to remove embedded vendor directory
- Revised README to explain development vs production build processes
- Updated Chinese documentation to reflect new build configuration
- Removed outdated comments about PHPT bootstrap initialization costs
- Documented proper usage of project.yml vs project-release.yml for different scenarios
- Add project-release.yml with embedded vendor files for standalone builds
- Implement YAML include mechanism in ProjectYamlLoader with circular reference detection
- Support single file or list of files in include directive with ordered merging
- Add recursive map merging and list replacement for included configurations
- Create CompilerProjectConfigurationTest to verify release compiler embedding
- Add ProjectYamlLoaderTest with comprehensive include scenarios
- Update GitHub workflows to build standalone compiler using project-release.yml
- Document include feature usage in README files with examples
- Remove embedded-files from development project.yml to reduce initialization cost
- Add validation for absolute paths and proper error handling for missing files
- Add version field to expose extension version through Zend module entry
- Add info mapping to accept arbitrary labels and scalar values for phpinfo()
- Generate PHP_MINFO_FUNCTION to display custom extension information
- Preserve info mapping order in module's phpinfo() section
- Validate version as non-empty string without NUL bytes
- Validate info as mapping of non-empty string labels to scalar values
- Add comprehensive tests for metadata parsing and generation
- Update documentation with extension metadata configuration examples
- Add testGccOnWindowsUsesGccIncludeSyntaxForAllSourceTypes method to verify include path formatting
- Test include paths with GCC compiler on Windows for C, C++, and assembler files
- Verify that GCC uses -I flag syntax instead of /I for all source types on Windows
- Confirm proper escaping of include paths with spaces using escapeshellarg
- Add formatIncludePaths method to handle include flag formatting consistently across platforms
- Add referencedClasses array to store fully resolved class names
- Implement recordReferencedClass method to track class references
- Enhance function call parsing with static function resolution
- Add native function lookup and return type detection
- Insert type conversion for runtime call results
- Resolve extension dependencies based on internal functions and classes
- Append extension requirements to generated module header
- Update tests to validate extension dependency detection
- Add test case for runtime builtin int property assignment
- Modify polymorphic class dispatch to restore string representation
- Removed strtotime from the list of functions that use direct PHPX wrappers
- Updated test case to verify only supported datetime calls use direct wrappers
- Modified strtotime test to include absolute, relative, epoch 0 and invalid dates
- Added timezone setting and additional test cases for relative date handling
- Updated expected test output to reflect new strtotime behavior
- Adjusted assertions to check for correct persistent function calls
- Added assertion to check opcodeBuildChecked property is false
- Used reflection to access parent class properties when needed
- Removed anonymousOpcode configuration from build parameters
- Ensured proper state verification for compiler fingerprint tests
- Implemented anonymous file detection and separate cache directory handling
- Added SHA256-based cache key generation for anonymous opcodes
- Created dedicated cache directories for anonymous files with build signature
- Added force clear functionality for anonymous opcode caches
- Updated cache hit tracking to distinguish between vendor and anonymous files
- Added progress output for anonymous opcode cache statistics
- Integrated anonymous file processing into existing opcode pipeline flow