Add libevent and postinstall action adder for library package

This commit is contained in:
crazywhalecc 2026-02-06 10:55:59 +08:00
parent d999bfcd11
commit 880bb8799b
No known key found for this signature in database
GPG Key ID: 1F4BDD59391F2680
3 changed files with 164 additions and 6 deletions

View File

@ -0,0 +1,18 @@
libevent:
type: library
artifact:
source:
type: ghrel
repo: libevent/libevent
match: libevent.+\.tar\.gz
prefer-stable: true
metadata:
license-files: [LICENSE]
license: BSD-3-Clause
depends@unix:
- openssl
static-libs@unix:
- libevent.a
- libevent_core.a
- libevent_extra.a
- libevent_openssl.a

View File

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace Package\Library;
use StaticPHP\Attribute\Package\BeforeStage;
use StaticPHP\Attribute\Package\BuildFor;
use StaticPHP\Attribute\Package\Library;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Runtime\Executor\UnixCMakeExecutor;
use StaticPHP\Util\FileSystem;
#[Library('libevent')]
class libevent
{
#[BeforeStage('libevent', 'packPrebuilt')]
public function beforePack(LibraryPackage $lib): void
{
$cmake_file = 'lib/cmake/libevent/LibeventTargets-static.cmake';
if (file_exists(BUILD_ROOT_PATH . '/' . $cmake_file)) {
// get pack placeholder defines
$placeholder = get_pack_replace();
// replace actual paths with placeholders
FileSystem::replaceFileRegex(
BUILD_ROOT_PATH . '/' . $cmake_file,
'/set\(_IMPORT_PREFIX .*\)/m',
'set(_IMPORT_PREFIX "' . $placeholder[BUILD_ROOT_PATH] . '")'
);
FileSystem::replaceFileRegex(
BUILD_ROOT_PATH . '/' . $cmake_file,
'/INTERFACE_INCLUDE_DIRECTORIES ".*"/m',
'INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"'
);
FileSystem::replaceFileRegex(
BUILD_ROOT_PATH . '/' . $cmake_file,
'/INTERFACE_LINK_LIBRARIES "libevent::core;.*"/m',
'INTERFACE_LINK_LIBRARIES "libevent::core;${_IMPORT_PREFIX}/lib/libssl.a;${_IMPORT_PREFIX}/lib/libcrypto.a"'
);
// add this file to postinstall for path replacement
$lib->addPostinstallAction([
'action' => 'replace-path',
'files' => [$cmake_file],
]);
}
}
#[BuildFor('Darwin')]
#[BuildFor('Linux')]
public function buildUnix(LibraryPackage $lib): void
{
$cmake = UnixCMakeExecutor::create($lib)
->addConfigureArgs(
'-DEVENT__LIBRARY_TYPE=STATIC',
'-DEVENT__DISABLE_BENCHMARK=ON',
'-DEVENT__DISABLE_THREAD_SUPPORT=ON',
'-DEVENT__DISABLE_TESTS=ON',
'-DEVENT__DISABLE_SAMPLES=ON',
'-DEVENT__DISABLE_MBEDTLS=ON ',
);
if (version_compare(get_cmake_version(), '4.0.0', '>=')) {
$cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.10');
}
$cmake->build();
$lib->patchPkgconfPrefix(['libevent.pc', 'libevent_core.pc', 'libevent_extra.pc', 'libevent_openssl.pc']);
$lib->patchPkgconfPrefix(
['libevent_openssl.pc'],
PKGCONF_PATCH_CUSTOM,
[
'/Libs.private:.*/m',
'Libs.private: -lssl -lcrypto',
]
);
}
}

View File

@ -21,6 +21,12 @@ use StaticPHP\Util\SPCConfigUtil;
*/
class LibraryPackage extends Package
{
/**
* Custom postinstall actions for this package.
* @var array<array>
*/
private array $customPostinstallActions = [];
public function isInstalled(): bool
{
foreach (PackageConfig::get($this->getName(), 'static-libs', []) as $lib) {
@ -52,6 +58,24 @@ class LibraryPackage extends Package
return true;
}
/**
* Add a custom postinstall action for this package.
* Available actions:
* - replace-path: Replace placeholders with actual paths
* Example: ['action' => 'replace-path', 'files' => ['lib/cmake/xxx.cmake']]
* - replace-to-env: Replace string with environment variable value
* Example: ['action' => 'replace-to-env', 'file' => 'bin/xxx-config', 'search' => 'XXX', 'replace-env' => 'BUILD_ROOT_PATH']
*
* @param array $action Action array with 'action' key and other required keys
*/
public function addPostinstallAction(array $action): void
{
if (!isset($action['action'])) {
throw new WrongUsageException('Postinstall action must have "action" key.');
}
$this->customPostinstallActions[] = $action;
}
public function patchLaDependencyPrefix(?array $files = null): void
{
logger()->info("Patching library {$this->name} la files");
@ -234,14 +258,49 @@ class LibraryPackage extends Package
}
}
// generate postinstall action file if there are files to process
// collect all postinstall actions
$postinstall_actions = [];
// add default replace-path action if there are .pc/.la files
if ($postinstall_files !== []) {
$postinstall_actions = [
[
'action' => 'replace-path',
'files' => $postinstall_files,
],
$postinstall_actions[] = [
'action' => 'replace-path',
'files' => $postinstall_files,
];
}
// merge custom postinstall actions and handle files for replace-path actions
foreach ($this->customPostinstallActions as $action) {
// if action is replace-path, process the files with placeholder replacement
if ($action['action'] === 'replace-path') {
$files = $action['files'] ?? [];
if (!is_array($files)) {
$files = [$files];
}
foreach ($files as $file) {
if (file_exists(BUILD_ROOT_PATH . '/' . $file)) {
$content = FileSystem::readFile(BUILD_ROOT_PATH . '/' . $file);
$origin_files[$file] = $content;
// replace actual paths with placeholders
$content = str_replace(
array_keys($placeholder),
array_values($placeholder),
$content
);
FileSystem::writeFile(BUILD_ROOT_PATH . '/' . $file, $content);
// ensure this file is included in the package
if (!in_array($file, $increase_files, true)) {
$increase_files[] = $file;
}
}
}
}
// add custom action to postinstall actions
$postinstall_actions[] = $action;
}
// generate postinstall action file if there are actions to process
if ($postinstall_actions !== []) {
FileSystem::writeFile($postinstall_file, json_encode($postinstall_actions, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
$increase_files[] = '.package.' . $this->getName() . '.postinstall.json';
}