Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prefer-stable option, dev:lib-ver and dev:ext-ver commands #491

Merged
merged 7 commits into from
Jun 30, 2024
5 changes: 5 additions & 0 deletions config/pre-built.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"repo": "static-php/static-php-cli-hosted",
"match-pattern": "{name}-{arch}-{os}.tgz",
"pack-config": {}
}
16 changes: 16 additions & 0 deletions config/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"type": "ghrel",
"repo": "curl/curl",
"match": "curl.+\\.tar\\.xz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "COPYING"
Expand Down Expand Up @@ -194,6 +195,7 @@
"type": "ghrel",
"repo": "unicode-org/icu",
"match": "icu4c.+-src\\.tgz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down Expand Up @@ -266,6 +268,7 @@
"type": "ghrel",
"repo": "c-ares/c-ares",
"match": "c-ares-.+\\.tar\\.gz",
"prefer-stable": true,
"alt": {
"type": "filelist",
"url": "https://c-ares.org/download/",
Expand All @@ -280,6 +283,7 @@
"type": "ghrel",
"repo": "libevent/libevent",
"match": "libevent.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand All @@ -289,6 +293,7 @@
"type": "ghrel",
"repo": "libffi/libffi",
"match": "libffi.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down Expand Up @@ -333,6 +338,7 @@
"type": "ghrel",
"repo": "lz4/lz4",
"match": "lz4-.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down Expand Up @@ -369,6 +375,7 @@
"type": "ghrel",
"repo": "jedisct1/libsodium",
"match": "libsodium-\\d+(\\.\\d+)*\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand All @@ -378,6 +385,7 @@
"type": "ghrel",
"repo": "libssh2/libssh2",
"match": "libssh2.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "COPYING"
Expand Down Expand Up @@ -444,6 +452,7 @@
"type": "ghrel",
"repo": "yaml/libyaml",
"match": "yaml-.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "License"
Expand All @@ -453,6 +462,7 @@
"type": "ghrel",
"repo": "nih-at/libzip",
"match": "libzip.+\\.tar\\.xz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down Expand Up @@ -483,6 +493,7 @@
"repo": "mongodb/mongo-php-driver",
"path": "php-src/ext/mongodb",
"match": "mongodb.+\\.tgz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand All @@ -501,6 +512,7 @@
"type": "ghrel",
"repo": "nghttp2/nghttp2",
"match": "nghttp2.+\\.tar\\.xz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "COPYING"
Expand All @@ -510,6 +522,7 @@
"type": "ghrel",
"repo": "kkos/oniguruma",
"match": "onig-.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "COPYING"
Expand Down Expand Up @@ -649,6 +662,7 @@
"type": "ghtar",
"path": "php-src/ext/swoole",
"repo": "swoole/swoole-src",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down Expand Up @@ -734,6 +748,7 @@
"type": "ghrel",
"repo": "madler/zlib",
"match": "zlib.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "text",
"text": "(C) 1995-2022 Jean-loup Gailly and Mark Adler\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n claim that you wrote the original software. If you use this software\n in a product, an acknowledgment in the product documentation would be\n appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution.\n\nJean-loup Gailly Mark Adler\[email protected] [email protected]"
Expand All @@ -743,6 +758,7 @@
"type": "ghrel",
"repo": "facebook/zstd",
"match": "zstd.+\\.tar\\.gz",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down
4 changes: 4 additions & 0 deletions src/SPC/ConsoleApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
use SPC\command\BuildLibsCommand;
use SPC\command\DeleteDownloadCommand;
use SPC\command\dev\AllExtCommand;
use SPC\command\dev\ExtVerCommand;
use SPC\command\dev\GenerateExtDocCommand;
use SPC\command\dev\LibVerCommand;
use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand;
Expand Down Expand Up @@ -48,6 +50,8 @@ public function __construct()
// Dev commands
new AllExtCommand(),
new PhpVerCommand(),
new LibVerCommand(),
new ExtVerCommand(),
new SortConfigCommand(),
new GenerateExtDocCommand(),
]
Expand Down
6 changes: 5 additions & 1 deletion src/SPC/builder/BuilderBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public function setLibsOnly(bool $status = true): void
* @throws WrongUsageException
* @internal
*/
public function proveExts(array $extensions): void
public function proveExts(array $extensions, bool $skip_check_deps = false): void
{
CustomExt::loadCustomExt();
$this->emitPatchPoint('before-php-extract');
Expand All @@ -181,6 +181,10 @@ public function proveExts(array $extensions): void
$this->addExt($ext);
}

if ($skip_check_deps) {
return;
}

foreach ($this->exts as $ext) {
$ext->checkDependency();
}
Expand Down
10 changes: 10 additions & 0 deletions src/SPC/builder/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,16 @@ public function validate(): void
// do nothing, just throw wrong usage exception if not valid
}

/**
* Get current extension version
*
* @return null|string Version string or null
*/
public function getExtVersion(): ?string
{
return null;
}

/**
* @throws RuntimeException
*/
Expand Down
10 changes: 10 additions & 0 deletions src/SPC/builder/LibraryBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ public function validate(): void
// do nothing, just throw wrong usage exception if not valid
}

/**
* Get current lib version
*
* @return null|string Version string or null
*/
public function getLibVersion(): ?string
{
return null;
}

/**
* Get current builder object.
*/
Expand Down
12 changes: 12 additions & 0 deletions src/SPC/builder/extension/swoole.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@
#[CustomExt('swoole')]
class swoole extends Extension
{
public function getExtVersion(): ?string
{
// Get version from source directory
$file = SOURCE_PATH . '/php-src/ext/swoole/include/swoole_version.h';
// Match #define SWOOLE_VERSION "5.1.3"
$pattern = '/#define SWOOLE_VERSION "(.+)"/';
if (preg_match($pattern, file_get_contents($file), $matches)) {
return $matches[1];
}
return null;
}

public function getUnixConfigureArg(): string
{
// enable swoole
Expand Down
2 changes: 1 addition & 1 deletion src/SPC/builder/macos/MacOSBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __construct(array $options = [])
$this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS');
$this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS');
// cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags);
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch', php_uname('m')), $this->arch_c_flags);

// create pkgconfig and include dir (some libs cannot create them automatically)
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
Expand Down
2 changes: 1 addition & 1 deletion src/SPC/builder/macos/SystemUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class SystemUtil
*/
public static function getCpuCount(): int
{
[$ret, $output] = shell()->execWithResult('sysctl -n hw.ncpu');
[$ret, $output] = shell()->execWithResult('sysctl -n hw.ncpu', false);
if ($ret !== 0) {
throw new RuntimeException('Failed to get cpu count');
}
Expand Down
54 changes: 15 additions & 39 deletions src/SPC/builder/unix/library/libyaml.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,27 @@

trait libyaml
{
public function getLibVersion(): ?string
{
// Match version from CMakeLists.txt:
// Format: set (YAML_VERSION_MAJOR 0)
// set (YAML_VERSION_MINOR 2)
// set (YAML_VERSION_PATCH 5)
$content = FileSystem::readFile($this->source_dir . '/CMakeLists.txt');
if (preg_match('/set \(YAML_VERSION_MAJOR (\d+)\)/', $content, $major)
&& preg_match('/set \(YAML_VERSION_MINOR (\d+)\)/', $content, $minor)
&& preg_match('/set \(YAML_VERSION_PATCH (\d+)\)/', $content, $patch)) {
return "{$major[1]}.{$minor[1]}.{$patch[1]}";
}
return null;
}

/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
// prepare cmake/config.h.in
if (!is_file(SOURCE_PATH . '/libyaml/cmake/config.h.in')) {
f_mkdir(SOURCE_PATH . '/libyaml/cmake');
file_put_contents(
SOURCE_PATH . '/libyaml/cmake/config.h.in',
<<<'EOF'
#define YAML_VERSION_MAJOR @YAML_VERSION_MAJOR@
#define YAML_VERSION_MINOR @YAML_VERSION_MINOR@
#define YAML_VERSION_PATCH @YAML_VERSION_PATCH@
#define YAML_VERSION_STRING "@YAML_VERSION_STRING@"
EOF
);
}

// prepare yamlConfig.cmake.in
if (!is_file(SOURCE_PATH . '/libyaml/yamlConfig.cmake.in')) {
file_put_contents(
SOURCE_PATH . '/libyaml/yamlConfig.cmake.in',
<<<'EOF'
# Config file for the yaml library.
#
# It defines the following variables:
# yaml_LIBRARIES - libraries to link against

@PACKAGE_INIT@

set_and_check(yaml_TARGETS "@PACKAGE_CONFIG_DIR_CONFIG@/yamlTargets.cmake")

if(NOT yaml_TARGETS_IMPORTED)
set(yaml_TARGETS_IMPORTED 1)
include(${yaml_TARGETS})
endif()

set(yaml_LIBRARIES yaml)

EOF
);
}

[$lib, $include, $destdir] = SEPARATED_PATH;

FileSystem::resetDir($this->source_dir . '/build');
Expand Down
12 changes: 8 additions & 4 deletions src/SPC/command/DownloadCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function configure(): void
$this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"');
$this->addOption('for-libs', 'l', InputOption::VALUE_REQUIRED, 'Fetch by libraries, e.g "libcares,openssl,onig"');
$this->addOption('without-suggestions', null, null, 'Do not fetch suggested sources when using --for-extensions');
$this->addOption('ignore-cache-sources', null, InputOption::VALUE_REQUIRED, 'Ignore some source caches, comma separated, e.g "php-src,curl,openssl"', '');
$this->addOption('ignore-cache-sources', null, InputOption::VALUE_OPTIONAL, 'Ignore some source caches, comma separated, e.g "php-src,curl,openssl"', '');
$this->addOption('retry', 'R', InputOption::VALUE_REQUIRED, 'Set retry time when downloading failed (default: 0)', '0');
}

Expand Down Expand Up @@ -147,8 +147,12 @@ public function handle(): int
}

$chosen_sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
$force_list = array_map('trim', array_filter(explode(',', $this->getOption('ignore-cache-sources'))));

$force_all = empty($this->getOption('ignore-cache-sources'));
if (!$force_all) {
$force_list = array_map('trim', array_filter(explode(',', $this->getOption('ignore-cache-sources'))));
} else {
$force_list = [];
}
if ($this->getOption('all')) {
logger()->notice('Downloading with --all option will take more times to download, we recommend you to download with --for-extensions option !');
}
Expand Down Expand Up @@ -182,7 +186,7 @@ public function handle(): int
Downloader::downloadSource($source, $new_config, true);
} else {
logger()->info("Fetching source {$source} [{$ni}/{$cnt}]");
Downloader::downloadSource($source, Config::getSource($source), in_array($source, $force_list));
Downloader::downloadSource($source, Config::getSource($source), $force_all || in_array($source, $force_list));
}
}
$time = round(microtime(true) - START_TIME, 3);
Expand Down
51 changes: 51 additions & 0 deletions src/SPC/command/dev/ExtVerCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace SPC\command\dev;

use SPC\builder\BuilderProvider;
use SPC\command\BaseCommand;
use SPC\store\Config;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand('dev:ext-version', 'Returns version of extension from source directory', ['dev:ext-ver'])]
class ExtVerCommand extends BaseCommand
{
public function configure()
{
$this->addArgument('extension', InputArgument::REQUIRED, 'The library name');
}

public function initialize(InputInterface $input, OutputInterface $output): void
{
$this->no_motd = true;
parent::initialize($input, $output);
}

public function handle(): int
{
// Get lib object
$builder = BuilderProvider::makeBuilderByInput($this->input);

$ext_conf = Config::getExt($this->getArgument('extension'));
$builder->proveExts([$this->getArgument('extension')], true);

// Check whether lib is extracted
// if (!is_dir(SOURCE_PATH . '/' . $this->getArgument('library'))) {
// $this->output->writeln("<error>Library {$this->getArgument('library')} is not extracted</error>");
// return static::FAILURE;
// }

$version = $builder->getExt($this->getArgument('extension'))->getExtVersion();
if ($version === null) {
$this->output->writeln("<error>Failed to get version of extension {$this->getArgument('extension')}</error>");
return static::FAILURE;
}
$this->output->writeln("<info>{$version}</info>");
return static::SUCCESS;
}
}
Loading