From 76c353e79078111335063be1b56ef7cc4155dfff Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Mon, 24 Mar 2025 22:39:45 +0800 Subject: [PATCH] Add SPC_DOCKER_DEBUG=yes option for docker build --- bin/spc-alpine-docker | 14 ++++++++ bin/spc-gnu-docker | 18 ++++++++-- src/SPC/command/BuildPHPCommand.php | 51 ++++++++++++----------------- 3 files changed, 51 insertions(+), 32 deletions(-) diff --git a/bin/spc-alpine-docker b/bin/spc-alpine-docker index 28cc4939..16609b5f 100755 --- a/bin/spc-alpine-docker +++ b/bin/spc-alpine-docker @@ -122,6 +122,20 @@ MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot" # shellcheck disable=SC2086 # shellcheck disable=SC2090 if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then + echo "* Debug mode enabled, run docker in interactive mode." + echo "* You can use 'exit' to exit the docker container." + echo "* You can use 'bin/spc' like normal builds." + echo "*" + echo "* Mounted directories:" + echo "* ./config: $(pwd)/config" + echo "* ./src: $(pwd)/src" + echo "* ./buildroot: $(pwd)/buildroot" + echo "* ./source: $(pwd)/source" + echo "* ./dist: $(pwd)/dist" + echo "* ./downloads: $(pwd)/downloads" + echo "* ./pkgroot: $(pwd)/pkgroot" + echo "*" + $DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-v2 else $DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-v2 bin/spc $@ diff --git a/bin/spc-gnu-docker b/bin/spc-gnu-docker index d96abbc5..6bc7bd4a 100755 --- a/bin/spc-gnu-docker +++ b/bin/spc-gnu-docker @@ -86,7 +86,7 @@ COPY ./composer.* /app/ ADD ./bin/setup-runtime /app/bin/setup-runtime ADD ./bin/spc /app/bin/spc RUN /app/bin/setup-runtime -RUN /app/bin/php /app/bin/composer install --no-dev --classmap-authoritative +RUN /app/bin/php /app/bin/composer install --no-dev ENV PATH="/app/bin:/cmake/bin:$PATH" ENV SPC_LIBC=glibc @@ -145,8 +145,22 @@ echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm -lresolv -lutil -lrt"' # shellcheck disable=SC2086 # shellcheck disable=SC2090 + if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then - echo -e "\e[033m* Debug mode enabled, run docker in interactive mode.\e[0m" + echo "* Debug mode enabled, run docker in interactive mode." + echo "* You can use 'exit' to exit the docker container." + echo "* You can use 'bin/spc' like normal builds." + echo "*" + echo "* Mounted directories:" + echo "* ./config: $(pwd)/config" + echo "* ./src: $(pwd)/src" + echo "* ./buildroot: $(pwd)/buildroot" + echo "* ./source: $(pwd)/source" + echo "* ./dist: $(pwd)/dist" + echo "* ./downloads: $(pwd)/downloads" + echo "* ./pkgroot: $(pwd)/pkgroot" + echo "*" + $DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH else $DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH bin/spc $@ diff --git a/src/SPC/command/BuildPHPCommand.php b/src/SPC/command/BuildPHPCommand.php index 3a5c17a4..b10739eb 100644 --- a/src/SPC/command/BuildPHPCommand.php +++ b/src/SPC/command/BuildPHPCommand.php @@ -11,7 +11,6 @@ use SPC\store\Config; use SPC\store\FileSystem; use SPC\store\SourcePatcher; use SPC\util\DependencyUtil; -use SPC\util\DynamicExt; use SPC\util\GlobalEnvManager; use SPC\util\LicenseDumper; use Symfony\Component\Console\Attribute\AsCommand; @@ -28,10 +27,12 @@ class BuildPHPCommand extends BuildCommand $this->addArgument('extensions', InputArgument::REQUIRED, 'The extensions will be compiled, comma separated'); $this->addOption('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', ''); + $this->addOption('with-dynamic', 'D', InputOption::VALUE_REQUIRED, 'Dynamic extensions to build, comma separated', ''); $this->addOption('build-micro', null, null, 'Build micro SAPI'); $this->addOption('build-cli', null, null, 'Build cli SAPI'); $this->addOption('build-fpm', null, null, 'Build fpm SAPI (not available on Windows)'); $this->addOption('build-embed', null, null, 'Build embed SAPI (not available on Windows)'); + $this->addOption('build-dev', null, null, 'Build dev things for building dynamic extensions (not available on Windows)'); $this->addOption('build-all', null, null, 'Build all SAPI'); $this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions'); $this->addOption('disable-opcache-jit', null, null, 'disable opcache jit'); @@ -53,13 +54,15 @@ class BuildPHPCommand extends BuildCommand // transform string to array $libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs')))); // transform string to array - $extensions = $this->parseExtensionList($this->getArgument('extensions')); + $dynamic_extensions = array_map('trim', array_filter(explode(',', $this->getOption('with-dynamic')))); + // transform string to array + $static_extensions = $this->parseExtensionList($this->getArgument('extensions')); // parse rule with options - $rule = $this->parseRules(); + $rule = $this->parseRules($dynamic_extensions); - if ($rule === BUILD_TARGET_NONE) { - $this->output->writeln('Please add at least one build target!'); + if ($rule === BUILD_TARGET_NONE || $rule === BUILD_TARGET_DEV) { + $this->output->writeln('Please add at least one build SAPI!'); $this->output->writeln("\t--build-cli\tBuild php-cli SAPI"); $this->output->writeln("\t--build-micro\tBuild phpmicro SAPI"); $this->output->writeln("\t--build-fpm\tBuild php-fpm SAPI"); @@ -108,33 +111,22 @@ class BuildPHPCommand extends BuildCommand $builder = BuilderProvider::makeBuilderByInput($this->input); $include_suggest_ext = $this->getOption('with-suggested-exts'); $include_suggest_lib = $this->getOption('with-suggested-libs'); - [$extensions, $libraries, $not_included] = DependencyUtil::getExtsAndLibs($extensions, $libraries, $include_suggest_ext, $include_suggest_lib); + [$extensions, $libraries, $not_included] = DependencyUtil::getExtsAndLibs(array_merge($static_extensions, $dynamic_extensions), $libraries, $include_suggest_ext, $include_suggest_lib); $display_libs = array_filter($libraries, fn ($lib) => in_array(Config::getLib($lib, 'type', 'lib'), ['lib', 'package'])); - $dynamic_libs = $dynamic_exts = array_filter($extensions, function (string $ext) { - $classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\builder\extension'); - $extension = array_find($classes, function (string $class) use ($ext) { - $a = explode('\\', $class); - return end($a) === $ext; - }); - if (!$extension) { - return false; - } - $reflector = new \ReflectionClass($extension); - $attributes = $reflector->getAttributes(); - return array_find($attributes, fn ($attr) => $attr->getName() === DynamicExt::class) !== null; - }); - $extensions = array_diff($extensions, $dynamic_exts); - $libraries = array_diff($libraries, $dynamic_libs); + $display_extensions = array_map(fn ($ext) => in_array($ext, $dynamic_extensions) ? "*{$ext}" : $ext, $extensions); // print info $indent_texts = [ 'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')', 'Build SAPI' => $builder->getBuildTypeName($rule), - 'Extensions (' . count($extensions) . ')' => implode(',', $extensions), + 'Extensions (' . count($extensions) . ')' => implode(',', $display_extensions), 'Libraries (' . count($libraries) . ')' => implode(',', $display_libs), 'Strip Binaries' => $builder->getOption('no-strip') ? 'no' : 'yes', 'Enable ZTS' => $builder->getOption('enable-zts') ? 'yes' : 'no', ]; + if (!empty($dynamic_exts) || ($rule & BUILD_TARGET_EMBED) || ($rule & BUILD_TARGET_DEV)) { + $indent_texts['Build Dev'] = 'yes'; + } if (!empty($this->input->getOption('with-config-file-path'))) { $indent_texts['Config File Path'] = $this->input->getOption('with-config-file-path'); } @@ -168,7 +160,7 @@ class BuildPHPCommand extends BuildCommand // compile libraries $builder->proveLibs($libraries); // check extensions - $builder->proveExts($extensions); + $builder->proveExts($extensions, shared_build_extensions: $dynamic_extensions); // validate libs and extensions $builder->validateLibsAndExts(); @@ -199,11 +191,9 @@ class BuildPHPCommand extends BuildCommand // start to build $builder->buildPHP($rule); - if ($rule & BUILD_TARGET_EMBED) { - // build dynamic extensions - $builder->proveLibs($dynamic_libs); - // build or install libraries - $builder->setupLibs(); + // build dynamic extensions if needed + if (!empty($dynamic_exts)) { + $builder->buildDynamicExts(); } // compile stopwatch :P @@ -240,7 +230,7 @@ class BuildPHPCommand extends BuildCommand file_put_contents(BUILD_ROOT_PATH . '/build-libraries.json', json_encode($libraries, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); // export licenses $dumper = new LicenseDumper(); - $dumper->addExts($extensions)->addLibs($libraries)->addLibs($dynamic_libs)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license'); + $dumper->addExts($extensions)->addLibs($libraries)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license'); $path = FileSystem::convertPath("{$build_root_path}/license/"); logger()->info("License path{$fixed}: {$path}"); return static::SUCCESS; @@ -262,13 +252,14 @@ class BuildPHPCommand extends BuildCommand /** * Parse build options to rule int. */ - private function parseRules(): int + private function parseRules(array $dynamic_exts = []): 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-dev') || !empty($dynamic_exts) ? BUILD_TARGET_DEV : BUILD_TARGET_NONE); $rule |= ($this->getOption('build-all') ? BUILD_TARGET_ALL : BUILD_TARGET_NONE); return $rule; }