From 5a6a33303c5242032a3bbe0211786b2e762a3811 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 31 Oct 2025 16:48:21 +0800 Subject: [PATCH] Export php binary debug symbols for mac, linux and windows --- src/SPC/builder/linux/LinuxBuilder.php | 89 +++++----------------- src/SPC/builder/macos/MacOSBuilder.php | 48 +++++------- src/SPC/builder/unix/UnixBuilderBase.php | 71 +++++++++++++---- src/SPC/builder/windows/WindowsBuilder.php | 78 ++++++++++++------- src/SPC/store/FileSystem.php | 3 + 5 files changed, 151 insertions(+), 138 deletions(-) diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 3995c3a8..5ffa6a4d 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace SPC\builder\linux; use SPC\builder\unix\UnixBuilderBase; -use SPC\exception\PatchException; use SPC\exception\WrongUsageException; use SPC\store\Config; use SPC\store\FileSystem; @@ -194,14 +193,6 @@ class LinuxBuilder extends UnixBuilderBase SourcePatcher::patchFile('musl_static_readline.patch', SOURCE_PATH . '/php-src', true); } - if (!$this->getOption('no-strip', false)) { - shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-unneeded php'); - } - if ($this->getOption('with-upx-pack')) { - shell()->cd(SOURCE_PATH . '/php-src/sapi/cli') - ->exec(getenv('UPX_EXEC') . ' --best php'); - } - $this->deployBinary(BUILD_TARGET_CLI); } @@ -213,14 +204,6 @@ class LinuxBuilder extends UnixBuilderBase ->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec("make {$concurrency} {$vars} cgi"); - if (!$this->getOption('no-strip', false)) { - shell()->cd(SOURCE_PATH . '/php-src/sapi/cgi')->exec('strip --strip-unneeded php-cgi'); - } - if ($this->getOption('with-upx-pack')) { - shell()->cd(SOURCE_PATH . '/php-src/sapi/cgi') - ->exec(getenv('UPX_EXEC') . ' --best php-cgi'); - } - $this->deployBinary(BUILD_TARGET_CGI); } @@ -232,29 +215,29 @@ class LinuxBuilder extends UnixBuilderBase if ($this->getPHPVersionID() < 80000) { throw new WrongUsageException('phpmicro only support PHP >= 8.0!'); } - if ($this->getExt('phar')) { - $this->phar_patched = true; - SourcePatcher::patchMicroPhar($this->getPHPVersionID()); - } + try { + if ($this->getExt('phar')) { + $this->phar_patched = true; + SourcePatcher::patchMicroPhar($this->getPHPVersionID()); + } - $enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; - $vars = $this->getMakeExtraVars(); + $enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; + $vars = $this->getMakeExtraVars(); - // patch fake cli for micro - $vars['EXTRA_CFLAGS'] .= $enable_fake_cli; - $vars = SystemUtil::makeEnvVarString($vars); - $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; + // patch fake cli for micro + $vars['EXTRA_CFLAGS'] .= $enable_fake_cli; + $vars = SystemUtil::makeEnvVarString($vars); + $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; - shell()->cd(SOURCE_PATH . '/php-src') - ->exec('sed -i "s|//lib|/lib|g" Makefile') - ->exec("make {$concurrency} {$vars} micro"); + shell()->cd(SOURCE_PATH . '/php-src') + ->exec('sed -i "s|//lib|/lib|g" Makefile') + ->exec("make {$concurrency} {$vars} micro"); - $this->processMicroUPX(); - - $this->deployBinary(BUILD_TARGET_MICRO); - - if ($this->phar_patched) { - SourcePatcher::unpatchMicroPhar(); + $this->deployBinary(BUILD_TARGET_MICRO); + } finally { + if ($this->phar_patched) { + SourcePatcher::unpatchMicroPhar(); + } } } @@ -269,13 +252,6 @@ class LinuxBuilder extends UnixBuilderBase ->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec("make {$concurrency} {$vars} fpm"); - if (!$this->getOption('no-strip', false)) { - shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-unneeded php-fpm'); - } - if ($this->getOption('with-upx-pack')) { - shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm') - ->exec(getenv('UPX_EXEC') . ' --best php-fpm'); - } $this->deployBinary(BUILD_TARGET_FPM); } @@ -390,31 +366,4 @@ class LinuxBuilder extends UnixBuilderBase 'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie", ]); } - - /** - * Strip micro.sfx for Linux. - * The micro.sfx does not support UPX directly, but we can remove UPX-info segment to adapt. - * This will also make micro.sfx with upx-packed more like a malware fore antivirus :( - */ - private function processMicroUPX(): void - { - if (version_compare($this->getMicroVersion(), '0.2.0') >= 0 && !$this->getOption('no-strip', false)) { - shell()->exec('strip --strip-unneeded ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx'); - - if ($this->getOption('with-upx-pack')) { - // strip first - shell()->exec(getenv('UPX_EXEC') . ' --best ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx'); - // cut binary with readelf - [$ret, $out] = shell()->execWithResult('readelf -l ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx | awk \'/LOAD|GNU_STACK/ {getline; print $1, $2, $3, $4, $6, $7}\''); - $out[1] = explode(' ', $out[1]); - $offset = $out[1][0]; - if ($ret !== 0 || !str_starts_with($offset, '0x')) { - throw new PatchException('phpmicro UPX patcher', 'Cannot find offset in readelf output'); - } - $offset = hexdec($offset); - // remove upx extra wastes - file_put_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx', substr(file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx'), 0, $offset)); - } - } - } } diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index bcfaf6cf..d3bc5d19 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -189,9 +189,6 @@ class MacOSBuilder extends UnixBuilderBase $shell = shell()->cd(SOURCE_PATH . '/php-src'); $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; $shell->exec("make {$concurrency} {$vars} cli"); - if (!$this->getOption('no-strip', false)) { - $shell->exec('dsymutil -f sapi/cli/php')->exec('strip -S sapi/cli/php'); - } $this->deployBinary(BUILD_TARGET_CLI); } @@ -202,9 +199,6 @@ class MacOSBuilder extends UnixBuilderBase $shell = shell()->cd(SOURCE_PATH . '/php-src'); $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; $shell->exec("make {$concurrency} {$vars} cgi"); - if (!$this->getOption('no-strip', false)) { - $shell->exec('dsymutil -f sapi/cgi/php-cgi')->exec('strip -S sapi/cgi/php-cgi'); - } $this->deployBinary(BUILD_TARGET_CGI); } @@ -216,31 +210,30 @@ class MacOSBuilder extends UnixBuilderBase if ($this->getPHPVersionID() < 80000) { throw new WrongUsageException('phpmicro only support PHP >= 8.0!'); } - if ($this->getExt('phar')) { - $this->phar_patched = true; - SourcePatcher::patchMicroPhar($this->getPHPVersionID()); - } - $enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; - $vars = $this->getMakeExtraVars(); + try { + if ($this->getExt('phar')) { + $this->phar_patched = true; + SourcePatcher::patchMicroPhar($this->getPHPVersionID()); + } - // patch fake cli for micro - $vars['EXTRA_CFLAGS'] .= $enable_fake_cli; - $vars = SystemUtil::makeEnvVarString($vars); + $enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; + $vars = $this->getMakeExtraVars(); - $shell = shell()->cd(SOURCE_PATH . '/php-src'); - // build - $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; - $shell->exec("make {$concurrency} {$vars} micro"); - // strip - if (!$this->getOption('no-strip', false)) { - $shell->exec('dsymutil -f sapi/micro/micro.sfx')->exec('strip -S sapi/micro/micro.sfx'); - } + // patch fake cli for micro + $vars['EXTRA_CFLAGS'] .= $enable_fake_cli; + $vars = SystemUtil::makeEnvVarString($vars); - $this->deployBinary(BUILD_TARGET_MICRO); + $shell = shell()->cd(SOURCE_PATH . '/php-src'); + // build + $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; + $shell->exec("make {$concurrency} {$vars} micro"); - if ($this->phar_patched) { - SourcePatcher::unpatchMicroPhar(); + $this->deployBinary(BUILD_TARGET_MICRO); + } finally { + if ($this->phar_patched) { + SourcePatcher::unpatchMicroPhar(); + } } } @@ -254,9 +247,6 @@ class MacOSBuilder extends UnixBuilderBase $shell = shell()->cd(SOURCE_PATH . '/php-src'); $concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : ''; $shell->exec("make {$concurrency} {$vars} fpm"); - if (!$this->getOption('no-strip', false)) { - $shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip -S sapi/fpm/php-fpm'); - } $this->deployBinary(BUILD_TARGET_FPM); } diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index 0d123d1f..8122bf2c 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -6,6 +6,7 @@ namespace SPC\builder\unix; use SPC\builder\BuilderBase; use SPC\builder\linux\SystemUtil as LinuxSystemUtil; +use SPC\exception\PatchException; use SPC\exception\SPCException; use SPC\exception\SPCInternalException; use SPC\exception\ValidationException; @@ -210,21 +211,71 @@ abstract class UnixBuilderBase extends BuilderBase /** * Deploy the binary file to the build bin path. * - * @param int $type Type integer, one of BUILD_TARGET_CLI, BUILD_TARGET_MICRO, BUILD_TARGET_FPM + * @param int $type Type integer, one of BUILD_TARGET_CLI, BUILD_TARGET_MICRO, BUILD_TARGET_FPM, BUILD_TARGET_CGI, BUILD_TARGET_FRANKENPHP */ - protected function deployBinary(int $type): bool + protected function deployBinary(int $type): void { + FileSystem::createDir(BUILD_BIN_PATH); + $copy_files = []; $src = match ($type) { BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php', BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx', BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm', BUILD_TARGET_CGI => SOURCE_PATH . '/php-src/sapi/cgi/php-cgi', + BUILD_TARGET_FRANKENPHP => BUILD_BIN_PATH . '/frankenphp', default => throw new SPCInternalException("Deployment does not accept type {$type}"), }; - logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file'); - FileSystem::createDir(BUILD_BIN_PATH); - shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH)); - return true; + $no_strip_option = (bool) $this->getOption('no-strip', false); + $upx_option = (bool) $this->getOption('with-upx-pack', false); + + // Generate debug symbols if needed + $copy_files[] = $src; + if (!$no_strip_option && PHP_OS_FAMILY === 'Darwin') { + shell() + ->exec("dsymutil -f {$src}") // generate .dwarf file + ->exec("strip -S {$src}"); // strip unneeded symbols + $copy_files[] = "{$src}.dwarf"; + } elseif (!$no_strip_option && PHP_OS_FAMILY === 'Linux') { + shell() + ->exec("objcopy --only-keep-debug {$src} {$src}.debug") // extract debug symbols + ->exec("objcopy --strip-debug --add-gnu-debuglink={$src}.debug {$src}") // link debug symbols + ->exec("strip --strip-unneeded {$src}"); // strip unneeded symbols + $copy_files[] = "{$src}.debug"; + } + + // Compress binary with UPX if needed (only for Linux) + if ($upx_option && PHP_OS_FAMILY === 'Linux') { + if ($no_strip_option) { + logger()->warning('UPX compression is not recommended when --no-strip is enabled.'); + } + logger()->info("Compressing {$src} with UPX"); + shell()->exec(getenv('UPX_EXEC') . " --best {$src}"); + + // micro needs special section handling in LinuxBuilder. + // The micro.sfx does not support UPX directly, but we can remove UPX-info segment to adapt. + // This will also make micro.sfx with upx-packed more like a malware fore antivirus :( + if ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0) { + // strip first + // cut binary with readelf + [$ret, $out] = shell()->execWithResult("readelf -l {$src} | awk '/LOAD|GNU_STACK/ {getline; print \$1, \$2, \$3, \$4, \$6, \$7}'"); + $out[1] = explode(' ', $out[1]); + $offset = $out[1][0]; + if ($ret !== 0 || !str_starts_with($offset, '0x')) { + throw new PatchException('phpmicro UPX patcher', 'Cannot find offset in readelf output'); + } + $offset = hexdec($offset); + // remove upx extra wastes + file_put_contents($src, substr(file_get_contents($src), 0, $offset)); + } + } + + // Copy files + foreach ($copy_files as $file) { + if (!file_exists($file)) { + throw new SPCInternalException("Deploy failed. Cannot find file: {$file}"); + } + FileSystem::copy($file, BUILD_BIN_PATH . '/' . basename($file)); + } } /** @@ -325,13 +376,7 @@ abstract class UnixBuilderBase extends BuilderBase ->setEnv($env) ->exec("xcaddy build --output frankenphp {$xcaddyModules}"); - if (!$this->getOption('no-strip', false) && file_exists(BUILD_BIN_PATH . '/frankenphp')) { - if (PHP_OS_FAMILY === 'Linux') { - shell()->cd(BUILD_BIN_PATH)->exec('strip --strip-unneeded frankenphp'); - } else { // macOS doesn't understand strip-unneeded - shell()->cd(BUILD_BIN_PATH)->exec('strip -S frankenphp'); - } - } + $this->deployBinary(BUILD_TARGET_FRANKENPHP); } /** diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 1892d801..35b1623d 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -67,21 +67,6 @@ class WindowsBuilder extends BuilderBase $zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no '; - // with-upx-pack for phpmicro - if ($enableMicro && version_compare($this->getMicroVersion(), '0.2.0') < 0) { - $makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32'); - if ($this->getOption('with-upx-pack', false)) { - if (!file_exists($makefile . '.originfile')) { - copy($makefile, $makefile . '.originfile'); - FileSystem::replaceFileStr($makefile, '$(MICRO_SFX):', '_MICRO_UPX = ' . getenv('UPX_EXEC') . " --best $(MICRO_SFX)\n$(MICRO_SFX):"); - FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)"); - } - } elseif (file_exists($makefile . '.originfile')) { - copy($makefile . '.originfile', $makefile); - unlink($makefile . '.originfile'); - } - } - $opcache_jit = !$this->getOption('disable-opcache-jit', false); $opcache_jit_arg = $opcache_jit ? '--enable-opcache-jit=yes ' : '--enable-opcache-jit=no '; @@ -145,7 +130,7 @@ class WindowsBuilder extends BuilderBase } } - public function testPHP(int $build_target = BUILD_TARGET_NONE) + public function testPHP(int $build_target = BUILD_TARGET_NONE): void { $this->sanityCheck($build_target); } @@ -156,8 +141,23 @@ class WindowsBuilder extends BuilderBase $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; + // Add debug symbols for release build if --no-strip is specified + // We need to modify CFLAGS to replace /Ox with /Zi and add /DEBUG to LDFLAGS + $debug_overrides = ''; + if ($this->getOption('no-strip', false)) { + // Read current CFLAGS from Makefile and replace optimization flags + $makefile_content = file_get_contents(SOURCE_PATH . '\php-src\Makefile'); + if (preg_match('/^CFLAGS=(.+?)$/m', $makefile_content, $matches)) { + $cflags = $matches[1]; + // Replace /Ox (full optimization) with /Zi (debug info) and /Od (disable optimization) + // Keep optimization for speed: /O2 /Zi instead of /Od /Zi + $cflags = str_replace('/Ox ', '/O2 /Zi ', $cflags); + $debug_overrides = '"CFLAGS=' . $cflags . '" "LDFLAGS=/DEBUG /LTCG /INCREMENTAL:NO" "LDFLAGS_CLI=/DEBUG" '; + } + } + // add nmake wrapper - FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cli_wrapper.bat', "nmake /nologo LIBS_CLI=\"ws2_32.lib shell32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); + FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cli_wrapper.bat', "nmake /nologo {$debug_overrides}LIBS_CLI=\"ws2_32.lib shell32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cli_wrapper.bat --task-args php.exe"); @@ -170,8 +170,19 @@ class WindowsBuilder extends BuilderBase $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; + // Add debug symbols for release build if --no-strip is specified + $debug_overrides = ''; + if ($this->getOption('no-strip', false)) { + $makefile_content = file_get_contents(SOURCE_PATH . '\php-src\Makefile'); + if (preg_match('/^CFLAGS=(.+?)$/m', $makefile_content, $matches)) { + $cflags = $matches[1]; + $cflags = str_replace('/Ox ', '/O2 /Zi ', $cflags); + $debug_overrides = '"CFLAGS=' . $cflags . '" "LDFLAGS=/DEBUG /LTCG /INCREMENTAL:NO" "LDFLAGS_CGI=/DEBUG" '; + } + } + // add nmake wrapper - FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo LIBS_CGI=\"ws2_32.lib kernel32.lib advapi32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); + FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo {$debug_overrides}LIBS_CGI=\"ws2_32.lib kernel32.lib advapi32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe"); @@ -202,9 +213,20 @@ class WindowsBuilder extends BuilderBase $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; + // Add debug symbols for release build if --no-strip is specified + $debug_overrides = ''; + if ($this->getOption('no-strip', false) && !$this->getOption('debug', false)) { + $makefile_content = file_get_contents(SOURCE_PATH . '\php-src\Makefile'); + if (preg_match('/^CFLAGS=(.+?)$/m', $makefile_content, $matches)) { + $cflags = $matches[1]; + $cflags = str_replace('/Ox ', '/O2 /Zi ', $cflags); + $debug_overrides = '"CFLAGS=' . $cflags . '" "LDFLAGS=/DEBUG /LTCG /INCREMENTAL:NO" "LDFLAGS_MICRO=/DEBUG" '; + } + } + // add nmake wrapper $fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' /DPHP_MICRO_FAKE_CLI" ' : ''; - $wrapper = "nmake /nologo LIBS_MICRO=\"ws2_32.lib shell32.lib {$extra_libs}\" CFLAGS_MICRO=\"/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1{$fake_cli}\" %*"; + $wrapper = "nmake /nologo {$debug_overrides}LIBS_MICRO=\"ws2_32.lib shell32.lib {$extra_libs}\" CFLAGS_MICRO=\"/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1{$fake_cli}\" %*"; FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_micro_wrapper.bat', $wrapper); // phar patch for micro @@ -335,28 +357,32 @@ class WindowsBuilder extends BuilderBase * * @param int $type Deploy type */ - public function deployBinary(int $type): bool + public function deployBinary(int $type): void { + $rel_type = 'Release'; // TODO: Debug build support $ts = $this->zts ? '_TS' : ''; $src = match ($type) { - BUILD_TARGET_CLI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php.exe", - BUILD_TARGET_MICRO => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\micro.sfx", - BUILD_TARGET_CGI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php-cgi.exe", + BUILD_TARGET_CLI => [SOURCE_PATH . "\\php-src\\x64\\{$rel_type}{$ts}", 'php.exe', 'php.pdb'], + BUILD_TARGET_MICRO => [SOURCE_PATH . "\\php-src\\x64\\{$rel_type}{$ts}", 'micro.sfx', 'micro.pdb'], + BUILD_TARGET_CGI => [SOURCE_PATH . "\\php-src\\x64\\{$rel_type}{$ts}", 'php-cgi.exe', 'php-cgi.pdb'], default => throw new SPCInternalException("Deployment does not accept type {$type}"), }; // with-upx-pack for cli and micro if ($this->getOption('with-upx-pack', false)) { if ($type === BUILD_TARGET_CLI || $type === BUILD_TARGET_CGI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) { - cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src)); + cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg("{$src[0]}\\{$src[1]}")); } } logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file'); FileSystem::createDir(BUILD_BIN_PATH); - cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH . '\\')); - return true; + cmd()->exec('copy ' . escapeshellarg("{$src[0]}\\{$src[1]}") . ' ' . escapeshellarg(BUILD_BIN_PATH . '\\')); + if ($this->getOption('no-strip', false) && file_exists("{$src[0]}\\{$src[2]}")) { + logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' debug symbols'); + cmd()->exec('copy ' . escapeshellarg("{$src[0]}\\{$src[2]}") . ' ' . escapeshellarg(BUILD_BIN_PATH . '\\')); + } } /** diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php index f6ce371e..86daefc4 100644 --- a/src/SPC/store/FileSystem.php +++ b/src/SPC/store/FileSystem.php @@ -174,6 +174,9 @@ class FileSystem logger()->debug("Copying file from {$from} to {$to}"); $dst_path = FileSystem::convertPath($to); $src_path = FileSystem::convertPath($from); + if ($src_path === $dst_path) { + return; + } if (!copy($src_path, $dst_path)) { throw new FileSystemException('Cannot copy file from ' . $src_path . ' to ' . $dst_path); }