Skip to content

libgomp support instead of custom built gcc toolchain? #736

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
14 changes: 14 additions & 0 deletions config/lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@
"IOKit"
]
},
"libgomp": {
"source": "gcc",
"static-libs-linux": [
"libgomp.a"
],
"headers": [
"omp.h",
"openacc.h",
"acc_prof.h"
]
},
"gmp": {
"source": "gmp",
"static-libs-unix": [
Expand Down Expand Up @@ -213,6 +224,9 @@
"libheif",
"bzip2"
],
"lib-depends-linux": [
"libgomp"
],
"lib-suggests": [
"zstd",
"xz",
Expand Down
7 changes: 7 additions & 0 deletions config/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@
"path": "LICENSE.TXT"
}
},
"gcc": {
"type": "custom",
"license": {
"type": "file",
"path": "COPYING"
}
},
"gettext": {
"type": "filelist",
"url": "https://ftp.gnu.org/pub/gnu/gettext/",
Expand Down
7 changes: 3 additions & 4 deletions src/SPC/builder/extension/imagick.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@ class imagick extends Extension
{
public function patchBeforeMake(): bool
{
if (getenv('SPC_LIBC') !== 'musl') {
if (PHP_OS_FAMILY !== 'Linux') {
return false;
}
// imagick with calls omp_pause_all which requires -lgomp, on non-musl we build imagick without openmp
// imagemagick with --enable-openmp calls omp_pause_all which requires -lgomp on Linux
$extra_libs = trim(getenv('SPC_EXTRA_LIBS') . ' -lgomp');
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
return true;
}

public function getUnixConfigureArg(bool $shared = false): string
{
$disable_omp = getenv('SPC_LIBC') === 'musl' ? '' : ' ac_cv_func_omp_pause_resource_all=no';
return '--with-imagick=' . BUILD_ROOT_PATH . $disable_omp;
return '--with-imagick=' . BUILD_ROOT_PATH;
}
}
60 changes: 60 additions & 0 deletions src/SPC/builder/linux/library/libgomp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace SPC\builder\linux\library;

use SPC\builder\linux\LinuxBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\store\source\GccSource;

class libgomp extends LinuxLibraryBase
{
public const NAME = 'libgomp';

protected array $static_libs = ['libgomp.a'];

protected array $headers = [
'omp.h',
'openacc.h',
'acc_prof.h',
];

public function __construct(LinuxBuilder $builder)
{
parent::__construct($builder);
$this->source_dir = SOURCE_PATH . '/gcc';
}

/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
if (getenv('SPC_LIBC') !== 'glibc') {
return; // can use musl's libgomp.a as it's built with -fPIC
}
$outdir = $this->source_dir . '/libgomp/build/out';

FileSystem::createDir($this->source_dir . '/libgomp/build');
shell()->cd($this->source_dir . '/libgomp/build')
->setEnv([
'CFLAGS' => $this->getLibExtraCFlags(),
'LDFLAGS' => $this->getLibExtraLdFlags(),
'LIBS' => $this->getLibExtraLibs(),
])
->execWithEnv('../configure --enable-static --disable-shared --prefix= --disable-multilib --with-pic --libdir=/lib --includedir=/include')
->execWithEnv('make clean')
->execWithEnv("make -j{$this->builder->concurrency}")
->execWithEnv("make install DESTDIR={$outdir}");

copy($outdir . '/lib64/libgomp.a', BUILD_LIB_PATH . '/libgomp.a');
FileSystem::copyDir(
$outdir . '/lib/gcc/' . GccSource::getGccVersion() . '/include',
BUILD_ROOT_PATH
);
}
}
4 changes: 1 addition & 3 deletions src/SPC/builder/unix/library/imagemagick.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ trait imagemagick
*/
protected function build(): void
{
// TODO: glibc rh 10 toolset's libgomp.a was built without -fPIC -fPIE so we can't use openmp without depending on libgomp.so
$openmp = getenv('SPC_LIBC') === 'musl' ? '--enable-openmp' : '--disable-openmp';
$extra = "--without-jxl --without-x {$openmp} ";
$extra = '--without-jxl --without-x --enable-openmp ';
$required_libs = '';
$optional_libs = [
'libzip' => 'zip',
Expand Down
69 changes: 69 additions & 0 deletions src/SPC/store/source/GccSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace SPC\store\source;

use JetBrains\PhpStorm\ArrayShape;
use SPC\exception\DownloaderException;
use SPC\exception\FileSystemException;
use SPC\store\Downloader;

class GccSource extends CustomSourceBase
{
public const NAME = 'gcc';

/**
* @throws DownloaderException
* @throws FileSystemException
*/
public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void
{
$version = self::getGccVersion();
Downloader::downloadSource('gcc', self::getGccSourceInfo($version), $force);
}

/**
* Get the installed GCC version
*
* @return string The GCC version (e.g., "11.5.0")
* @throws DownloaderException
*/
public static function getGccVersion(): string
{
$cc = getenv('CC') ?: 'gcc';
$output = [];
$return_var = 0;

exec("{$cc} --version", $output, $return_var);

if ($return_var !== 0 || empty($output)) {
throw new DownloaderException("Failed to get GCC version using {$cc}");
}

// Parse the version from the output
// Example output: "gcc (GCC) 11.5.0" or "gcc (Ubuntu 4.8.5-4ubuntu2) 4.8.5"
$version_line = $output[0];
if (preg_match('/\s(\d+\.\d+\.\d+)/', $version_line, $matches)) {
// official ftp mirrors only keep .0 releases
return preg_replace('/\.\d+$/', '.0', $matches[1]);
}

throw new DownloaderException("Could not parse GCC version from: {$version_line}");
}

/**
* Get the GCC source information for a specific version
*
* @param string $version The GCC version to download
* @return array The source information
*/
#[ArrayShape(['type' => 'string', 'url' => 'string'])]
public static function getGccSourceInfo(string $version): array
{
return [
'type' => 'url',
'url' => "https://ftp.gnu.org/gnu/gcc/gcc-{$version}/gcc-{$version}.tar.xz",
];
}
}
2 changes: 1 addition & 1 deletion src/SPC/util/SPCConfigUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private function getLibsString(array $libraries): string
}
}
// patch: imagick (imagemagick wrapper) for linux needs libgomp
if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') {
if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux') {
$short_name[] = '-lgomp';
}
return implode(' ', $short_name);
Expand Down