diff --git a/phpunit/src/Backend/BackendTest.php b/phpunit/src/Backend/BackendTest.php index 9316f0e5..8427c6c4 100644 --- a/phpunit/src/Backend/BackendTest.php +++ b/phpunit/src/Backend/BackendTest.php @@ -153,7 +153,7 @@ class BackendTest extends TestCase $this->assertStringContainsString('/TC', $cmd); $this->assertStringContainsString('/fsanitize=address', $cmd); $this->assertStringContainsString('/DPPROF_ON=1', $cmd); - $this->assertStringContainsString('/DPROF_OUTPUT_FILE=', $cmd); + $this->assertStringContainsString('/D' . escapeshellarg('PROF_OUTPUT_FILE="app.prof"'), $cmd); $this->assertStringContainsString('/DFEATURE_X=1', $cmd); $this->assertStringContainsString('/GL', $cmd); $this->assertStringContainsString('/DZTS', $cmd); @@ -326,7 +326,7 @@ class BackendTest extends TestCase $this->assertStringContainsString('-fsanitize=address', $cmd); $this->assertStringContainsString('-DPPROF_ON=1', $cmd); - $this->assertStringContainsString('-DPROF_OUTPUT_FILE=', $cmd); + $this->assertStringContainsString('-D' . escapeshellarg('PROF_OUTPUT_FILE="app.prof"'), $cmd); $this->assertStringContainsString('-DFEATURE_X=1', $cmd); $this->assertStringContainsString('-flto', $cmd); $this->assertStringContainsString('-march=native', $cmd); diff --git a/phpunit/src/CompilerBaseApiTest.php b/phpunit/src/CompilerBaseApiTest.php index e7df6af8..080d0078 100644 --- a/phpunit/src/CompilerBaseApiTest.php +++ b/phpunit/src/CompilerBaseApiTest.php @@ -301,6 +301,75 @@ YAML); $this->assertSame(['/yaml/lib'], $this->compiler->getLinkPaths()); } + public function testCCompileCommandOptionsKeepCommonUserConfiguration(): void + { + $this->setPropertyValue('userIncludePaths', ['/user/include']); + $this->setPropertyValue('userDefines', ['FEATURE_X=1']); + $this->setPropertyValue('buildMode', CompilerBase::BUILD_MODE_EXT); + $this->setPropertyValue('enableProfiler', true); + $this->setPropertyValue('enableLto', true); + $this->setPropertyValue('sanitize', 'address'); + $this->setPropertyValue('targetPlatform', 'aarch64-linux-gnu'); + $this->setPropertyValue('march', 'native'); + + $options = $this->invokeMethod('getCCompileCommandOptions'); + + $this->assertContains('/user/include', $options['include_paths']); + $this->assertSame(['FEATURE_X=1'], $options['user_defines']); + $this->assertSame(CompilerBase::BUILD_MODE_EXT, $options['build_mode']); + $this->assertTrue($options['enable_profiler']); + $this->assertTrue($options['lto']); + $this->assertSame('address', $options['sanitize']); + $this->assertSame('aarch64-linux-gnu', $options['target_platform']); + $this->assertSame('native', $options['march']); + } + + public function testNativeCompileCommandOptionsKeepCommonUserConfiguration(): void + { + $this->setPropertyValue('userIncludePaths', ['/native/include']); + $this->setPropertyValue('userDefines', ['NATIVE_FEATURE=1']); + $this->setPropertyValue('buildMode', CompilerBase::BUILD_MODE_EXT); + $this->setPropertyValue('enableProfiler', true); + $this->setPropertyValue('enableLto', true); + + $options = $this->invokeMethod('getNativeCompileCommandOptions', 'objective-c'); + + $this->assertContains('/native/include', $options['include_paths']); + $this->assertSame(['NATIVE_FEATURE=1'], $options['user_defines']); + $this->assertSame(CompilerBase::BUILD_MODE_EXT, $options['build_mode']); + $this->assertTrue($options['enable_profiler']); + $this->assertTrue($options['lto']); + $this->assertArrayNotHasKey('cpp_std', $options); + $this->assertArrayNotHasKey('cxxflags', $options); + } + + public function testObjectiveCppCompileCommandOptionsKeepCppOptions(): void + { + $this->setPropertyValue('cxxStd', 'c++20'); + $this->setPropertyValue('cxxFlags', '-fobjc-arc'); + + $options = $this->invokeMethod('getNativeCompileCommandOptions', 'objective-c++'); + + $this->assertSame('c++20', $options['cpp_std']); + $this->assertSame('-fobjc-arc', $options['cxxflags']); + } + + public function testLinkCommandOptionsPassUserLibrariesThroughBackendFields(): void + { + $this->setPropertyValue('linkLibs', ['curl', 'ssl']); + $this->setPropertyValue('linkPaths', ['/user/lib']); + $this->setPropertyValue('enableProfiler', true); + $this->setPropertyValue('ldflags', '-Wl,--as-needed'); + + $options = $this->invokeMethod('getLinkCommandOptions'); + + $this->assertContains('/user/lib', $options['library_paths']); + $this->assertContains('profiler', $options['libraries']); + $this->assertContains('curl', $options['libraries']); + $this->assertContains('ssl', $options['libraries']); + $this->assertSame('-Wl,--as-needed', $options['ldflags']); + } + public function testFormatCppCodeEscapesPathsWithSpaces(): void { $spaceDir = sys_get_temp_dir() . '/compiler api format ' . uniqid(); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 98bc550a..877a8031 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -1486,7 +1486,7 @@ CODE; } } - protected function getCompileCommandOptions(): array + protected function getCommonCompileCommandOptions(): array { // 包含路径:系统路径 + 用户自定义路径 $includePaths = $this->getIncludePaths(); @@ -1499,36 +1499,31 @@ CODE; 'optimize' => $this->optimizeLevel, 'debug' => $this->debug, 'sanitize' => $this->sanitize, - 'cpp_std' => $this->cxxStd, 'march' => $this->march, 'target_platform' => $this->targetPlatform, 'is_zts' => $this->isPhpZts, 'build_mode' => $this->buildMode, 'enable_profiler' => $this->enableProfiler, 'prof_output' => $this->targetName . '.prof', - 'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [], - 'cxxflags' => $this->cxxFlags, 'user_defines' => $this->userDefines, 'lto' => $this->enableLto, ]; } + protected function getCompileCommandOptions(): array + { + $options = $this->getCommonCompileCommandOptions(); + $options['cpp_std'] = $this->cxxStd; + $options['cxxflags'] = $this->cxxFlags; + $options['suppressed_warnings'] = Constants::MSVC_SUPPRESSED_WARNINGS ?? []; + return $options; + } + protected function getCCompileCommandOptions(): array { - return [ - 'include_paths' => $this->getIncludePaths(), - 'optimize' => 0, - 'debug' => $this->debug, - 'sanitize' => $this->sanitize, - 'is_zts' => $this->isPhpZts, - 'enable_profiler' => $this->enableProfiler, - 'prof_output' => $this->targetName . '.prof', - 'user_defines' => $this->userDefines, - 'lto' => $this->enableLto, - 'march' => $this->march, - 'target_platform' => $this->targetPlatform, - 'suppressed_warnings' => ['4244', '4146'], - ]; + $options = $this->getCommonCompileCommandOptions(); + $options['suppressed_warnings'] = ['4244', '4146']; + return $options; } /** @@ -1538,41 +1533,30 @@ CODE; */ protected function getNativeCompileCommandOptions(string $language = ''): array { - return [ - 'include_paths' => $this->getIncludePaths(), - 'optimize' => $this->optimizeLevel, - 'debug' => $this->debug, - 'sanitize' => $this->sanitize, - 'is_zts' => $this->isPhpZts, - 'build_mode' => $this->buildMode, - 'enable_profiler' => $this->enableProfiler, - 'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [], - 'march' => $this->march, - 'target_platform' => $this->targetPlatform, - ]; + $options = $this->getCommonCompileCommandOptions(); + $options['suppressed_warnings'] = Constants::MSVC_SUPPRESSED_WARNINGS ?? []; + + if ($language === 'objective-c++') { + $options['cpp_std'] = $this->cxxStd; + $options['cxxflags'] = $this->cxxFlags; + } + + return $options; } protected function getLinkCommandOptions(): array { $ldflags = $this->ldflags; - + $libraryPaths = array_merge($this->getLibraryPaths(), $this->linkPaths); + $libraries = $this->getLibraries(); if ($this->enableProfiler) { - $ldflags .= ' -lprofiler'; - } - - // 用户通过 --link-lib / -l 指定的链接库 - foreach ($this->linkLibs as $lib) { - $ldflags .= ' -l' . $lib; - } - - // 用户通过 --link-path / -L 指定的库搜索路径 - foreach ($this->linkPaths as $path) { - $ldflags .= ' -L' . escapeshellarg($path); + $libraries[] = 'profiler'; } + $libraries = array_merge($libraries, $this->linkLibs); $options = [ - 'library_paths' => $this->getLibraryPaths(), - 'libraries' => $this->getLibraries(), + 'library_paths' => $libraryPaths, + 'libraries' => $libraries, 'ldflags' => $ldflags, 'debug' => $this->debug, 'no_console' => $this->noConsole,