diff --git a/bin/setup-runtime b/bin/setup-runtime index 48144f973..9f3805495 100755 --- a/bin/setup-runtime +++ b/bin/setup-runtime @@ -28,8 +28,10 @@ __PROJECT__=$(cd ${__DIR__}/../ && pwd) __PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.6-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz" __COMPOSER_URL__="https://getcomposer.org/download/latest-stable/composer.phar" + # use china mirror # bash bin/setup-runtime --mirror china + mirror='' while [ $# -gt 0 ]; do case "$1" in diff --git a/config/ext.json b/config/ext.json index 7a7b3b0f9..c82b1b56f 100644 --- a/config/ext.json +++ b/config/ext.json @@ -81,7 +81,11 @@ "arg-type-windows": "with", "lib-depends": [ "zlib", - "libpng" + "libpng", + "libjpeg", + "freetype", + "libgif", + "libwebp" ], "ext-depends": [ "zlib" diff --git a/config/source.json b/config/source.json index d74fd4963..8f557cb12 100644 --- a/config/source.json +++ b/config/source.json @@ -173,8 +173,34 @@ "url": "https://git.code.sf.net/p/libpng/code", "rev": "libpng16", "license": { - "type": "text", - "text": "COPYRIGHT NOTICE, DISCLAIMER, and LICENSE\n=========================================\n\nPNG Reference Library License version 2\n---------------------------------------\n\n * Copyright (c) 1995-2019 The PNG Reference Library Authors.\n * Copyright (c) 2018-2019 Cosmin Truta.\n * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.\n * Copyright (c) 1996-1997 Andreas Dilger.\n * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n\nThe software is supplied \"as is\", without warranty of any kind,\nexpress or implied, including, without limitation, the warranties\nof merchantability, fitness for a particular purpose, title, and\nnon-infringement. In no event shall the Copyright owners, or\nanyone distributing the software, be liable for any damages or\nother liability, whether in contract, tort or otherwise, arising\nfrom, out of, or in connection with the software, or the use or\nother dealings in the software, even if advised of the possibility\nof such damage.\n\nPermission is hereby granted to use, copy, modify, and distribute\nthis software, or portions hereof, for any purpose, without fee,\nsubject to the following restrictions:\n\n 1. The origin of this software must not be misrepresented; you\n must not claim that you wrote the original software. If you\n use this software in a product, an acknowledgment in the product\n documentation would be appreciated, but is not required.\n\n 2. Altered source versions must be plainly marked as such, and must\n not be misrepresented as being the original software.\n\n 3. This Copyright notice may not be removed or altered from any\n source or altered source distribution.\n\n\nPNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)\n-----------------------------------------------------------------------\n\nlibpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are\nCopyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are\nderived from libpng-1.0.6, and are distributed according to the same\ndisclaimer and license as libpng-1.0.6 with the following individuals\nadded to the list of Contributing Authors:\n\n Simon-Pierre Cadieux\n Eric S. Raymond\n Mans Rullgard\n Cosmin Truta\n Gilles Vollant\n James Yu\n Mandar Sahastrabuddhe\n Google Inc.\n Vadim Barkov\n\nand with the following additions to the disclaimer:\n\n There is no warranty against interference with your enjoyment of\n the library or against infringement. There is no warranty that our\n efforts or the library will fulfill any of your particular purposes\n or needs. This library is provided with all faults, and the entire\n risk of satisfactory quality, performance, accuracy, and effort is\n with the user.\n\nSome files in the \"contrib\" directory and some configure-generated\nfiles that are distributed with libpng have other copyright owners, and\nare released under other open source licenses.\n\nlibpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are\nCopyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from\nlibpng-0.96, and are distributed according to the same disclaimer and\nlicense as libpng-0.96, with the following individuals added to the\nlist of Contributing Authors:\n\n Tom Lane\n Glenn Randers-Pehrson\n Willem van Schaik\n\nlibpng versions 0.89, June 1996, through 0.96, May 1997, are\nCopyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,\nand are distributed according to the same disclaimer and license as\nlibpng-0.88, with the following individuals added to the list of\nContributing Authors:\n\n John Bowler\n Kevin Bracey\n Sam Bushell\n Magnus Holmgren\n Greg Roelofs\n Tom Tanner\n\nSome files in the \"scripts\" directory have other copyright owners,\nbut are released under this license.\n\nlibpng versions 0.5, May 1995, through 0.88, January 1996, are\nCopyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n\nFor the purposes of this copyright and license, \"Contributing Authors\"\nis defined as the following set of individuals:\n\n Andreas Dilger\n Dave Martindale\n Guy Eric Schalnat\n Paul Schmidt\n Tim Wegner\n\nThe PNG Reference Library is supplied \"AS IS\". The Contributing\nAuthors and Group 42, Inc. disclaim all warranties, expressed or\nimplied, including, without limitation, the warranties of\nmerchantability and of fitness for any purpose. The Contributing\nAuthors and Group 42, Inc. assume no liability for direct, indirect,\nincidental, special, exemplary, or consequential damages, which may\nresult from the use of the PNG Reference Library, even if advised of\nthe possibility of such damage.\n\nPermission is hereby granted to use, copy, modify, and distribute this\nsource code, or portions hereof, for any purpose, without fee, subject\nto the following restrictions:\n\n 1. The origin of this source code must not be misrepresented.\n\n 2. Altered versions must be plainly marked as such and must not\n be misrepresented as being the original source.\n\n 3. This Copyright notice may not be removed or altered from any\n source or altered source distribution.\n\nThe Contributing Authors and Group 42, Inc. specifically permit,\nwithout fee, and encourage the use of this source code as a component\nto supporting the PNG file format in commercial products. If you use\nthis source code in a product, acknowledgment is not required but would\nbe appreciated.\n" + "type": "file", + "path": "LICENSE" + } + }, + "libjpeg": { + "type": "git", + "url": "https://github.com/libjpeg-turbo/libjpeg-turbo.git", + "rev": "2.1.91", + "license": { + "type": "file", + "path": "LICENSE.md" + } + }, + "libgif": { + "type": "url", + "url": "https://nchc.dl.sourceforge.net/project/giflib/giflib-5.2.1.tar.gz", + "license": { + "type": "file", + "path": "COPYING" + } + }, + "libwebp": { + "type": "git", + "url": "https://chromium.googlesource.com/webm/libwebp", + "rev": "v1.3.0", + "license": { + "type": "file", + "path": "COPYING" } }, "libressl": { diff --git a/quickstart/linux/README.md b/quickstart/linux/README.md index c6090a30e..3648e88ab 100644 --- a/quickstart/linux/README.md +++ b/quickstart/linux/README.md @@ -14,7 +14,11 @@ sh quickstart/linux/run-debian-11-container.sh sh quickstart/linux/connection-static-php-cli.sh # 准备构建基础软件 -sh quickstart/linux/debian-11-init.sh +sh quickstart/linux/x86_64/debian-11-init.sh + +# 准备构建基础软件 使用镜像 +sh quickstart/linux/x86_64/debian-11-init.sh --mirror china + ``` @@ -29,6 +33,19 @@ sh quickstart/linux/run-alpine-3.16-container.sh sh sh quickstart/linux/connection-static-php-cli.sh # 准备构建基础软件 -sh quickstart/linux/alpine-3.16-init.sh +sh quickstart/linux/x86_64/alpine-3.16-init.sh + +# 准备构建基础软件 使用镜像 +sh quickstart/linux/x86_64/alpine-3.16-init.sh --mirror china +``` + + +## 准备PHP 运行时镜像 +```bash +sh bin/setup-runtime + +# 使用镜像 +sh bin/setup-runtime --mirror china + ``` \ No newline at end of file diff --git a/quickstart/linux/alpine-3.16-init.sh b/quickstart/linux/alpine-3.16-init.sh index 8aed86b66..f84ebbc45 100644 --- a/quickstart/linux/alpine-3.16-init.sh +++ b/quickstart/linux/alpine-3.16-init.sh @@ -34,7 +34,6 @@ esac apk update - apk add vim alpine-sdk xz autoconf automake linux-headers clang-dev clang lld libtool cmake bison re2c gettext coreutils apk add bash p7zip zip unzip flex pkgconf ca-certificates -apk add wget git curl \ No newline at end of file +apk add wget git curl diff --git a/quickstart/linux/debian-11-init.sh b/quickstart/linux/debian-11-init.sh index dbd8478c1..5c7cec5a8 100644 --- a/quickstart/linux/debian-11-init.sh +++ b/quickstart/linux/debian-11-init.sh @@ -39,3 +39,6 @@ apt install -y xz-utils autoconf automake lld libtool cmake bison re2c gettext c apt install -y pkg-config bzip2 flex p7zip apt install -y musl-tools g++ apt install -y clang + +# apt install build-essential linux-headers-$(uname -r) + diff --git a/quickstart/linux/run-alpine-3.16-container.sh b/quickstart/linux/run-alpine-3.16-container.sh index fa3ea0e50..2fd66c114 100644 --- a/quickstart/linux/run-alpine-3.16-container.sh +++ b/quickstart/linux/run-alpine-3.16-container.sh @@ -14,6 +14,7 @@ cd ${__DIR__} { docker stop static-php-cli-dev-1 + sleep 5 } || { echo $? } diff --git a/quickstart/linux/run-debian-11-container.sh b/quickstart/linux/run-debian-11-container.sh index c00ae1a6b..1e19c7794 100644 --- a/quickstart/linux/run-debian-11-container.sh +++ b/quickstart/linux/run-debian-11-container.sh @@ -14,6 +14,7 @@ cd ${__DIR__} { docker stop static-php-cli-dev-1 + sleep 5 } || { echo $? } diff --git a/quickstart/prepare.sh b/quickstart/prepare.sh index 9f4669d12..64e9e9e82 100644 --- a/quickstart/prepare.sh +++ b/quickstart/prepare.sh @@ -48,5 +48,8 @@ EXTENSIONS="${EXTENSIONS},mongodb" # EXTENSIONS="${EXTENSIONS},swoole" EXTENSIONS="${EXTENSIONS},swow" + +# # musl-gcc/musl-clang(或 gcc-musl/gcc-clang + ./bin/spc build "${EXTENSIONS}" --build-cli --cc=clang --cxx=clang++ --debug # ./bin/spc build "${EXTENSIONS}" --build-cli --cc=gcc --cxx=g++ --debug diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index 900bb4ed2..864c31fa1 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -76,7 +76,9 @@ public function buildLibs(array $libraries): void // 过滤不支持的库后添加 foreach ($libraries as $library) { if (!isset($support_lib_list[$library])) { - throw new RuntimeException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!'); + throw new RuntimeException( + 'library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!' + ); } $lib = new ($support_lib_list[$library])($this); $this->addLib($lib); @@ -91,6 +93,7 @@ public function buildLibs(array $libraries): void // 构建库 foreach ($this->libs as $lib) { + // $lib->build(true); match ($lib->tryBuild()) { BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'), BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'), @@ -257,7 +260,9 @@ protected function checkLibsSource(): void '"' . implode(', ', $not_downloaded) . '" totally ' . count($not_downloaded) . ' source' . (count($not_downloaded) === 1 ? '' : 's') . - ' not downloaded, maybe you need to "fetch" ' . (count($not_downloaded) === 1 ? 'it' : 'them') . ' first?' + ' not downloaded, maybe you need to "fetch" ' . (count( + $not_downloaded + ) === 1 ? 'it' : 'them') . ' first?' ); } } @@ -265,7 +270,9 @@ protected function checkLibsSource(): void protected function initSource(?array $sources = null, ?array $libs = null, ?array $exts = null): void { if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) { - throw new WrongUsageException('Download lock file "downloads/.lock.json" not found, maybe you need to download sources first ?'); + throw new WrongUsageException( + 'Download lock file "downloads/.lock.json" not found, maybe you need to download sources first ?' + ); } $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true); @@ -299,13 +306,19 @@ protected function initSource(?array $sources = null, ?array $libs = null, ?arra // start check foreach ($sources_extracted as $source => $item) { if (!isset($lock[$source])) { - throw new WrongUsageException('Source [' . $source . '] not downloaded, you should download it first !'); + throw new WrongUsageException( + 'Source [' . $source . '] not downloaded, you should download it first !' + ); } // check source dir exist $check = $lock[$source]['move_path'] === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $lock[$source]['move_path']; if (!is_dir($check)) { - FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']); + FileSystem::extractSource( + $source, + DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), + $lock[$source]['move_path'] + ); } } } diff --git a/src/SPC/builder/extension/zip.php b/src/SPC/builder/extension/zip.php new file mode 100644 index 000000000..d49e3e629 --- /dev/null +++ b/src/SPC/builder/extension/zip.php @@ -0,0 +1,17 @@ +cc = $cc ?? match (SystemUtil::getOSRelease()['dist']) { 'alpine' => 'gcc', default => 'musl-gcc' }; + $this->cxx = $cxx ?? 'g++'; $this->arch = $arch ?? php_uname('m'); $this->gnu_arch = arch2gnu($this->arch); + $this->zts = $zts; $this->libc = 'musl'; // SystemUtil::selectLibc($this->cc); @@ -70,14 +90,25 @@ public function __construct(?string $cc = null, ?string $cxx = null, ?string $ar cc: $this->cc, cxx: $this->cxx ); + $build_root_path = BUILD_ROOT_PATH; + $build_lib_path = BUILD_LIB_PATH; // 设置 pkgconfig + $this->pkgconf_env = 'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig"'; + // 设置 configure 依赖的环境变量 - $this->configure_env = - $this->pkgconf_env . ' ' . - "CC='{$this->cc}' " . - "CXX='{$this->cxx}' " . - (php_uname('m') === $this->arch ? '' : "CFLAGS='{$this->arch_c_flags}'"); + $this->configure_env = <<cc} + export CXX={$this->cxx} + export LD={$this->ld} + export PATH={$build_root_path}/bin/:\$PATH + {$this->pkgconf_env} + +EOF; + $this->configure_env = PHP_EOL . $this->configure_env . PHP_EOL; + + php_uname('m') === $this->arch ? '' : "CFLAGS='{$this->arch_c_flags}'"; // 交叉编译依赖的,TODO if (php_uname('m') !== $this->arch) { $this->cross_compile_prefix = SystemUtil::getCrossCompilePrefix($this->cc, $this->arch); @@ -96,6 +127,7 @@ public function __construct(?string $cc = null, ?string $cxx = null, ?string $ar } // 创立 pkg-config 和放头文件的目录 + f_mkdir(BUILD_ROOT_PATH . '/bin', recursive: true); f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true); f_mkdir(BUILD_INCLUDE_PATH, recursive: true); } @@ -146,9 +178,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean $extra_libs .= ' /usr/lib/libMagick++-7.Q16HDRI.a /usr/lib/libMagickCore-7.Q16HDRI.a /usr/lib/libMagickWand-7.Q16HDRI.a'; } - $envs = $this->pkgconf_env . ' ' . - "CC='{$this->cc}' " . - "CXX='{$this->cxx}' "; + $envs = ''; $cflags = $this->arch_c_flags; $use_lld = ''; @@ -158,21 +188,55 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean $cflags .= ' -static-libgcc -I"' . BUILD_INCLUDE_PATH . '"'; break; case 'musl': + case 'libc': if (str_ends_with($this->cc, 'clang') && SystemUtil::findCommand('lld')) { - $use_lld = '-Xcompiler -fuse-ld=lld'; + $use_lld = '-Xcompiler -fuse-ld=lld'; // lld = ld.lld soft link } break; default: - throw new WrongUsageException('libc ' . $this->libc . ' is not implemented yet'); + throw new WrongUsageException( + 'libc ' . $this->libc . ' is not implemented yet ' . __FILE__ . ':' . __LINE__ + ); + } + + $lib_meta = FileSystem::loadConfigArray('lib'); + $packages = []; + $pkg_libs = []; + foreach ($this->libs as $lib) { + if (isset($lib_meta[$lib::NAME]['pkg-unix'])) { + $packages = array_merge($packages, $lib_meta[$lib::NAME]['pkg-unix']); + } + if (isset($lib_meta[$lib::NAME]['none-pkg-unix'])) { + $pkg_libs = array_merge($pkg_libs, $lib_meta[$lib::NAME]['none-pkg-unix']); + } } - $envs = "{$envs} CFLAGS='{$cflags}' LIBS='-ldl -lpthread'"; + $packages = array_unique($packages); + // -I/usr/include -I/usr/local/include + // -L/usr/lib -L/usr/local/lib + $envs = $this->configure_env; + $envs .= ' CPPFLAGS="-I' . BUILD_ROOT_PATH . '/include " ' . PHP_EOL; + $envs .= ' LDFLAGS="-L' . BUILD_ROOT_PATH . '/lib " ' . PHP_EOL; + $envs .= ' LIBS=" -lm -lrt -lpthread -lcrypt -lutil -lresolv " ' . PHP_EOL; + # $envs .= ' LIBS="-lc++ -libc++ -lm -lrt -lpthread -lcrypt -lutil -lxnet -lresolv " ' . PHP_EOL; + // for libc -lm -lrt -lpthread -lcrypt -lutil -lxnet -lresolv SourcePatcher::patchPHPBuildconf($this); - shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force'); + if (!empty($pkg_libs)) { + $envs .= ' LIBS="$LIBS ' . implode(' ', $pkg_libs) . '"' . PHP_EOL; + } - SourcePatcher::patchPHPConfigure($this); + if (!empty($packages)) { + $envs .= ' export PACKAGES="' . implode(' ', $packages) . '" ' . PHP_EOL; + $envs .= ' export CPPFLAGS="$CPPFLAGS $(pkg-config --cflags-only-I --static $PACKAGES )" ' . PHP_EOL; + $envs .= ' export LDFLAGS="$LDFLAGS $(pkg-config --libs-only-L --static $PACKAGES )" ' . PHP_EOL; + $envs .= ' export LIBS="$(pkg-config --libs-only-l --static $PACKAGES ) $LIBS" ' . PHP_EOL; + } + $cflags .= ' -static '; // -std=gnu11 -idirafter /usr/include -nostdinc /usr/lib + if (strlen($cflags) > 2) { + $envs .= " export CFLAGS=\"{$cflags}\" " . PHP_EOL; + } if ($this->getPHPVersionID() < 80000) { $json_74 = '--enable-json '; @@ -182,8 +246,21 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean shell()->cd(SOURCE_PATH . '/php-src') ->exec( + <<<'EOF' + if [[ -d php_cli_process_title.lo ]] + then + make clean + fi + +EOF + ); + shell() + ->cd(SOURCE_PATH . '/php-src') + ->exec( + $envs . PHP_EOL . + './buildconf --force' . PHP_EOL . './configure ' . - '--prefix= ' . + '--prefix=/' . '--with-valgrind=no ' . '--enable-shared=no ' . '--enable-static=yes ' . @@ -195,8 +272,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean $json_74 . '--enable-micro=all-static ' . ($this->zts ? '--enable-zts' : '') . ' ' . - $this->makeExtensionArgs() . ' ' . - $envs + $this->makeExtensionArgs() ); SourcePatcher::patchPHPAfterConfigure($this); @@ -204,24 +280,24 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean file_put_contents('/tmp/comment', $this->note_section); // 清理 - $this->cleanMake(); + // $this->cleanMake(); if ($bloat) { logger()->info('bloat linking'); - $extra_libs = "-Wl,--whole-archive {$extra_libs} -Wl,--no-whole-archive"; + $extra_libs = "-Wl,--whole-archive {$extra_libs} -Wl,--no-whole-archive "; } if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { logger()->info('building cli'); - $this->buildCli($extra_libs, $use_lld); + $this->buildCli($extra_libs, $use_lld, $envs); } if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) { logger()->info('building fpm'); - $this->buildFpm($extra_libs, $use_lld); + $this->buildFpm($extra_libs, $use_lld, $envs); } if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) { logger()->info('building micro'); - $this->buildMicro($extra_libs, $use_lld, $cflags); + $this->buildMicro($extra_libs, $use_lld, $cflags, $envs); } if (php_uname('m') === $this->arch) { @@ -236,30 +312,35 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean /** * @throws RuntimeException */ - public function buildCli(string $extra_libs, string $use_lld): void + public function buildCli(string $extra_libs, string $use_lld, string $envs = ''): void { shell()->cd(SOURCE_PATH . '/php-src') - ->exec('sed -i "s|//lib|/lib|g" Makefile') + // ->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec( + 'echo start build' . PHP_EOL . + $envs . PHP_EOL . 'make -j' . $this->concurrency . - ' EXTRA_CFLAGS="-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . '" ' . - "EXTRA_LIBS=\"{$extra_libs}\" " . - "EXTRA_LDFLAGS_PROGRAM='{$use_lld} -all-static' " . - 'cli' + ' cli' ); - + /* + . '" ' . + "EXTRA_LIBS=\"{$extra_libs}\" " . + "EXTRA_LDFLAGS_PROGRAM='{$use_lld} -all-static' " . + */ shell()->cd(SOURCE_PATH . '/php-src/sapi/cli') ->exec("{$this->cross_compile_prefix}objcopy --only-keep-debug php php.debug") ->exec('elfedit --output-osabi linux php') ->exec("{$this->cross_compile_prefix}strip --strip-all php") - ->exec("{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php.debug --remove-section=.note php"); + ->exec( + "{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php.debug --remove-section=.note php" + ); $this->deployBinary(BUILD_TARGET_CLI); } /** * @throws RuntimeException */ - public function buildMicro(string $extra_libs, string $use_lld, string $cflags): void + public function buildMicro(string $extra_libs, string $use_lld, string $cflags, string $envs = ''): void { if ($this->getPHPVersionID() < 80000) { throw new RuntimeException('phpmicro only support PHP >= 8.0!'); @@ -273,13 +354,17 @@ public function buildMicro(string $extra_libs, string $use_lld, string $cflags): ->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec( "make -j{$this->concurrency} " . - 'EXTRA_CFLAGS=' . quote('-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags))) . ' ' . + 'EXTRA_CFLAGS=' . quote( + '-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) + ) . ' ' . 'EXTRA_LIBS=' . quote($extra_libs) . ' ' . 'EXTRA_LDFLAGS_PROGRAM=' . quote("{$cflags} {$use_lld}" . ' -all-static', "'") . ' ' . 'micro' ); - shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec("{$this->cross_compile_prefix}strip --strip-all micro.sfx"); + shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec( + "{$this->cross_compile_prefix}strip --strip-all micro.sfx" + ); $this->deployBinary(BUILD_TARGET_MICRO); } @@ -289,13 +374,16 @@ public function buildMicro(string $extra_libs, string $use_lld, string $cflags): * * @throws FileSystemException|RuntimeException */ - public function buildFpm(string $extra_libs, string $use_lld): void + public function buildFpm(string $extra_libs, string $use_lld, string $envs = ''): void { shell()->cd(SOURCE_PATH . '/php-src') ->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec( 'make -j' . $this->concurrency . - ' EXTRA_CFLAGS="-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . '" ' . + ' EXTRA_CFLAGS="-g -Os -fno-ident ' . implode( + ' ', + array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags) + ) . '" ' . "EXTRA_LIBS=\"{$extra_libs}\" " . "EXTRA_LDFLAGS_PROGRAM='{$use_lld} -all-static' " . 'fpm' @@ -305,7 +393,9 @@ public function buildFpm(string $extra_libs, string $use_lld): void ->exec("{$this->cross_compile_prefix}objcopy --only-keep-debug php-fpm php-fpm.debug") ->exec('elfedit --output-osabi linux php-fpm') ->exec("{$this->cross_compile_prefix}strip --strip-all php-fpm") - ->exec("{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php-fpm.debug --remove-section=.note php-fpm"); + ->exec( + "{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php-fpm.debug --remove-section=.note php-fpm" + ); $this->deployBinary(BUILD_TARGET_FPM); } } diff --git a/src/SPC/builder/linux/library/libgif.php b/src/SPC/builder/linux/library/libgif.php new file mode 100644 index 000000000..0f6b4bffb --- /dev/null +++ b/src/SPC/builder/linux/library/libgif.php @@ -0,0 +1,36 @@ +cd($this->source_dir) + ->exec( + <<<'EOF' + if [[ -f libgif.a ]] + then + make clean + fi +EOF + ); + shell()->cd($this->source_dir) + ->exec(" {$this->builder->configure_env} make -j {$this->builder->concurrency} libgif.a") + ->exec("cp libgif.a {$destdir}/lib/libgif.a") + ->exec("cp gif_lib.h {$destdir}/include/gif_lib.h"); + } +} diff --git a/src/SPC/builder/linux/library/libpng.php b/src/SPC/builder/linux/library/libpng.php index e3d0e2cef..2e8b5d46d 100644 --- a/src/SPC/builder/linux/library/libpng.php +++ b/src/SPC/builder/linux/library/libpng.php @@ -56,7 +56,9 @@ public function build() '--prefix=' ) ->exec('make clean') - ->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la") + ->exec( + "make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la" + ) ->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH) ->cd(BUILD_LIB_PATH) ->exec('ln -sf libpng16.a libpng.a'); diff --git a/src/SPC/builder/linux/library/libwebp.php b/src/SPC/builder/linux/library/libwebp.php index d376e3416..972353840 100644 --- a/src/SPC/builder/linux/library/libwebp.php +++ b/src/SPC/builder/linux/library/libwebp.php @@ -1,20 +1,4 @@ - * - * lwmbs is licensed under Mulan PSL v2. You can use this - * software according to the terms and conditions of the - * Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, - * WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * - * See the Mulan PSL v2 for more details. - */ declare(strict_types=1); diff --git a/src/SPC/builder/linux/library/nghttp2.php b/src/SPC/builder/linux/library/nghttp2.php index 733b562d8..693d32f51 100644 --- a/src/SPC/builder/linux/library/nghttp2.php +++ b/src/SPC/builder/linux/library/nghttp2.php @@ -42,7 +42,7 @@ public function build() 'cunit' => null, ]); - [,,$destdir] = SEPARATED_PATH; + [, , $destdir] = SEPARATED_PATH; shell()->cd($this->source_dir) ->exec( diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index d5cfa7cbb..7dde29db4 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -34,7 +34,7 @@ class openssl extends LinuxLibraryBase */ public function build() { - [$lib,$include,$destdir] = SEPARATED_PATH; + [$lib, $include, $destdir] = SEPARATED_PATH; $extra = ''; $ex_lib = '-ldl -pthread'; diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index cb7f9f562..e11f862bc 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -10,7 +10,9 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\store\FileSystem; use SPC\store\SourcePatcher; +use SPC\util\Patcher; /** * macOS 系统环境下的构建器 @@ -24,6 +26,9 @@ class MacOSBuilder extends BuilderBase /** @var bool 标记是否 patch 了 phar */ private bool $phar_patched = false; + /** @var string env pkgconf */ + private string $pkgconf_env; + /** * @param null|string $cc C编译器名称,如果不传入则默认使用clang * @param null|string $cxx C++编译器名称,如果不传入则默认使用clang++ @@ -48,7 +53,16 @@ public function __construct(?string $cc = null, ?string $cxx = null, ?string $ar $this->arch_cxx_flags = SystemUtil::getArchCFlags($this->arch); // 设置 cmake $this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->arch, $this->arch_c_flags); + + $build_root_path = BUILD_ROOT_PATH; + $build_lib_path = BUILD_LIB_PATH; + // 设置 pkgconfig + $this->pkgconf_env = 'export PKG_CONFIG_PATH="' . $build_lib_path . '/pkgconfig:/usr/lib/pkgconfig"'; + $this->ld = $this->cc == 'clang' ? 'lld' : 'ld'; // 设置 configure 依赖的环境变量 + + $this->configure_env .= PHP_EOL . $this->pkgconf_env . PHP_EOL; + $this->configure_env = 'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" ' . 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' . @@ -57,6 +71,7 @@ public function __construct(?string $cc = null, ?string $cxx = null, ?string $ar "CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration'"; // 创立 pkg-config 和放头文件的目录 + f_mkdir(BUILD_ROOT_PATH . '/bin', recursive: true); f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true); f_mkdir(BUILD_INCLUDE_PATH, recursive: true); } @@ -137,9 +152,59 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = fa ); } + $envs = ''; + $cflags = $this->arch_c_flags; + $use_lld = ''; + + $lib_meta = FileSystem::loadConfigArray('lib'); + $packages = []; + $pkg_libs = []; + foreach ($this->libs as $lib) { + if (isset($lib_meta[$lib::NAME]['pkg-unix'])) { + $packages = array_merge($packages, $lib_meta[$lib::NAME]['pkg-unix']); + } + if (isset($lib_meta[$lib::NAME]['none-pkg-unix'])) { + $pkg_libs = array_merge($pkg_libs, $lib_meta[$lib::NAME]['none-pkg-unix']); + } + } + + $packages = array_unique($packages); + $envs = $this->configure_env; + $envs .= ' CPPFLAGS="-I' . BUILD_ROOT_PATH . '/include " ' . PHP_EOL; + $envs .= ' LDFLAGS="-L' . BUILD_ROOT_PATH . '/lib " ' . PHP_EOL; + $envs .= ' LIBS=" -lm -lpthread -lutil -lresolv " ' . PHP_EOL; + + if (!empty($pkg_libs)) { + $envs .= ' LIBS="$LIBS ' . implode(' ', $pkg_libs) . '"' . PHP_EOL; + } + + if (!empty($packages)) { + $envs .= ' export PACKAGES="' . implode(' ', $packages) . '" ' . PHP_EOL; + $envs .= ' export CPPFLAGS="$CPPFLAGS $(pkg-config --cflags-only-I --static $PACKAGES )" ' . PHP_EOL; + $envs .= ' export LDFLAGS="$LDFLAGS $(pkg-config --libs-only-L --static $PACKAGES )" ' . PHP_EOL; + $envs .= ' export LIBS="$(pkg-config --libs-only-l --static $PACKAGES ) $LIBS" ' . PHP_EOL; + } + $cflags .= ' -Wimplicit-function-declaration '; + if (strlen($cflags) > 2) { + $envs .= " export CFLAGS=\"{$cflags}\" " . PHP_EOL; + } + + $envs .= 'export EXTRA_LDFLAGS_PROGRAM="$LDFLAGS -all-static"'; + shell()->cd(SOURCE_PATH . '/php-src') + ->exec( + <<<'EOF' + if [[ -d php_cli_process_title.lo ]] + then + make clean + fi + +EOF + ); // patch before configure SourcePatcher::patchPHPBuildconf($this); + // Patcher::patchPHPConfigure($this); + shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force'); SourcePatcher::patchPHPConfigure($this); @@ -156,6 +221,9 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = fa shell()->cd(SOURCE_PATH . '/php-src') ->exec( + 'echo "start build php"' . PHP_EOL . + $envs . PHP_EOL . + './buildconf --force ' . PHP_EOL . './configure ' . '--prefix= ' . '--with-valgrind=no ' . // 不检测内存泄漏 @@ -180,15 +248,15 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = fa if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { logger()->info('building cli'); - $this->buildCli($extra_libs); + $this->buildCli($extra_libs, $envs); } if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) { logger()->info('building fpm'); - $this->buildFpm($extra_libs); + $this->buildFpm($extra_libs, $envs); } if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) { logger()->info('building micro'); - $this->buildMicro($extra_libs); + $this->buildMicro($extra_libs, $envs); } if (php_uname('m') === $this->arch) { @@ -206,10 +274,12 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = fa * @throws RuntimeException * @throws FileSystemException */ - public function buildCli(string $extra_libs): void + public function buildCli(string $extra_libs, string $envs): void { $shell = shell()->cd(SOURCE_PATH . '/php-src'); - $shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli"); + $shell->exec( + "make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli" + ); if ($this->strip) { $shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php'); } @@ -221,7 +291,7 @@ public function buildCli(string $extra_libs): void * * @throws FileSystemException|RuntimeException */ - public function buildMicro(string $extra_libs): void + public function buildMicro(string $extra_libs, string $envs): void { if ($this->getPHPVersionID() < 80000) { throw new RuntimeException('phpmicro only support PHP >= 8.0!'); @@ -232,7 +302,9 @@ public function buildMicro(string $extra_libs): void } shell()->cd(SOURCE_PATH . '/php-src') - ->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" " . ($this->strip ? 'STRIP="dsymutil -f " ' : '') . 'micro'); + ->exec( + "make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" " . ($this->strip ? 'STRIP="dsymutil -f " ' : '') . 'micro' + ); $this->deployBinary(BUILD_TARGET_MICRO); } @@ -242,10 +314,12 @@ public function buildMicro(string $extra_libs): void * @throws RuntimeException * @throws FileSystemException */ - public function buildFpm(string $extra_libs): void + public function buildFpm(string $extra_libs, string $envs): void { $shell = shell()->cd(SOURCE_PATH . '/php-src'); - $shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" fpm"); + $shell->exec( + "make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" fpm" + ); if ($this->strip) { $shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm'); } diff --git a/src/SPC/builder/macos/library/freetype.php b/src/SPC/builder/macos/library/freetype.php index ee1600ec1..5cb3d33b3 100644 --- a/src/SPC/builder/macos/library/freetype.php +++ b/src/SPC/builder/macos/library/freetype.php @@ -4,9 +4,6 @@ namespace SPC\builder\macos\library; -/** - * is a template library class for unix - */ class freetype extends MacOSLibraryBase { use \SPC\builder\unix\library\freetype; diff --git a/src/SPC/builder/macos/library/libgif.php b/src/SPC/builder/macos/library/libgif.php new file mode 100644 index 000000000..bf852e32d --- /dev/null +++ b/src/SPC/builder/macos/library/libgif.php @@ -0,0 +1,36 @@ +cd($this->source_dir) + ->exec( + <<<'EOF' + if [[ -f libgif.a ]] + then + make clean + fi +EOF + ); + shell()->cd($this->source_dir) + ->exec(" {$this->builder->configure_env} make -j {$this->builder->concurrency} libgif.a") + ->exec("cp libgif.a {$destdir}/lib/libgif.a") + ->exec("cp gif_lib.h {$destdir}/include/gif_lib.h"); + } +} diff --git a/src/SPC/builder/macos/library/libpng.php b/src/SPC/builder/macos/library/libpng.php index 76a0645e1..1446ecd42 100644 --- a/src/SPC/builder/macos/library/libpng.php +++ b/src/SPC/builder/macos/library/libpng.php @@ -28,8 +28,8 @@ class libpng extends MacOSLibraryBase public const NAME = 'libpng'; /** - * @throws FileSystemException * @throws RuntimeException + * @throws FileSystemException */ protected function build() { @@ -50,7 +50,9 @@ protected function build() '--prefix=' ) ->exec('make clean') - ->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la") + ->exec( + "make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la" + ) ->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH) ->cd(BUILD_LIB_PATH) ->exec('ln -sf libpng16.a libpng.a'); diff --git a/src/SPC/builder/macos/library/libwebp.php b/src/SPC/builder/macos/library/libwebp.php index 1b2a2ee8c..5b8a43fa7 100644 --- a/src/SPC/builder/macos/library/libwebp.php +++ b/src/SPC/builder/macos/library/libwebp.php @@ -1,20 +1,4 @@ - * - * lwmbs is licensed under Mulan PSL v2. You can use this - * software according to the terms and conditions of the - * Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, - * WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * - * See the Mulan PSL v2 for more details. - */ declare(strict_types=1); diff --git a/src/SPC/builder/macos/library/nghttp2.php b/src/SPC/builder/macos/library/nghttp2.php index 62518c241..3aa0ab2f0 100644 --- a/src/SPC/builder/macos/library/nghttp2.php +++ b/src/SPC/builder/macos/library/nghttp2.php @@ -42,7 +42,7 @@ protected function build() 'cunit' => null, ]); - [,,$destdir] = SEPARATED_PATH; + [, , $destdir] = SEPARATED_PATH; shell()->cd($this->source_dir) ->exec( diff --git a/src/SPC/builder/macos/library/openssl.php b/src/SPC/builder/macos/library/openssl.php index 7349e9ee5..b8d682f4e 100644 --- a/src/SPC/builder/macos/library/openssl.php +++ b/src/SPC/builder/macos/library/openssl.php @@ -26,7 +26,7 @@ class openssl extends MacOSLibraryBase protected function build() { - [$lib,,$destdir] = SEPARATED_PATH; + [$lib, , $destdir] = SEPARATED_PATH; // lib:zlib $extra = ''; diff --git a/src/SPC/builder/traits/UnixBuilderTrait.php b/src/SPC/builder/traits/UnixBuilderTrait.php index 49b952d0c..04dc6f2f9 100644 --- a/src/SPC/builder/traits/UnixBuilderTrait.php +++ b/src/SPC/builder/traits/UnixBuilderTrait.php @@ -20,6 +20,8 @@ trait UnixBuilderTrait /** @var string C++ 编译器命令 */ public string $cxx; + public string $ld; + /** @var string cflags 参数 */ public string $arch_c_flags; @@ -57,15 +59,12 @@ public function getAllStaticLibFiles(): array } /** - * Sanity check after build complete - * * @throws RuntimeException */ - public function sanityCheck(int $build_target): void + public function sanityCheck(int $build_micro_rule): void { - // sanity check for php-cli - if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { - logger()->info('running cli sanity check'); + logger()->info('running sanity check'); + if ($build_micro_rule == BUILD_TARGET_CLI) { [$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"'); if ($ret !== 0 || trim(implode('', $output)) !== 'hello') { throw new RuntimeException('cli failed sanity check'); @@ -84,9 +83,7 @@ public function sanityCheck(int $build_target): void } } } - - // sanity check for phpmicro - if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) { + if ($build_micro_rule == BUILD_TARGET_MICRO) { if (file_exists(SOURCE_PATH . '/hello.exe')) { @unlink(SOURCE_PATH . '/hello.exe'); } @@ -115,10 +112,9 @@ public function deployBinary(int $type): bool $src = match ($type) { BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php', BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx', - BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm', default => throw new RuntimeException('Deployment does not accept type ' . $type), }; - logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file'); + logger()->info('Deploying ' . ($type === BUILD_TARGET_CLI ? 'cli' : 'micro') . ' file'); FileSystem::createDir(BUILD_ROOT_PATH . '/bin'); shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/')); return true; diff --git a/src/SPC/util/UnixShell.php b/src/SPC/util/UnixShell.php index 565182eac..7ed998eea 100644 --- a/src/SPC/util/UnixShell.php +++ b/src/SPC/util/UnixShell.php @@ -36,11 +36,14 @@ public function exec(string $cmd): UnixShell /* @phpstan-ignore-next-line */ logger()->info(ConsoleColor::yellow('[EXEC] ') . ConsoleColor::green($cmd)); if ($this->cd !== null) { - $cmd = 'cd ' . escapeshellarg($this->cd) . ' && ' . $cmd; + $cmd = 'cd ' . escapeshellarg($this->cd) . PHP_EOL . $cmd; } if (!$this->debug) { $cmd .= ' 1>/dev/null 2>&1'; } + echo PHP_EOL; + echo $cmd; + echo PHP_EOL; f_passthru($cmd); return $this; } diff --git a/src/globals/defines.php b/src/globals/defines.php index fb66869e3..6066df58a 100644 --- a/src/globals/defines.php +++ b/src/globals/defines.php @@ -5,14 +5,15 @@ use ZM\Logger\ConsoleLogger; define('WORKING_DIR', getcwd()); -const ROOT_DIR = __DIR__ . '/../..'; +define('ROOT_DIR', realpath(__DIR__ . '/../..')); // CLI start time define('START_TIME', microtime(true)); -define('BUILD_ROOT_PATH', is_string($a = getenv('BUILD_ROOT_PATH')) ? $a : (WORKING_DIR . '/buildroot')); -define('SOURCE_PATH', is_string($a = getenv('SOURCE_PATH')) ? $a : (WORKING_DIR . '/source')); -define('DOWNLOAD_PATH', is_string($a = getenv('DOWNLOAD_PATH')) ? $a : (WORKING_DIR . '/downloads')); +define('BUILD_ROOT_PATH', is_string($a = getenv('BUILD_ROOT_PATH')) ? $a : (ROOT_DIR . '/buildroot')); +define('SOURCE_PATH', is_string($a = getenv('SOURCE_PATH')) ? $a : (ROOT_DIR . '/source')); +define('DOWNLOAD_PATH', is_string($a = getenv('DOWNLOAD_PATH')) ? $a : (ROOT_DIR . '/downloads')); + define('BUILD_LIB_PATH', is_string($a = getenv('INSTALL_LIB_PATH')) ? $a : (BUILD_ROOT_PATH . '/lib')); const BUILD_DEPS_PATH = BUILD_ROOT_PATH; define('BUILD_INCLUDE_PATH', is_string($a = getenv('INSTALL_INCLUDE_PATH')) ? $a : (BUILD_ROOT_PATH . '/include'));