diff --git a/README.md b/README.md index cd714f70..1edbc56a 100755 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ You can also use the micro binary file to combine php binary and php source code [![](https://img.shields.io/badge/Extension%20Counter-65+-yellow.svg?style=flat-square)]() [![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]() -## Docs +## Documentation The current README contains basic usage. For all the features of static-php-cli, see . @@ -135,7 +135,7 @@ Basic usage for building php and micro with some extensions: > If you are using the packaged `spc` binary, you need to replace `bin/spc` with `./spc` in the following commands. ```bash -# Check system tool dependencies, fix them automatically +# Check system tool dependencies, fix them if possible ./bin/spc doctor # fetch all libraries ./bin/spc download --all @@ -167,7 +167,7 @@ If anything goes wrong, use `--debug` option to display full terminal output: ./bin/spc fetch --all --debug ``` -In addition, we build NTS by default. If you are going to build ZTS version, just add `--enable-zts` option. +In addition, we build NTS (non-thread-safe) by default. If you are going to build ZTS version, just add `--enable-zts` option. ```bash ./bin/spc build openssl,pcntl --build-all --enable-zts @@ -236,7 +236,7 @@ When using the parameter `--build-all` or `--build-fpm`, the final compilation result will output a file named `./php-fpm`, This file will be located in the path `buildroot/bin/`, simply copy it out for use. -In normal Linux distributions and macOS systems, the package manager will automatically generate a default fpm configuration file after installing php-fpm. +In common Linux distributions and macOS systems, the package manager will automatically generate a default fpm configuration file after installing php-fpm. Because php-fpm must specify a configuration file before running, the php-fpm compiled by this project will not have any configuration files, so you need to write `php-fpm.conf` and `pool.conf` configuration files yourself. Specifying `php-fpm.conf` can use the command parameter `-y`, for example: `./php-fpm -y php-fpm.conf`. @@ -262,10 +262,6 @@ If you want to contribute documentation, please go to [static-php/static-php-cli Now there is a [static-php](https://github.com/static-php) organization, which is used to store the repo related to the project. -Part of the English document is written by me, and part is translated by Google, -and there may be inaccurate descriptions, strange or offensive expressions. -If you are a native English speaker, some corrections to the documentation are welcome. - ## Sponsor this project You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md). @@ -288,8 +284,3 @@ and they all have their own open source licenses. Please use the `bin/spc dump-license` command to export the open source licenses used in the project after compilation, and comply with the corresponding project's LICENSE. -## Advanced - -The refactoring branch of this project is written modularly. -If you are interested in this project and want to join the development, -you can refer to the [Contribution Guide](https://static-php.dev) of the documentation to contribute code or documentation. diff --git a/bin/spc-alpine-docker b/bin/spc-alpine-docker index e807a2df..87e52968 100755 --- a/bin/spc-alpine-docker +++ b/bin/spc-alpine-docker @@ -73,6 +73,7 @@ RUN apk update; \ git \ jq \ libgcc \ + libtool \ libstdc++ \ linux-headers \ m4 \ diff --git a/config/ext.json b/config/ext.json index e38bacb6..2df51239 100644 --- a/config/ext.json +++ b/config/ext.json @@ -228,7 +228,8 @@ ] }, "opcache": { - "type": "builtin" + "type": "builtin", + "arg-type": "custom" }, "openssl": { "type": "builtin", diff --git a/src/SPC/builder/extension/opcache.php b/src/SPC/builder/extension/opcache.php index f592303a..82efc853 100644 --- a/src/SPC/builder/extension/opcache.php +++ b/src/SPC/builder/extension/opcache.php @@ -5,11 +5,25 @@ declare(strict_types=1); namespace SPC\builder\extension; use SPC\builder\Extension; +use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; use SPC\util\CustomExt; #[CustomExt('opcache')] class opcache extends Extension { + /** + * @throws WrongUsageException + * @throws RuntimeException + */ + public function getUnixConfigureArg(): string + { + if ($this->builder->getPHPVersionID() < 80000) { + throw new WrongUsageException('Statically compiled PHP with Zend Opcache only available for PHP >= 8.0 !'); + } + return '--enable-opcache'; + } + public function getDistName(): string { return 'Zend Opcache'; diff --git a/src/SPC/command/BuildCliCommand.php b/src/SPC/command/BuildCliCommand.php index 72235847..5bd0bba3 100644 --- a/src/SPC/command/BuildCliCommand.php +++ b/src/SPC/command/BuildCliCommand.php @@ -16,7 +16,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use ZM\Logger\ConsoleColor; -#[AsCommand('build', 'build CLI binary')] +#[AsCommand('build', 'build PHP')] class BuildCliCommand extends BuildCommand { public function configure(): void @@ -33,6 +33,8 @@ class BuildCliCommand extends BuildCommand $this->addOption('disable-opcache-jit', null, null, 'disable opcache jit'); $this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI'); $this->addOption('with-micro-fake-cli', null, null, 'Enable phpmicro fake cli'); + $this->addOption('with-suggested-libs', 'L', null, 'Build with suggested libs for selected exts and libs'); + $this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts'); } public function handle(): int @@ -42,12 +44,9 @@ class BuildCliCommand extends BuildCommand // transform string to array $extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions')))); - $rule = BUILD_TARGET_NONE; - $rule |= ($this->getOption('build-cli') ? BUILD_TARGET_CLI : BUILD_TARGET_NONE); - $rule |= ($this->getOption('build-micro') ? BUILD_TARGET_MICRO : BUILD_TARGET_NONE); - $rule |= ($this->getOption('build-fpm') ? BUILD_TARGET_FPM : BUILD_TARGET_NONE); - $rule |= ($this->getOption('build-embed') ? BUILD_TARGET_EMBED : BUILD_TARGET_NONE); - $rule |= ($this->getOption('build-all') ? BUILD_TARGET_ALL : BUILD_TARGET_NONE); + // parse rule with options + $rule = $this->parseRules(); + if ($rule === BUILD_TARGET_NONE) { $this->output->writeln('Please add at least one build target!'); $this->output->writeln("\t--build-cli\tBuild php-cli SAPI"); @@ -62,16 +61,27 @@ class BuildCliCommand extends BuildCommand $builder = BuilderProvider::makeBuilderByInput($this->input); // calculate dependencies [$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries); - /* @phpstan-ignore-next-line */ - logger()->info('Build target: ' . ConsoleColor::yellow($builder->getBuildTypeName($rule))); - /* @phpstan-ignore-next-line */ - logger()->info('Enabled extensions: ' . ConsoleColor::yellow(implode(', ', $extensions))); - /* @phpstan-ignore-next-line */ - logger()->info('Required libraries: ' . ConsoleColor::yellow(implode(', ', $libraries))); - if (!empty($not_included)) { - logger()->warning('some extensions will be enabled due to dependencies: ' . implode(',', $not_included)); + + // print info + $indent_texts = [ + 'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')', + 'Build SAPI' => $builder->getBuildTypeName($rule), + 'Extensions (' . count($extensions) . ')' => implode(', ', $extensions), + 'Libraries (' . count($libraries) . ')' => implode(', ', $libraries), + 'Strip Binaries' => $builder->getOption('no-strip') ? 'no' : 'yes', + 'Enable ZTS' => $builder->getOption('enable-zts') ? 'yes' : 'no', + ]; + if (!empty($this->input->getOption('with-hardcoded-ini'))) { + $indent_texts['Hardcoded INI'] = $this->input->getOption('with-hardcoded-ini'); } + $this->printFormatInfo($indent_texts); + + if (!empty($not_included)) { + logger()->warning('Some extensions will be enabled due to dependencies: ' . implode(',', $not_included)); + } + logger()->info('Build will start after 2s ...'); sleep(2); + if ($this->input->getOption('with-clean')) { logger()->info('Cleaning source dir...'); FileSystem::removeDir(SOURCE_PATH); @@ -140,4 +150,41 @@ class BuildCliCommand extends BuildCommand return static::FAILURE; } } + + /** + * Parse build options to rule int. + */ + private function parseRules(): int + { + $rule = BUILD_TARGET_NONE; + $rule |= ($this->getOption('build-cli') ? BUILD_TARGET_CLI : BUILD_TARGET_NONE); + $rule |= ($this->getOption('build-micro') ? BUILD_TARGET_MICRO : BUILD_TARGET_NONE); + $rule |= ($this->getOption('build-fpm') ? BUILD_TARGET_FPM : BUILD_TARGET_NONE); + $rule |= ($this->getOption('build-embed') ? BUILD_TARGET_EMBED : BUILD_TARGET_NONE); + $rule |= ($this->getOption('build-all') ? BUILD_TARGET_ALL : BUILD_TARGET_NONE); + return $rule; + } + + private function printFormatInfo(array $indent_texts): void + { + // calculate space count for every line + $maxlen = 0; + foreach ($indent_texts as $k => $v) { + $maxlen = max(strlen($k), $maxlen); + } + foreach ($indent_texts as $k => $v) { + if (is_string($v)) { + /* @phpstan-ignore-next-line */ + logger()->info($k . ': ' . str_pad('', $maxlen - strlen($k)) . ConsoleColor::yellow($v)); + } elseif (is_array($v) && !is_assoc_array($v)) { + $first = array_shift($v); + /* @phpstan-ignore-next-line */ + logger()->info($k . ': ' . str_pad('', $maxlen - strlen($k)) . ConsoleColor::yellow($first)); + foreach ($v as $vs) { + /* @phpstan-ignore-next-line */ + logger()->info(str_pad('', $maxlen + 2) . ConsoleColor::yellow($vs)); + } + } + } + } } diff --git a/src/SPC/doctor/item/LinuxToolCheckList.php b/src/SPC/doctor/item/LinuxToolCheckList.php index 33aa0639..01df03d6 100644 --- a/src/SPC/doctor/item/LinuxToolCheckList.php +++ b/src/SPC/doctor/item/LinuxToolCheckList.php @@ -21,6 +21,7 @@ class LinuxToolCheckList 'tar', 'unzip', 'gzip', 'bzip2', 'cmake', 'gcc', 'g++', 'patch', 'binutils-gold', + 'libtoolize', ]; public const TOOLS_DEBIAN = [ @@ -102,7 +103,8 @@ class LinuxToolCheckList try { $is_debian = in_array($distro['dist'], ['debian', 'ubuntu']); $to_install = $is_debian ? str_replace('xz', 'xz-utils', $missing) : $missing; - $to_install = $is_debian ? str_replace('libtoolize', 'libtool', $to_install) : $to_install; + // debian, alpine libtool -> libtoolize + $to_install = str_replace('libtoolize', 'libtool', $to_install); shell(true)->exec($prefix . $install_cmd . ' ' . implode(' ', $to_install)); } catch (RuntimeException) { return false;