Separate env to env.ini file

This commit is contained in:
crazywhalecc
2024-10-01 15:37:37 +08:00
committed by Jerry Ma
parent 2f320507ae
commit 4e88dba630
9 changed files with 267 additions and 179 deletions

View File

@@ -30,12 +30,15 @@ use Symfony\Component\Console\Application;
*/
final class ConsoleApplication extends Application
{
public const VERSION = '2.3.4';
public const VERSION = '2.3.5';
public function __construct()
{
parent::__construct('static-php-cli', self::VERSION);
// Define internal env vars and constants
require_once ROOT_DIR . '/src/globals/internal-env.php';
$this->addCommands(
[
// Common commands

View File

@@ -10,6 +10,7 @@ use Psr\Log\LogLevel;
use SPC\ConsoleApplication;
use SPC\exception\ExceptionHandler;
use SPC\exception\WrongUsageException;
use SPC\util\GlobalEnvManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
@@ -94,6 +95,11 @@ abstract class BaseCommand extends Command
$question = new ConfirmationQuestion($prompt->label . $case, $prompt->default);
return $helper->ask($input, $output, $question);
});
// init GlobalEnv
if (!$this instanceof BuildCommand) {
GlobalEnvManager::init();
}
if ($this->shouldExecute()) {
try {
// show raw argv list for logger()->debug

View File

@@ -23,6 +23,8 @@ class DoctorCommand extends BaseCommand
{
try {
$checker = new CheckListHandler();
// skipped items
$skip_items = array_filter(explode(',', getenv('SPC_SKIP_DOCTOR_CHECK_ITEMS') ?: ''));
$fix_policy = $this->input->getOption('auto-fix') ? FIX_POLICY_AUTOFIX : FIX_POLICY_PROMPT;
foreach ($checker->runChecks() as $check) {
@@ -32,13 +34,12 @@ class DoctorCommand extends BaseCommand
$this->output->write('Checking <comment>' . $check->item_name . '</comment> ... ');
$result = call_user_func($check->callback);
if ($result === null) {
// check if this item is skipped
if (in_array($check->item_name, $skip_items) || ($result = call_user_func($check->callback)) === null) {
$this->output->writeln('skipped');
} elseif ($result instanceof CheckResult) {
if ($result->isOK()) {
$this->output->writeln($result->getMessage() ?? 'ok');
continue;
}

View File

@@ -5,11 +5,9 @@ declare(strict_types=1);
namespace SPC\util;
use SPC\builder\BuilderBase;
use SPC\builder\freebsd\SystemUtil as BSDSystemUtil;
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
use SPC\builder\windows\SystemUtil as WindowsSystemUtil;
use SPC\builder\linux\SystemUtil;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
/**
* Environment variable manager
@@ -29,168 +27,78 @@ class GlobalEnvManager
* @param BuilderBase $builder Builder
* @throws RuntimeException
*/
public static function init(BuilderBase $builder): void
public static function init(?BuilderBase $builder = null): void
{
// Init global env, build related path
self::putenv('BUILD_ROOT_PATH=' . BUILD_ROOT_PATH);
self::putenv('BUILD_INCLUDE_PATH=' . BUILD_INCLUDE_PATH);
self::putenv('BUILD_LIB_PATH=' . BUILD_LIB_PATH);
self::putenv('BUILD_BIN_PATH=' . BUILD_BIN_PATH);
self::putenv('PKG_ROOT_PATH=' . PKG_ROOT_PATH);
self::putenv('SOURCE_PATH=' . SOURCE_PATH);
self::putenv('DOWNLOAD_PATH=' . DOWNLOAD_PATH);
// Check pre-defined env vars exists
if (getenv('BUILD_ROOT_PATH') === false) {
throw new RuntimeException('You must include src/globals/internal-env.php before using GlobalEnvManager');
}
// Init SPC env
self::initIfNotExists('SPC_CONCURRENCY', match (PHP_OS_FAMILY) {
'Windows' => (string) WindowsSystemUtil::getCpuCount(),
'Darwin' => (string) MacOSSystemUtil::getCpuCount(),
'Linux' => (string) LinuxSystemUtil::getCpuCount(),
'BSD' => (string) BSDSystemUtil::getCpuCount(),
default => '1',
});
// Init system-specific env
match (PHP_OS_FAMILY) {
'Windows' => self::initWindowsEnv(),
'Darwin' => self::initDarwinEnv($builder),
'Linux' => self::initLinuxEnv($builder),
'BSD' => 'TODO',
default => logger()->warning('Unknown OS: ' . PHP_OS_FAMILY),
};
}
private static function initWindowsEnv(): void
{
// Windows need php-sdk binary tools
self::initIfNotExists('PHP_SDK_PATH', WORKING_DIR . DIRECTORY_SEPARATOR . 'php-sdk-binary-tools');
self::initIfNotExists('UPX_EXEC', PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'upx.exe');
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static');
}
private static function initLinuxEnv(BuilderBase $builder): void
{
// Init C Compiler and C++ Compiler (alpine)
if (LinuxSystemUtil::isMuslDist()) {
self::initIfNotExists('CC', 'gcc');
self::initIfNotExists('CXX', 'g++');
self::initIfNotExists('AR', 'ar');
self::initIfNotExists('LD', 'ld.gold');
} else {
$arch = arch2gnu(php_uname('m'));
self::initIfNotExists('CC', "{$arch}-linux-musl-gcc");
self::initIfNotExists('CXX', "{$arch}-linux-musl-g++");
self::initIfNotExists('AR', "{$arch}-linux-musl-ar");
self::initIfNotExists('LD', 'ld.gold');
if (getenv('SPC_NO_MUSL_PATH') !== 'yes') {
self::putenv("PATH=/usr/local/musl/bin:/usr/local/musl/{$arch}-linux-musl/bin:" . getenv('PATH'));
// Define env vars for unix
if (is_unix()) {
self::putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
self::putenv('PKG_CONFIG=' . BUILD_BIN_PATH . '/pkg-config');
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
if ($builder instanceof BuilderBase) {
self::putenv('SPC_PHP_DEFAULT_OPTIMIZE_CFLAGS=' . ($builder->getOption('no-strip') ? '-g -O0' : '-g -Os'));
}
}
// Init arch-specific cflags
self::initIfNotExists('SPC_DEFAULT_C_FLAGS', '');
self::initIfNotExists('SPC_DEFAULT_CXX_FLAGS', '');
self::initIfNotExists('SPC_EXTRA_LIBS', '');
// Define env vars for linux
if (PHP_OS_FAMILY === 'Linux') {
$arch = GNU_ARCH;
if (SystemUtil::isMuslDist()) {
self::putenv('SPC_LINUX_DEFAULT_CC=gcc');
self::putenv('SPC_LINUX_DEFAULT_CXX=g++');
self::putenv('SPC_LINUX_DEFAULT_AR=ar');
} else {
self::putenv("SPC_LINUX_DEFAULT_CC={$arch}-linux-musl-gcc");
self::putenv("SPC_LINUX_DEFAULT_CXX={$arch}-linux-musl-g++");
self::putenv("SPC_LINUX_DEFAULT_AR={$arch}-linux-musl-ar");
}
self::putenv("SPC_PHP_DEFAULT_LD_LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib");
}
// SPC_MICRO_PATCHES for linux
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream');
// Init linux-only env
self::initIfNotExists('UPX_EXEC', PKG_ROOT_PATH . '/bin/upx');
self::initIfNotExists('GNU_ARCH', arch2gnu(php_uname('m')));
// optimization flags with different strip option
$php_extra_cflags_optimize = $builder->getOption('no-strip') ? '-g -O0' : '-g -Os';
// optimization flags with different c compiler
$clang_use_lld = str_ends_with(getenv('CC'), 'clang') && LinuxSystemUtil::findCommand('lld') ? '-Xcompiler -fuse-ld=lld ' : '';
$init_spc_cmd_maps = [
// Init default build command prefix
'SPC_CMD_PREFIX_PHP_BUILDCONF' => './buildconf --force',
'SPC_CMD_PREFIX_PHP_CONFIGURE' => $builder->getOption('ld_library_path') . ' ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg',
'SPC_CMD_PREFIX_PHP_MAKE' => 'make -j' . getenv('SPC_CONCURRENCY'),
// Init default build vars for build command
'SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS' => getenv('SPC_DEFAULT_C_FLAGS'),
'SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
'SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS' => '-L' . BUILD_LIB_PATH,
'SPC_CMD_VAR_PHP_CONFIGURE_LIBS' => '-ldl -lpthread -lm',
'SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS' => $php_extra_cflags_optimize . ' -fno-ident -fPIE',
'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS' => '',
'SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM' => $clang_use_lld . '-all-static',
// Init env.ini file, read order:
// WORKING_DIR/config/env.ini
// ROOT_DIR/config/env.ini
$ini_files = [
WORKING_DIR . '/config/env.ini',
ROOT_DIR . '/config/env.ini',
];
foreach ($init_spc_cmd_maps as $name => $value) {
self::initIfNotExists($name, $value);
$ini = null;
foreach ($ini_files as $ini_file) {
if (file_exists($ini_file)) {
$ini = parse_ini_file($ini_file, true);
break;
}
}
self::initUnixEnv($builder);
}
private static function initDarwinEnv(BuilderBase $builder): void
{
// Init C Compiler and C++ Compiler
self::initIfNotExists('CC', 'clang');
self::initIfNotExists('CXX', 'clang++');
// Init arch-specific cflags
self::initIfNotExists('SPC_DEFAULT_C_FLAGS', match (php_uname('m')) {
'arm64', 'aarch64' => '--target=arm64-apple-darwin',
default => '--target=x86_64-apple-darwin',
});
// Init arch-specific cxxflags
self::initIfNotExists('SPC_DEFAULT_CXX_FLAGS', match (php_uname('m')) {
'arm64', 'aarch64' => '--target=arm64-apple-darwin',
default => '--target=x86_64-apple-darwin',
});
// Init extra libs (will be appended before `before-php-buildconf` event point)
self::initIfNotExists('SPC_EXTRA_LIBS', '');
// SPC_MICRO_PATCHES for macOS
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,macos_iconv');
$init_spc_cmd_maps = [
// Init default build command prefix
'SPC_CMD_PREFIX_PHP_BUILDCONF' => './buildconf --force',
'SPC_CMD_PREFIX_PHP_CONFIGURE' => './configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg',
'SPC_CMD_PREFIX_PHP_MAKE' => 'make -j' . getenv('SPC_CONCURRENCY'),
// Init default build vars for build command
'SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS' => getenv('SPC_DEFAULT_C_FLAGS') . ' -Werror=unknown-warning-option',
'SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
'SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS' => '-L' . BUILD_LIB_PATH,
'SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS' => $builder->getOption('no-strip') ? '-g -O0' : '-g -Os',
'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS' => '-lresolv',
];
foreach ($init_spc_cmd_maps as $name => $value) {
self::initIfNotExists($name, $value);
if ($ini === null) {
throw new WrongUsageException('env.ini not found');
}
self::initUnixEnv($builder);
}
private static function initUnixEnv(BuilderBase $builder): void
{
self::putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
self::putenv('PKG_CONFIG=' . BUILD_BIN_PATH . '/pkg-config');
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
}
/**
* Initialize the environment variable if it does not exist
*
* @param string $name Environment variable name
* @param string $value Environment variable value
*/
private static function initIfNotExists(string $name, string $value): void
{
if (($val = getenv($name)) === false) {
self::putenv($name . '=' . $value);
} else {
logger()->debug("env [{$name}] existing: {$val}");
if ($ini === false || !isset($ini['global'])) {
throw new WrongUsageException('Failed to parse ' . $ini_file);
}
self::applyConfig($ini['global']);
match (PHP_OS_FAMILY) {
'Windows' => self::applyConfig($ini['windows']),
'Darwin' => self::applyConfig($ini['macos']),
'Linux' => self::applyConfig($ini['linux']),
'BSD' => self::applyConfig($ini['freebsd']),
default => null,
};
}
private static function putenv(string $val): void
public static function putenv(string $val): void
{
f_putenv($val);
self::$env_cache[] = $val;
}
private static function applyConfig(array $ini): void
{
foreach ($ini as $k => $v) {
self::putenv($k . '=' . $v);
}
}
}

View File

@@ -2,7 +2,6 @@
declare(strict_types=1);
use SPC\store\FileSystem;
use ZM\Logger\ConsoleLogger;
define('WORKING_DIR', getcwd());
@@ -11,23 +10,6 @@ define('ROOT_DIR', dirname(__DIR__, 2));
// CLI start time
define('START_TIME', microtime(true));
define('BUILD_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_ROOT_PATH')) ? $a : (WORKING_DIR . '/buildroot')));
define('SOURCE_PATH', FileSystem::convertPath(is_string($a = getenv('SOURCE_PATH')) ? $a : (WORKING_DIR . '/source')));
define('DOWNLOAD_PATH', FileSystem::convertPath(is_string($a = getenv('DOWNLOAD_PATH')) ? $a : (WORKING_DIR . '/downloads')));
define('PKG_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('PKG_ROOT_PATH')) ? $a : (WORKING_DIR . '/pkgroot')));
define('BUILD_BIN_PATH', FileSystem::convertPath(is_string($a = getenv('INSTALL_BIN_PATH')) ? $a : (BUILD_ROOT_PATH . '/bin')));
define('BUILD_LIB_PATH', FileSystem::convertPath(is_string($a = getenv('INSTALL_LIB_PATH')) ? $a : (BUILD_ROOT_PATH . '/lib')));
define('BUILD_INCLUDE_PATH', FileSystem::convertPath(is_string($a = getenv('INSTALL_INCLUDE_PATH')) ? $a : (BUILD_ROOT_PATH . '/include')));
define('SEPARATED_PATH', [
'/' . pathinfo(BUILD_LIB_PATH)['basename'], // lib
'/' . pathinfo(BUILD_INCLUDE_PATH)['basename'], // include
BUILD_ROOT_PATH,
]);
if (PHP_OS_FAMILY === 'Windows') {
define('PHP_SDK_PATH', is_string($a = getenv('PHP_SDK_PATH')) ? $a : (WORKING_DIR . DIRECTORY_SEPARATOR . 'php-sdk-binary-tools'));
}
// for windows, prevent calling Invoke-WebRequest and wsl command
const SPC_CURL_EXEC = PHP_OS_FAMILY === 'Windows' ? 'curl.exe' : 'curl';
const SPC_GIT_EXEC = PHP_OS_FAMILY === 'Windows' ? 'git.exe' : 'git';

View File

@@ -31,6 +31,11 @@ function logger(): LoggerInterface
return $ob_logger;
}
function is_unix(): bool
{
return in_array(PHP_OS_FAMILY, ['Linux', 'Darwin', 'BSD']);
}
/**
* Transfer architecture name to gnu triplet
*

View File

@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
use SPC\builder\freebsd\SystemUtil as BSDSystemUtil;
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
use SPC\builder\windows\SystemUtil as WindowsSystemUtil;
use SPC\store\FileSystem;
use SPC\util\GlobalEnvManager;
define('BUILD_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_ROOT_PATH')) ? $a : (WORKING_DIR . '/buildroot')));
define('BUILD_INCLUDE_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_INCLUDE_PATH')) ? $a : (BUILD_ROOT_PATH . '/include')));
define('BUILD_LIB_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_LIB_PATH')) ? $a : (BUILD_ROOT_PATH . '/lib')));
define('BUILD_BIN_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_BIN_PATH')) ? $a : (BUILD_ROOT_PATH . '/bin')));
define('PKG_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('PKG_ROOT_PATH')) ? $a : (WORKING_DIR . '/pkgroot')));
define('SOURCE_PATH', FileSystem::convertPath(is_string($a = getenv('SOURCE_PATH')) ? $a : (WORKING_DIR . '/source')));
define('DOWNLOAD_PATH', FileSystem::convertPath(is_string($a = getenv('DOWNLOAD_PATH')) ? $a : (WORKING_DIR . '/downloads')));
define('CPU_COUNT', match (PHP_OS_FAMILY) {
'Windows' => (string) WindowsSystemUtil::getCpuCount(),
'Darwin' => (string) MacOSSystemUtil::getCpuCount(),
'Linux' => (string) LinuxSystemUtil::getCpuCount(),
'BSD' => (string) BSDSystemUtil::getCpuCount(),
default => 1,
});
define('GNU_ARCH', arch2gnu(php_uname('m')));
define('MAC_ARCH', match ($_im8a = arch2gnu(php_uname('m'))) {
'aarch64' => 'arm64',
default => $_im8a
});
// deprecated variables
define('SEPARATED_PATH', [
'/' . pathinfo(BUILD_LIB_PATH)['basename'], // lib
'/' . pathinfo(BUILD_INCLUDE_PATH)['basename'], // include
BUILD_ROOT_PATH,
]);
// add these to env vars with same name
GlobalEnvManager::putenv('BUILD_ROOT_PATH=' . BUILD_ROOT_PATH);
GlobalEnvManager::putenv('BUILD_INCLUDE_PATH=' . BUILD_INCLUDE_PATH);
GlobalEnvManager::putenv('BUILD_LIB_PATH=' . BUILD_LIB_PATH);
GlobalEnvManager::putenv('BUILD_BIN_PATH=' . BUILD_BIN_PATH);
GlobalEnvManager::putenv('PKG_ROOT_PATH=' . PKG_ROOT_PATH);
GlobalEnvManager::putenv('SOURCE_PATH=' . SOURCE_PATH);
GlobalEnvManager::putenv('DOWNLOAD_PATH=' . DOWNLOAD_PATH);
GlobalEnvManager::putenv('CPU_COUNT=' . CPU_COUNT);
GlobalEnvManager::putenv('GNU_ARCH=' . GNU_ARCH);
GlobalEnvManager::putenv('MAC_ARCH=' . MAC_ARCH);

View File

@@ -13,7 +13,7 @@ declare(strict_types=1);
$test_php_version = ['8.3'];
$test_os = ['macos-13', 'macos-14', 'ubuntu-latest', 'windows-latest'];
$test_os = ['macos-14', 'ubuntu-latest'];
$zts = false;
@@ -23,13 +23,13 @@ $upx = true;
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
$extensions = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'gmssl',
'Windows' => 'gmssl',
'Linux', 'Darwin' => '',
'Windows' => '',
};
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
$with_libs = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'liblz4',
'Linux', 'Darwin' => '',
'Windows' => '',
};
@@ -37,7 +37,7 @@ $with_libs = match (PHP_OS_FAMILY) {
// You can use `common`, `bulk`, `minimal` or `none`.
// note: combination is only available for *nix platform. Windows must use `none` combination
$base_combination = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'none',
'Linux', 'Darwin' => 'common',
'Windows' => 'none',
};