1414use StaticPHP \Attribute \Package \Target ;
1515use StaticPHP \Attribute \Package \Validate ;
1616use StaticPHP \Attribute \PatchDescription ;
17+ use StaticPHP \Config \PackageConfig ;
1718use StaticPHP \DI \ApplicationContext ;
1819use StaticPHP \Exception \SPCException ;
1920use StaticPHP \Exception \WrongUsageException ;
@@ -111,7 +112,7 @@ public function init(TargetPackage $package): void
111112 }
112113
113114 #[ResolveBuild]
114- public function resolveBuild (TargetPackage $ package ): array
115+ public function resolveBuild (TargetPackage $ package, PackageInstaller $ installer ): array
115116 {
116117 // Parse extensions and additional packages for all php-* targets
117118 $ static_extensions = parse_extension_list ($ package ->getBuildArgument ('extensions ' ));
@@ -128,6 +129,7 @@ public function resolveBuild(TargetPackage $package): array
128129 // get instances
129130 foreach ($ extensions_pkg as $ extension ) {
130131 $ extname = substr ($ extension , 4 );
132+ $ config = PackageConfig::get ($ extension , 'php-extension ' , []);
131133 if (!PackageLoader::hasPackage ($ extension )) {
132134 throw new WrongUsageException ("Extension [ {$ extname }] does not exist. Please check your extension name. " );
133135 }
@@ -137,13 +139,25 @@ public function resolveBuild(TargetPackage $package): array
137139 }
138140 // set build static/shared
139141 if (in_array ($ extname , $ static_extensions )) {
142+ if (($ config ['build-static ' ] ?? true ) === false ) {
143+ throw new WrongUsageException ("Extension [ {$ extname }] cannot be built as static extension. " );
144+ }
140145 $ instance ->setBuildStatic ();
141146 }
142147 if (in_array ($ extname , $ shared_extensions )) {
148+ if (($ config ['build-shared ' ] ?? true ) === false ) {
149+ throw new WrongUsageException ("Extension [ {$ extname }] cannot be built as shared extension, please remove it from --build-shared option. " );
150+ }
143151 $ instance ->setBuildShared ();
152+ $ instance ->setBuildWithPhp ($ config ['build-with-php ' ] ?? false );
144153 }
145154 }
146155
156+ // building shared extensions need embed SAPI
157+ if (!empty ($ shared_extensions ) && !$ package ->getBuildOption ('build-embed ' , false ) && $ package ->getName () === 'php ' ) {
158+ $ installer ->addBuildPackage ('php-embed ' );
159+ }
160+
147161 return [...$ extensions_pkg , ...$ additional_packages ];
148162 }
149163
@@ -178,14 +192,14 @@ public function info(Package $package, PackageInstaller $installer): array
178192 return [];
179193 }
180194 $ sapis = array_filter ([
181- $ installer ->getBuildPackage ('php-cli ' ) ? 'cli ' : null ,
182- $ installer ->getBuildPackage ('php-fpm ' ) ? 'fpm ' : null ,
183- $ installer ->getBuildPackage ('php-micro ' ) ? 'micro ' : null ,
184- $ installer ->getBuildPackage ('php-cgi ' ) ? 'cgi ' : null ,
185- $ installer ->getBuildPackage ('php-embed ' ) ? 'embed ' : null ,
186- $ installer ->getBuildPackage ('frankenphp ' ) ? 'frankenphp ' : null ,
195+ $ installer ->isPackageResolved ('php-cli ' ) ? 'cli ' : null ,
196+ $ installer ->isPackageResolved ('php-fpm ' ) ? 'fpm ' : null ,
197+ $ installer ->isPackageResolved ('php-micro ' ) ? 'micro ' : null ,
198+ $ installer ->isPackageResolved ('php-cgi ' ) ? 'cgi ' : null ,
199+ $ installer ->isPackageResolved ('php-embed ' ) ? 'embed ' : null ,
200+ $ installer ->isPackageResolved ('frankenphp ' ) ? 'frankenphp ' : null ,
187201 ]);
188- $ static_extensions = array_filter ($ installer ->getResolvedPackages (), fn ($ x ) => $ x-> getType () === ' php-extension ' );
202+ $ static_extensions = array_filter ($ installer ->getResolvedPackages (), fn ($ x ) => $ x instanceof PhpExtensionPackage && $ x -> isBuildStatic () );
189203 $ shared_extensions = parse_extension_list ($ package ->getBuildOption ('build-shared ' ) ?? []);
190204 $ install_packages = array_filter ($ installer ->getResolvedPackages (), fn ($ x ) => $ x ->getType () !== 'php-extension ' && $ x ->getName () !== 'php ' && !str_starts_with ($ x ->getName (), 'php- ' ));
191205 return [
@@ -281,15 +295,15 @@ public function configureForUnix(TargetPackage $package, PackageInstaller $insta
281295 $ args [] = "--with-config-file-scan-dir= {$ option }" ;
282296 }
283297 // perform enable cli options
284- $ args [] = $ installer ->isBuildPackage ('php-cli ' ) ? '--enable-cli ' : '--disable-cli ' ;
285- $ args [] = $ installer ->isBuildPackage ('php-fpm ' ) ? '--enable-fpm ' : '--disable-fpm ' ;
286- $ args [] = $ installer ->isBuildPackage ('php-micro ' ) ? match (SystemTarget::getTargetOS ()) {
298+ $ args [] = $ installer ->isPackageResolved ('php-cli ' ) ? '--enable-cli ' : '--disable-cli ' ;
299+ $ args [] = $ installer ->isPackageResolved ('php-fpm ' ) ? '--enable-fpm ' : '--disable-fpm ' ;
300+ $ args [] = $ installer ->isPackageResolved ('php-micro ' ) ? match (SystemTarget::getTargetOS ()) {
287301 'Linux ' => '--enable-micro=all-static ' ,
288302 default => '--enable-micro ' ,
289303 } : null ;
290- $ args [] = $ installer ->isBuildPackage ('php-cgi ' ) ? '--enable-cgi ' : '--disable-cgi ' ;
304+ $ args [] = $ installer ->isPackageResolved ('php-cgi ' ) ? '--enable-cgi ' : '--disable-cgi ' ;
291305 $ embed_type = getenv ('SPC_CMD_VAR_PHP_EMBED_TYPE ' ) ?: 'static ' ;
292- $ args [] = $ installer ->isBuildPackage ('php-embed ' ) ? "--enable-embed= {$ embed_type }" : '--disable-embed ' ;
306+ $ args [] = $ installer ->isPackageResolved ('php-embed ' ) ? "--enable-embed= {$ embed_type }" : '--disable-embed ' ;
293307 $ args [] = getenv ('SPC_EXTRA_PHP_VARS ' ) ?: null ;
294308 $ args = implode (' ' , array_filter ($ args ));
295309
@@ -311,19 +325,19 @@ public function makeForUnix(TargetPackage $package, PackageInstaller $installer)
311325 logger ()->info ('cleaning up php-src build files ' );
312326 shell ()->cd ($ package ->getSourceDir ())->exec ('make clean ' );
313327
314- if ($ installer ->isBuildPackage ('php-cli ' )) {
328+ if ($ installer ->isPackageResolved ('php-cli ' )) {
315329 $ package ->runStage ('unix-make-cli ' );
316330 }
317- if ($ installer ->isBuildPackage ('php-cgi ' )) {
331+ if ($ installer ->isPackageResolved ('php-cgi ' )) {
318332 $ package ->runStage ('unix-make-cgi ' );
319333 }
320- if ($ installer ->isBuildPackage ('php-fpm ' )) {
334+ if ($ installer ->isPackageResolved ('php-fpm ' )) {
321335 $ package ->runStage ('unix-make-fpm ' );
322336 }
323- if ($ installer ->isBuildPackage ('php-micro ' )) {
337+ if ($ installer ->isPackageResolved ('php-micro ' )) {
324338 $ package ->runStage ('unix-make-micro ' );
325339 }
326- if ($ installer ->isBuildPackage ('php-embed ' )) {
340+ if ($ installer ->isPackageResolved ('php-embed ' )) {
327341 $ package ->runStage ('unix-make-embed ' );
328342 }
329343 }
@@ -359,6 +373,7 @@ public function makeFpmForUnix(TargetPackage $package, PackageInstaller $install
359373 }
360374
361375 #[Stage('unix-make-micro ' )]
376+ #[PatchDescription('Patch phar extension for micro SAPI to support compressed phar ' )]
362377 public function makeMicroForUnix (TargetPackage $ package , PackageInstaller $ installer , PackageBuilder $ builder ): void
363378 {
364379 $ phar_patched = false ;
@@ -375,6 +390,8 @@ public function makeMicroForUnix(TargetPackage $package, PackageInstaller $insta
375390 shell ()->cd ($ package ->getSourceDir ())
376391 ->setEnv ($ vars )
377392 ->exec ("make -j {$ builder ->concurrency } micro " );
393+
394+ $ builder ->deployBinary ($ package ->getSourceDir () . '/sapi/micro/micro.sfx ' , BUILD_BIN_PATH . '/micro.sfx ' );
378395 } finally {
379396 if ($ phar_patched ) {
380397 SourcePatcher::unpatchMicroPhar ();
@@ -385,6 +402,7 @@ public function makeMicroForUnix(TargetPackage $package, PackageInstaller $insta
385402 #[Stage('unix-make-embed ' )]
386403 public function makeEmbedForUnix (TargetPackage $ package , PackageInstaller $ installer , PackageBuilder $ builder ): void
387404 {
405+ InteractiveTerm::setMessage ('Building php: ' . ConsoleColor::yellow ('make embed ' ));
388406 $ shared_exts = array_filter (
389407 $ installer ->getResolvedPackages (),
390408 static fn ($ x ) => $ x instanceof PhpExtensionPackage && $ x ->isBuildShared () && $ x ->isBuildWithPhp ()
@@ -395,9 +413,11 @@ public function makeEmbedForUnix(TargetPackage $package, PackageInstaller $insta
395413 $ diff = new DirDiff (BUILD_MODULES_PATH , true );
396414
397415 $ root = BUILD_ROOT_PATH ;
416+ $ sed_prefix = SystemTarget::getTargetOS () === 'Darwin ' ? 'sed -i "" ' : 'sed -i ' ;
417+
398418 shell ()->cd ($ package ->getSourceDir ())
399419 ->setEnv ($ this ->makeVars ($ installer ))
400- ->exec (' sed -i "s|^EXTENSION_DIR = .*|EXTENSION_DIR = /' . basename (BUILD_MODULES_PATH ) . '|" Makefile ' )
420+ ->exec ("{ $ sed_prefix } \ "s|^EXTENSION_DIR = .*|EXTENSION_DIR = / " . basename (BUILD_MODULES_PATH ) . '|" Makefile ' )
401421 ->exec ("make -j {$ builder ->concurrency } INSTALL_ROOT= {$ root } install-sapi {$ install_modules } install-build install-headers install-programs " );
402422
403423 // ------------- SPC_CMD_VAR_PHP_EMBED_TYPE=shared -------------
@@ -417,12 +437,15 @@ public function makeEmbedForUnix(TargetPackage $package, PackageInstaller $insta
417437 // process shared extensions that built-with-php
418438 $ increment_files = $ diff ->getChangedFiles ();
419439 foreach ($ increment_files as $ increment_file ) {
420- $ builder ->deployBinary ($ increment_file , $ libphp_so , false );
440+ $ builder ->deployBinary ($ increment_file , $ increment_file , false );
421441 }
422442
423443 // ------------- SPC_CMD_VAR_PHP_EMBED_TYPE=static -------------
424444
425445 // process libphp.a for static embed
446+ if (!file_exists ("{$ package ->getLibDir ()}/libphp.a " )) {
447+ return ;
448+ }
426449 $ ar = getenv ('AR ' ) ?: 'ar ' ;
427450 $ libphp_a = "{$ package ->getLibDir ()}/libphp.a " ;
428451 shell ()->exec ("{$ ar } -t {$ libphp_a } | grep ' \\.a$' | xargs -n1 {$ ar } d {$ libphp_a }" );
@@ -432,19 +455,9 @@ public function makeEmbedForUnix(TargetPackage $package, PackageInstaller $insta
432455 $ package ->runStage ('patch-embed-scripts ' );
433456 }
434457
435- #[BuildFor('Darwin ' )]
436- #[BuildFor('Linux ' )]
437- public function build (TargetPackage $ package , PackageInstaller $ installer , ToolchainInterface $ toolchain ): void
458+ #[Stage('unix-build-shared-ext ' )]
459+ public function unixBuildSharedExt (PackageInstaller $ installer , ToolchainInterface $ toolchain ): void
438460 {
439- // virtual target, do nothing
440- if ($ package ->getName () !== 'php ' ) {
441- return ;
442- }
443-
444- $ package ->runStage ('unix-buildconf ' );
445- $ package ->runStage ('unix-configure ' );
446- $ package ->runStage ('unix-make ' );
447-
448461 // collect shared extensions
449462 /** @var PhpExtensionPackage[] $shared_extensions */
450463 $ shared_extensions = array_filter (
@@ -470,9 +483,10 @@ public function build(TargetPackage $package, PackageInstaller $installer, Toolc
470483 }
471484
472485 try {
486+ logger ()->debug ('Building shared extensions... ' );
473487 foreach ($ shared_extensions as $ extension ) {
474- logger ()-> info ( 'Building shared extensions... ' );
475- $ extension ->buildSharedExtension ();
488+ InteractiveTerm:: setMessage ( 'Building shared PHP extension: ' . ConsoleColor:: yellow ( $ extension -> getName ()) );
489+ $ extension ->buildShared ();
476490 }
477491 } finally {
478492 // restore php-config
@@ -483,6 +497,22 @@ public function build(TargetPackage $package, PackageInstaller $installer, Toolc
483497 }
484498 }
485499
500+ #[BuildFor('Darwin ' )]
501+ #[BuildFor('Linux ' )]
502+ public function build (TargetPackage $ package ): void
503+ {
504+ // virtual target, do nothing
505+ if ($ package ->getName () !== 'php ' ) {
506+ return ;
507+ }
508+
509+ $ package ->runStage ('unix-buildconf ' );
510+ $ package ->runStage ('unix-configure ' );
511+ $ package ->runStage ('unix-make ' );
512+
513+ $ package ->runStage ('unix-build-shared-ext ' );
514+ }
515+
486516 /**
487517 * Patch phpize and php-config if needed
488518 */
0 commit comments