Giter VIP home page Giter VIP logo

Comments (5)

crazywhalecc avatar crazywhalecc commented on May 17, 2024 1

@jingjingxyk 我已经完成了小重构,小重构更新了 CMake 编译时的流程,同时完成了以下特性:

  • 使用 pkgconfig 管理依赖,无需每个库手动指定 _LIBS 了。
  • 在编译 CMake 库时,减少重复编写参数(合并例如 -DCMAKE_INSTALL_PREFIX),使用调用方法获取。
  • 利用 PHP 的 Trait 合并了部分 Linux 和 macOS 编译命令相同的库,减少冗余重复代码。
  • 完成了 gd 的额外库编译:gif、webp、jpeg、avif。
  • 新增了 patch pkgconfig 的方法,在编译后直接调用方法,传入 pkgconf 文件名即可实现 patch prefix(就是把 prefix=/ 替换成真实路径)。

例如,我增加的 libjpeg 编译代码部分简洁到了这个地步:

trait libjpeg
{
    protected function build()
    {
        // CMake needs a clean build directory
        FileSystem::resetDir($this->source_dir . '/build');
        // Start build
        shell()->cd($this->source_dir . '/build')
            ->exec(
                "{$this->builder->configure_env} cmake {$this->builder->makeCmakeArgs()} " .
                '-DENABLE_STATIC=ON ' .
                '-DENABLE_SHARED=OFF ' .
                '..'
            )
            ->exec("cmake --build . -j {$this->builder->concurrency}")
            ->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
        // patch pkgconfig
        $this->patchPkgconfPrefix(['libjpeg.pc', 'libturbojpeg.pc']);
    }
}

在 gd 库根据选项启用特性的方法也简化了:

#[CustomExt('gd')]
class gd extends Extension
{
    public function getUnixConfigureArg(): string
    {
        $arg = '--enable-gd';
        $arg .= $this->builder->getLib('freetype') ? ' --with-freetype' : '';
        $arg .= $this->builder->getLib('libjpeg') ? ' --with-jpeg' : '';
        $arg .= $this->builder->getLib('libwebp') ? ' --with-webp' : '';
        $arg .= $this->builder->getLib('libavif') ? ' --with-avif' : '';
        return $arg;
    }
}

感谢提的建议,我这里也算是完成了这个特性,以后可以按照这个模子增加新的扩展了。还有你的 PR 也不白写,我写的时候也参照了你的改动分支,同时我看你的 PR 里面还有其他特性的更新,比如安装系统环境需要的工具。这个在我后续加入 doctor 命令时候有很大作用。

from static-php-cli.

crazywhalecc avatar crazywhalecc commented on May 17, 2024

你说的对,使用 pkgconf 来管理是更好的。现在因为部分库没有生成 pkgconf,所以就全部使用手动指定 XXX_LIBSXXX_CFLAGS 的方式来选择依赖库,例如我完成的 libjpeg 依赖处理:

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

shell()->cd($this->source_dir)
    ->exec('rm -rf build')
    ->exec('mkdir -p build')
    ->cd($this->source_dir . '/build')
    ->exec(
        "{$this->builder->configure_env} cmake " .
        '-DCMAKE_BUILD_TYPE=Release ' .
        '-DBUILD_SHARED_LIBS=OFF ' .
        '-DENABLE_SHARED=OFF ' .
        '-DCMAKE_INSTALL_PREFIX= ' .
        "-DCMAKE_INSTALL_LIBDIR={$lib} " .
        "-DCMAKE_INSTALL_INCLUDEDIR={$include} " .
        "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
        '..'
    )
    ->exec("make -j{$this->builder->concurrency}")
    ->exec("make install DESTDIR={$destdir}");

安装后,gd 库引入的方式是:

#[CustomExt('gd')]
class gd extends Extension
{
    public function getUnixConfigureArg(): string
    {
        $arg = '--enable-gd';
        if ($this->builder->getLib('freetype')) {
            $arg .= ' --with-freetype ' .
                'FREETYPE2_CFLAGS=-I"' . BUILD_INCLUDE_PATH . '/freetype2" ' .
                'FREETYPE2_LIBS="' . $this->getLibFilesString() . '"';
        }
        $arg .= ' PNG_CFLAGS=-I"' . BUILD_INCLUDE_PATH . '" ' .
            'PNG_LIBS="' . $this->getLibFilesString() . '"';
        if ($this->builder->getLib('libjpeg')) {
            $arg .= ' --with-jpeg' .
                'JPEG_CFLAGS=-I"' . BUILD_INCLUDE_PATH . '" ' .
                'JPEG_LIBS="' . $this->getLibFilesString() . '"';
        } // 手动设置 configure 中指定 libjpeg 库的 include 目录,LIBS 参数直接指定需要的库文件 `xxx.a`
        return $arg;
    }
}

我这几天尝试看看能不能优先把这些库都换成 pkgconfig 方式读取的,因为之前是混杂模式,现在 buildroot 目录没有 .so.dylib 库的生成,理论上不会有动静态混用导致编译失败的情况。

from static-php-cli.

crazywhalecc avatar crazywhalecc commented on May 17, 2024

使用 pkg-config 需要在 pkgconfig 内把 prefix= 后面加上 BUILD_ROOT_PATH,也就是 buildroot/ 这个目录的绝对路径。另外,例如 如果 libdir= 为空或者是 libdir=/lib 的话,需要手动换成 libdir=${prefix}/lib。当然这个是个小问题,可以在编译库的时候解决它。或者还有一种比较暴力的方案就是在编译 PHP 时,将所有的 pkgconf 都临时替换一下,将上述路径都替换为绝对路径。

from static-php-cli.

crazywhalecc avatar crazywhalecc commented on May 17, 2024

此外,配置文件的 static-libsheaders 参数也是有意义的。它可以统计每个库有哪些 .a 的静态 lib 文件,在编译初期也需要他们来判断是否要编译这个库,存在的话就可以跳过,避免反复编译;另一方面,每个库都做了什么,哪个扩展用到了,任何资源都是十分明了的。不建议在配置文件里留空,因为可能无法自动编译到对应的库。

from static-php-cli.

jingjingxyk avatar jingjingxyk commented on May 17, 2024

666

from static-php-cli.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.