从 Homebrew 失败到源码编译成功:PHP 8.2 安装全记录

从 Homebrew 失败到源码编译成功:PHP 8.2 安装全记录

补档说明
这篇记录的是我为了搭建 Codex 本地调试环境,在 macOS 13 上折腾 PHP 8.2 的完整过程。写于环境搭建完成后。

时隔十几年,我重新在 Mac 上编译了一次 PHP。

上一次干这事,还是 2008 年。那时候用的是 Windows,装的是 LAMP 组合安装包,点几下按钮就完事了。

这次不一样,我是为了能给Codex 搭一个本地调试环境,这样可以逃脱“Codex 写代码→‌我review→‌传服务器→‌访问发现报错→‌我复制给codex→‌反复循环”的牛马流程,让Codex有调试能力,但我从来没想过在一台老 Mac(macOS 13 Ventura,Intel 芯片)上装 PHP 8.2 居然能耗时这么久。

本来觉得挺简单的事:Homebrew 一行命令搞定,结果我折腾了一天一夜。


从头说起。

第一次尝试:brew install php@8.2

我打开终端,输入了那条熟悉的命令:

bash

brew install php@8.2

然后卡住了。

text

curl: (6) Could not resolve host: github.com
curl: (6) Could not resolve host: ghcr.io

网络问题。Homebrew 默认从 GitHub 和 ghcr.io 下载包,我在国内连过去要么慢到超时,要么直接连不上。

不过别慌,这不是新问题了,我早有准备。

第二次尝试:换国内镜像

我先后试了中科大和清华的镜像:

bash

export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles

部分包确实走镜像了,但还是有相当一部分回退到 ghcr.io。而且,即便网络问题解决了,brew install 还是失败了。

text

Error: Failed to download resource "libpq"
Build failure was expected, as this is not a Tier 1 configuration

我去查了一下,才知道 Homebrew 把系统支持分成三个等级。Tier 1 有预编译包,Tier 2 可能没有,Tier 3 官方不管。macOS 13 恰好是 Tier 3。

也就是说,Homebrew 明确告诉我:这个系统版本我们不支持了。

那好吧,自己编译。

第三次尝试:源码编译

bash

brew install php@8.2 --build-from-source --ignore-dependencies

这次确实开始编译了,但第一个依赖就挂了——libpq,PostgreSQL 的客户端库,编译文档时出错。

text

make[2]: *** [postgres-full.xml] Error 1
legal.sgml: parser error : Entity 'copy' not defined

折腾了一番后,我找到了解决方案:进入调试模式,用 --disable-docs 跳过文档生成。接着又陆续遇到了一系列问题:llvm 补丁缺失、oniguruma 找不到、libiconv 链接失败……每解决一个,下一个就在等着你。

这些问题的细节不展开了,我直接说最后怎么成功的。

最终方案:手动源码编译

核心是用 Homebrew 的 --debug 模式进入 shell,然后自己执行 configure、make、make install。

bash

brew install php@8.2 --build-from-source --ignore-dependencies --debug

当出现“Choose an action”时,输入 5 进入 shell。

然后手动设置环境变量,指定编译参数,执行编译:

bash

export PATH="/usr/local/Cellar/autoconf/2.73/bin:$PATH"
export PKG_CONFIG_PATH="/usr/local/Cellar/openssl@3/3.6.3/lib/pkgconfig:/usr/local/Cellar/oniguruma/6.9.10/lib/pkgconfig:$PKG_CONFIG_PATH"

./buildconf --force

./configure --prefix=/usr/local/Cellar/php@8.2/8.2.33 \
            --with-config-file-path=/usr/local/etc/php/8.2 \
            --enable-mbstring \
            --enable-bcmath \
            --enable-pcntl \
            --enable-ftp \
            --enable-exif \
            --enable-calendar \
            --enable-sockets \
            --enable-soap \
            --with-openssl \
            --with-curl \
            --with-mysqli=mysqlnd \
            --with-pdo-mysql=mysqlnd \
            --without-iconv

make -j$(sysctl -n hw.ncpu)
sudo make install

跑完最后一个命令的时候,已经是第二天下午了。

验证一下:

bash

php -v
# PHP 8.2.33 (cli) (built: ***) (NTS)

苍天啊,终于能用了。


回头看看,这事给我留下几个印象很深的东西:

第一,Homebrew 的 Tier 策略是个硬约束。 macOS 13 是 Tier 3,这意味着官方不会给你提供预编译包,也不会为你的系统版本做兼容测试。如果系统版本偏旧,不要依赖 Homebrew 的自动安装,源码编译是更可靠的路。

第二,--debug 模式是 Homebrew 留的后门。 它允许你在编译流程中断时进入 shell,手动执行每一步。相当于从“自动挡”切到“手动挡”——你掌握全部控制权。

第三,依赖问题其实有通用解法。 报错告诉你哪个依赖出问题,你确认它是否已安装;如果已安装但找不到,就设置 PKG_CONFIG_PATH;如果安装失败,考虑跳过;如果跳过不了,就在调试模式下手动编译它。一步一步来,不要跳步。

第四,有些扩展不值得死磕。 比如 iconv,我在它上面耗了挺久,最后决定 --without-iconv 跳过。事实上大多数 PHP 应用根本用不到它,为这个拖垮整个环境不值。

最终环境是这样的:

  • PHP 8.2.33,源码编译,装在 /usr/local/Cellar/php@8.2/8.2.33
  • 启用了 mbstring、bcmath、pcntl、openssl、curl、mysqli、pdo_mysql 等 40+ 个扩展
  • 跳过了 iconv
  • Shell 已经切到 zsh,PATH 已配置好

接下来还有几步: 装 MySQL 8.0、装 Composer、调 php.ini、然后跑一个 Laravel 项目验证环境。一步一步来吧。

这次重新编译 PHP,让我想起 2008 年那个用组合安装包点几下按钮的自己——那时候觉得装环境就是点点点,现在才知道每一个依赖背后都是漫长的调试。

一天一夜换一个能跑的 PHP,值不值?对我来说值。至少下次再遇到类似问题,我知道去哪里找答案。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注