mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Add openssl lib support
This commit is contained in:
parent
a709221223
commit
ccd948e58a
@ -41,6 +41,21 @@ fastlz:
|
||||
license-files: ['LICENSE.MIT']
|
||||
license: MIT
|
||||
|
||||
openssl:
|
||||
source:
|
||||
type: ghrel
|
||||
repo: openssl/openssl
|
||||
match: 'openssl.+\.tar\.gz'
|
||||
prefer-stable: true
|
||||
source-mirror:
|
||||
type: filelist
|
||||
url: 'https://www.openssl.org/source/'
|
||||
regex: '/href="(?<file>openssl-(?<version>[^"]+)\.tar\.gz)"/'
|
||||
binary: hosted
|
||||
metadata:
|
||||
license-files: ['LICENSE.txt']
|
||||
license: OpenSSL
|
||||
|
||||
zlib:
|
||||
source:
|
||||
type: ghrel
|
||||
|
||||
@ -28,6 +28,16 @@ fastlz:
|
||||
- fastlz.h
|
||||
artifact: fastlz
|
||||
|
||||
openssl:
|
||||
type: library
|
||||
static-libs@unix:
|
||||
- libssl.a
|
||||
- libcrypto.a
|
||||
headers: ['openssl']
|
||||
depends:
|
||||
- zlib
|
||||
artifact: openssl
|
||||
|
||||
zlib:
|
||||
type: library
|
||||
static-libs@unix:
|
||||
|
||||
35
src/Package/Artifact/openssl.php
Normal file
35
src/Package/Artifact/openssl.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Package\Artifact;
|
||||
|
||||
use StaticPHP\Attribute\Artifact\AfterSourceExtract;
|
||||
use StaticPHP\Attribute\PatchDescription;
|
||||
use StaticPHP\Util\FileSystem;
|
||||
|
||||
/**
|
||||
* openssl artifact patches.
|
||||
*/
|
||||
class openssl
|
||||
{
|
||||
/**
|
||||
* Patch OpenSSL 1.1 for Darwin (missing string.h include).
|
||||
*/
|
||||
#[AfterSourceExtract('openssl')]
|
||||
#[PatchDescription('Patch OpenSSL 1.1 for Darwin (missing string.h include)')]
|
||||
public function patchOpenssl11Darwin(string $target_path): void
|
||||
{
|
||||
spc_skip_if(PHP_OS_FAMILY !== 'Darwin', 'This patch is only for Darwin systems.');
|
||||
|
||||
spc_skip_if(file_exists("{$target_path}/openssl/VERSION.dat"), 'This patch is only for OpenSSL 1.1.x versions.');
|
||||
|
||||
spc_skip_if(!file_exists("{$target_path}/openssl/test/v3ext.c"), 'v3ext.c not found, skipping patch.');
|
||||
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/openssl/test/v3ext.c',
|
||||
'#include <stdio.h>',
|
||||
'#include <stdio.h>' . PHP_EOL . '#include <string.h>'
|
||||
);
|
||||
}
|
||||
}
|
||||
89
src/Package/Library/openssl.php
Normal file
89
src/Package/Library/openssl.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Package\Library;
|
||||
|
||||
use StaticPHP\Attribute\Package\BuildFor;
|
||||
use StaticPHP\Attribute\Package\Library;
|
||||
use StaticPHP\Package\LibraryPackage;
|
||||
use StaticPHP\Util\FileSystem;
|
||||
|
||||
#[Library('openssl')]
|
||||
class openssl
|
||||
{
|
||||
#[BuildFor('Darwin')]
|
||||
public function buildForDarwin(LibraryPackage $pkg): void
|
||||
{
|
||||
$zlib_libs = $pkg->getInstaller()->getLibraryPackage('zlib')->getStaticLibFiles();
|
||||
$arch = getenv('SPC_ARCH');
|
||||
|
||||
shell()->cd($pkg->getSourceDir())->initializeEnv($pkg)
|
||||
->exec(
|
||||
'./Configure no-shared zlib ' .
|
||||
"--prefix={$pkg->getBuildRootPath()} " .
|
||||
'--libdir=lib ' .
|
||||
'--openssldir=/etc/ssl ' .
|
||||
"darwin64-{$arch}-cc"
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec("make -j{$pkg->getBuilder()->concurrency} CNF_EX_LIBS=\"{$zlib_libs}\"")
|
||||
->exec('make install_sw');
|
||||
$this->patchPkgConfig($pkg);
|
||||
}
|
||||
|
||||
#[BuildFor('Linux')]
|
||||
public function build(LibraryPackage $lib): void
|
||||
{
|
||||
$arch = getenv('SPC_ARCH');
|
||||
|
||||
$env = "CC='" . getenv('CC') . ' -idirafter ' . BUILD_INCLUDE_PATH .
|
||||
' -idirafter /usr/include/ ' .
|
||||
' -idirafter /usr/include/' . getenv('SPC_ARCH') . '-linux-gnu/ ' .
|
||||
"' ";
|
||||
|
||||
$ex_lib = trim($lib->getInstaller()->getLibraryPackage('zlib')->getStaticLibFiles()) . ' -ldl -pthread';
|
||||
$zlib_extra =
|
||||
'--with-zlib-include=' . BUILD_INCLUDE_PATH . ' ' .
|
||||
'--with-zlib-lib=' . BUILD_LIB_PATH . ' ';
|
||||
|
||||
$openssl_dir = getenv('OPENSSLDIR') ?: null;
|
||||
// TODO: in v3 use the following: $openssl_dir ??= SystemUtil::getOSRelease()['dist'] === 'redhat' ? '/etc/pki/tls' : '/etc/ssl';
|
||||
$openssl_dir ??= '/etc/ssl';
|
||||
$ex_lib = trim($ex_lib);
|
||||
|
||||
shell()->cd($lib->getSourceDir())->initializeEnv($lib)
|
||||
->exec(
|
||||
"{$env} ./Configure no-shared zlib " .
|
||||
"--prefix={$lib->getBuildRootPath()} " .
|
||||
"--libdir={$lib->getLibDir()} " .
|
||||
"--openssldir={$openssl_dir} " .
|
||||
"{$zlib_extra}" .
|
||||
'enable-pie ' .
|
||||
'no-legacy ' .
|
||||
'no-tests ' .
|
||||
"linux-{$arch}"
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec("make -j{$lib->getBuilder()->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||
->exec('make install_sw');
|
||||
$this->patchPkgConfig($lib);
|
||||
}
|
||||
|
||||
private function patchPkgConfig(LibraryPackage $pkg): void
|
||||
{
|
||||
$pkg->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
|
||||
// patch for openssl 3.3.0+
|
||||
if (!str_contains($file = FileSystem::readFile("{$pkg->getLibDir()}/pkgconfig/libssl.pc"), 'prefix=')) {
|
||||
FileSystem::writeFile("{$pkg->getLibDir()}/pkgconfig/libssl.pc", "prefix={$pkg->getBuildRootPath()}\n{$file}");
|
||||
}
|
||||
if (!str_contains($file = FileSystem::readFile("{$pkg->getLibDir()}/pkgconfig/openssl.pc"), 'prefix=')) {
|
||||
FileSystem::writeFile("{$pkg->getLibDir()}/pkgconfig/openssl.pc", "prefix={$pkg->getBuildRootPath()}\n{$file}");
|
||||
}
|
||||
if (!str_contains($file = FileSystem::readFile("{$pkg->getLibDir()}/pkgconfig/libcrypto.pc"), 'prefix=')) {
|
||||
FileSystem::writeFile("{$pkg->getLibDir()}/pkgconfig/libcrypto.pc", "prefix={$pkg->getBuildRootPath()}\n{$file}");
|
||||
}
|
||||
FileSystem::replaceFileRegex("{$pkg->getLibDir()}/pkgconfig/libcrypto.pc", '/Libs.private:.*/m', 'Requires.private: zlib');
|
||||
FileSystem::replaceFileRegex("{$pkg->getLibDir()}/cmake/OpenSSL/OpenSSLConfig.cmake", '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")');
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ namespace StaticPHP\Package;
|
||||
use StaticPHP\Config\PackageConfig;
|
||||
use StaticPHP\Exception\PatchException;
|
||||
use StaticPHP\Util\FileSystem;
|
||||
use StaticPHP\Util\SPCConfigUtil;
|
||||
|
||||
/**
|
||||
* Represents a library package with platform-specific build functions.
|
||||
@ -159,6 +160,16 @@ class LibraryPackage extends Package
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get static library files for current package and its dependencies.
|
||||
*/
|
||||
public function getStaticLibFiles(): string
|
||||
{
|
||||
$config = new SPCConfigUtil(['libs_only_deps' => true, 'absolute_libs' => true]);
|
||||
$res = $config->config([$this->getName()]);
|
||||
return $res['libs'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extra LIBS for current package.
|
||||
* You need to define the environment variable in the format of {LIBRARY_NAME}_LIBS
|
||||
|
||||
@ -135,6 +135,22 @@ abstract class Package
|
||||
return isset($this->build_functions[PHP_OS_FAMILY]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PackageBuilder instance for this package.
|
||||
*/
|
||||
public function getBuilder(): PackageBuilder
|
||||
{
|
||||
return ApplicationContext::get(PackageBuilder::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PackageInstaller instance for this package.
|
||||
*/
|
||||
public function getInstaller(): PackageInstaller
|
||||
{
|
||||
return ApplicationContext::get(PackageInstaller::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the package.
|
||||
*/
|
||||
|
||||
@ -402,11 +402,64 @@ class PackageInstaller
|
||||
return SPC_STATUS_INSTALLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal internally calling only, for users, please use specific getter, such as 'getLibraryPackage', 'getTaretPackage', etc
|
||||
* @param string $package_name Package name
|
||||
*/
|
||||
public function getPackage(string $package_name): ?Package
|
||||
{
|
||||
return $this->packages[$package_name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a library package by name.
|
||||
*
|
||||
* @param string $package_name Package name
|
||||
* @return null|LibraryPackage The library package instance or null if not found
|
||||
*/
|
||||
public function getLibraryPackage(string $package_name): ?LibraryPackage
|
||||
{
|
||||
$pkg = $this->getPackage($package_name);
|
||||
if ($pkg instanceof LibraryPackage) {
|
||||
return $pkg;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a target package by name.
|
||||
*
|
||||
* @param string $package_name Package name
|
||||
* @return null|TargetPackage The target package instance or null if not found
|
||||
*/
|
||||
public function getTargetPackage(string $package_name): ?TargetPackage
|
||||
{
|
||||
$pkg = $this->getPackage($package_name);
|
||||
if ($pkg instanceof TargetPackage) {
|
||||
return $pkg;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a PHP extension by name.
|
||||
*
|
||||
* @param string $package_or_ext_name Extension name
|
||||
* @return null|PhpExtensionPackage The target package instance or null if not found
|
||||
*/
|
||||
public function getPhpExtensionPackage(string $package_or_ext_name): ?PhpExtensionPackage
|
||||
{
|
||||
$pkg = $this->getPackage($package_or_ext_name);
|
||||
if ($pkg instanceof PhpExtensionPackage) {
|
||||
return $pkg;
|
||||
}
|
||||
$pkg = $this->getPackage("ext-{$package_or_ext_name}");
|
||||
if ($pkg instanceof PhpExtensionPackage) {
|
||||
return $pkg;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a package has required artifacts.
|
||||
*/
|
||||
|
||||
@ -209,18 +209,21 @@ class SPCConfigUtil
|
||||
$frameworks = [];
|
||||
|
||||
foreach ($packages as $package) {
|
||||
// add pkg-configs libs
|
||||
$pkg_configs = PackageConfig::get($package, 'pkg-configs', []);
|
||||
foreach ($pkg_configs as $pkg_config) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$pkg_config}.pc")) {
|
||||
throw new WrongUsageException("pkg-config file '{$pkg_config}.pc' for lib [{$package}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first.");
|
||||
// parse pkg-configs only for unix systems
|
||||
if (SystemTarget::isUnix()) {
|
||||
// add pkg-configs libs
|
||||
$pkg_configs = PackageConfig::get($package, 'pkg-configs', []);
|
||||
foreach ($pkg_configs as $pkg_config) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$pkg_config}.pc")) {
|
||||
throw new WrongUsageException("pkg-config file '{$pkg_config}.pc' for lib [{$package}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first.");
|
||||
}
|
||||
}
|
||||
$pkg_configs = implode(' ', $pkg_configs);
|
||||
if ($pkg_configs !== '') {
|
||||
// static libs with dependencies come in reverse order, so reverse this too
|
||||
$pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs));
|
||||
$lib_names = [...$lib_names, ...$pc_libs];
|
||||
}
|
||||
}
|
||||
$pkg_configs = implode(' ', $pkg_configs);
|
||||
if ($pkg_configs !== '') {
|
||||
// static libs with dependencies come in reverse order, so reverse this too
|
||||
$pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs));
|
||||
$lib_names = [...$lib_names, ...$pc_libs];
|
||||
}
|
||||
// convert all static-libs to short names
|
||||
$libs = array_reverse(PackageConfig::get($package, 'static-libs', []));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user