Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/pkg/lib/imagemagick.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ imagemagick:
- xz
- libzip
- libxml2
suggests@unix:
- lcms2
headers@windows:
- imagemagick/MagickWand/MagickWand.h
lang: cpp
Expand Down
16 changes: 16 additions & 0 deletions config/pkg/lib/lcms2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
lcms2:
type: library
artifact:
source:
type: ghtagtar
repo: mm2/Little-CMS
match: lcms2\.\d+(\.\d+)?$
metadata:
license-files: [COPYING]
license: MIT
headers@unix:
- lcms2.h
pkg-configs:
- lcms2
static-libs@unix:
- liblcms2.a
1 change: 1 addition & 0 deletions src/Package/Library/imagemagick.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public function buildUnix(LibraryPackage $lib, ToolchainInterface $toolchain): v
->optionalPackage('zlib', ...ac_with_args('zlib'))
->optionalPackage('xz', ...ac_with_args('lzma'))
->optionalPackage('zstd', ...ac_with_args('zstd'))
->optionalPackage('lcms2', ...ac_with_args('lcms'))
->optionalPackage('freetype', ...ac_with_args('freetype'))
->optionalPackage('bzip2', ...ac_with_args('bzlib'))
->optionalPackage('libjxl', ...ac_with_args('jxl'))
Expand Down
26 changes: 26 additions & 0 deletions src/Package/Library/lcms2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Package\Library;

use StaticPHP\Attribute\Package\BuildFor;
use StaticPHP\Attribute\Package\Library;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Runtime\Executor\UnixAutoconfExecutor;

#[Library('lcms2')]
class lcms2
{
#[BuildFor('Darwin')]
#[BuildFor('Linux')]
public function buildUnix(LibraryPackage $lib): void
{
UnixAutoconfExecutor::create($lib)
->configure()
->make();

$lib->patchPkgconfPrefix(['lcms2.pc']);
$lib->patchLaDependencyPrefix();
}
}
21 changes: 19 additions & 2 deletions tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ public function testForLibsFilterIncludesTransitiveLibraryDeps(): void
}
}

/**
* --for-libs must include extensions that depend on the library through suggested libraries.
*/
public function testForLibsFilterIncludesTransitiveSuggestedLibraryDeps(): void
{
$matrix = $this->runMatrix(['--os' => 'Linux', '--for-libs' => 'lcms2']);

$this->assertNotEmpty($matrix, '--for-libs=lcms2 must yield at least one entry');
foreach ($matrix as $entry) {
$parts = explode(',', $entry['extension']);
$this->assertContains('imagick', $parts, "Entry {$entry['extension']} should not appear in --for-libs=lcms2 results");
}
}

/**
* Multiple filters should include entries matching any changed package.
*/
Expand Down Expand Up @@ -313,11 +327,14 @@ private static function buildFixture(): array
'ext-xml' => $ext(['arg-type' => 'standard'], ['depends' => ['libxml2']]),
'ext-dom' => $ext(['arg-type' => 'standard'], ['depends' => ['ext-xml']]),

// Transitive library chain: imagick -> imagemagick -> libheif -> libde265
// Transitive library chains:
// imagick -> imagemagick -> libheif -> libde265
// imagick -> imagemagick -> (suggests) lcms2
'ext-imagick' => $ext(['arg-type' => 'standard'], ['depends' => ['imagemagick']]),
'imagemagick' => $lib(['depends' => ['libheif']]),
'imagemagick' => $lib(['depends' => ['libheif'], 'suggests' => ['lcms2']]),
'libheif' => $lib(['depends' => ['libde265']]),
'libde265' => $lib(),
'lcms2' => $lib(),

// OS-restricted to Linux only
'ext-linux-only' => $ext(['os' => ['Linux']]),
Expand Down
78 changes: 39 additions & 39 deletions tests/StaticPHP/Registry/PackageLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Tests\StaticPHP\Registry;

use Package\Library\lcms2;
use PHPUnit\Framework\TestCase;
use StaticPHP\Attribute\Package\Extension;
use StaticPHP\Attribute\Package\Library;
Expand All @@ -28,26 +29,8 @@ protected function setUp(): void
parent::setUp();
$this->tempDir = sys_get_temp_dir() . '/package_loader_test_' . uniqid();
mkdir($this->tempDir, 0755, true);

// Reset PackageLoader state
$reflection = new \ReflectionClass(PackageLoader::class);

$property = $reflection->getProperty('packages');
$property->setValue(null, null);

$property = $reflection->getProperty('before_stages');
$property->setValue(null, []);

$property = $reflection->getProperty('after_stages');
$property->setValue(null, []);

$property = $reflection->getProperty('loaded_classes');
$property->setValue(null, []);

// Reset PackageConfig state
$configReflection = new \ReflectionClass(PackageConfig::class);
$configProperty = $configReflection->getProperty('package_configs');
$configProperty->setValue(null, []);
$this->resetPackageLoaderState();
$this->resetPackageConfigState();
}

protected function tearDown(): void
Expand All @@ -58,25 +41,8 @@ protected function tearDown(): void
$this->removeDirectory($this->tempDir);
}

// Reset PackageLoader state
$reflection = new \ReflectionClass(PackageLoader::class);

$property = $reflection->getProperty('packages');
$property->setValue(null, null);

$property = $reflection->getProperty('before_stages');
$property->setValue(null, []);

$property = $reflection->getProperty('after_stages');
$property->setValue(null, []);

$property = $reflection->getProperty('loaded_classes');
$property->setValue(null, []);

// Reset PackageConfig state
$configReflection = new \ReflectionClass(PackageConfig::class);
$configProperty = $configReflection->getProperty('package_configs');
$configProperty->setValue(null, []);
$this->resetPackageLoaderState();
$this->resetPackageConfigState();
}

public function testInitPackageInstancesOnlyRunsOnce(): void
Expand Down Expand Up @@ -533,6 +499,26 @@ class TestPackage1 {
$this->assertTrue(PackageLoader::hasPackage('test-lib'));
}

public function testLcms2PackageRegistersBuildStageOnUnix(): void
{
if (PHP_OS_FAMILY === 'Windows') {
$this->markTestSkipped('lcms2 build stage is only registered for Unix in this test.');
}

try {
PackageConfig::loadFromFile(__DIR__ . '/../../../config/pkg/lib/lcms2.yml', 'test');
PackageLoader::initPackageInstances();
PackageLoader::loadFromClass(lcms2::class);

$package = PackageLoader::getLibraryPackage('lcms2');
$this->assertTrue($package->hasBuildFunctionForCurrentOS());
$this->assertTrue($package->hasStage('build'));
} finally {
$this->resetPackageLoaderState();
$this->resetPackageConfigState();
}
}

private function removeDirectory(string $dir): void
{
if (!is_dir($dir)) {
Expand Down Expand Up @@ -561,4 +547,18 @@ private function createTestPackageConfig(string $name, string $type): void
];
$property->setValue(null, $configs);
}

private function resetPackageLoaderState(): void
{
$reflection = new \ReflectionClass(PackageLoader::class);
foreach (['packages' => null, 'before_stages' => [], 'after_stages' => [], 'loaded_classes' => []] as $propName => $value) {
$reflection->getProperty($propName)->setValue(null, $value);
}
}

private function resetPackageConfigState(): void
{
$configReflection = new \ReflectionClass(PackageConfig::class);
$configReflection->getProperty('package_configs')->setValue(null, []);
}
}
Loading