MacOS10.15编译安装PHP详细手册

这篇文章更多是提醒自己,同时希望对遇到类似问题的人有所帮助。文中基本上把我遇到的问题都罗列出来了,但前后次序各有不同。我是在执行phpize的时候发现的问题,所以先解决MacOS10.15的SIP和根目录写权限的问题,然后再重新编译PHP,安装apache。这篇文章没有解决编译覆盖MacOS内置PHP的问题,我应该会另外写一篇文章解专门说明如何操作。

一、安装phpize的依赖库

执行 phpize 的时候报了以下错误,表明缺少了必要的依赖库:

Configuring for:
PHP Api Version:          20180731
Zend Module Api No:       20180731
Zend Extension Api No:    320180731
Cannot find autoconf. Please check your autoconf installation and the  $PHP_AUTOCONF  environment variable is set correctly and then rerun this script.

这是由于phpize所依赖的autoconf库没有正确安装导致的,按下面的步骤安装依赖的软件即可解决,此处应当注意使用软件的最新版本。也可以通过brew命令进行安装,此时就只要安装autoconf即可。

wget http://ftp.gnu.org/gnu/m4/m4-1.4.9.tar.gz
tar -zvxf m4-1.4.9.tar.gz
cd m4-1.4.9/
./configure 
sudo make && make install

cd ../

wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.62.tar.gz
tar -zvxf autoconf-2.62.tar.gz
cd autoconf-2.62/
./configure 
sudo make && make install

注意:若要卸载使用 make install 命令安装的软件,可以执行 make uninstall 命令进行卸载。但由于需要读取原始 ./configure信息,因此必须在源码目录中进行操作,因此建议保留原始的源码目录以便必要时使用。

二、安装Homebrew

当需要在MacOS上安装各种扩展的时候,推荐使用Homebrew,Homebrew是MacOS上的命令行模式下的软件管理工具,与Fedora操作系统上的dnf命令类似。Homebrew 的安装非常简单,在安装前,需要确认XCode或者Command Line Tools for Xcode是否安装,但我并不使用Xcode这个庞然大物来编码,所以只需安装 Command Line Tools for Xcode 即可,在终端键入以下代码完成安装:

xcode-select --install

在终端执行下面的命令进行安装(注意不要有换行):

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install"

但是,这条命令执行时下载的速度非常慢,此时可以下载这个bash命令文件,修改里面的软件源的位置为国内的软件源,以提高下载速度,详细过程如下:

下载官网提供的安装脚本,保存为本地brew_install文件:

curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install >> brew_install

打开brew_install文件,更改脚本中的资源链接为清华大学的镜像,修改语句:

BREW_REPO = "https://github.com/Homebrew/brew".freeze

为:

BREW_REPO = "https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git".freeze

当然也可以换成别的软件源,修改之后执行:

/usr/bin/ruby brew_install

安装成功之后执行下面的命令检查是否安装成功:

brew -v

成功安装brew之后,对于phpize所依赖的autoconf软件库就无需通过编译源码的方式安装,只要通过下面的命令即可完成安装:

sudo brew install autoconf

例如在对php执行configure命令时,发现缺少zlib库,则可以通过下面的命令安装zlib库,安装成功后再次执行configure命令:

brew install zlib

注:上面安装autoconf的命令执行依然很慢,可为brew添加清华大学镜像源:

echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' >> 
~/.bash_profile
source ~/.bash_profile

下面列出brew命令的常见用法 

用brew命令搜索软件:

brew search autoconf

 用brew安装软件

brew install autoconf

查看软件信息

brew info autoconf

更新某一软件

brew upgrade autoconf

卸载软件

brew remove autoconf

删除程序,和upgrade一样,单个软件删除和所有程序删除

brew cleanup autoconf
brew cleanup

查看哪些软件可以升级

brew outdated

查看已经安装的软件列表

brew list

三、升级到OSX10.15后phpize找不到php.h文件

当系统升级到OSX10.15后,再次在php的某个ext扩展目录中执行phpize命令时,会发生找不到php.h头文件的错误,详细错误信息如下:

grep: /usr/include/php/main/php.h: No such file or directory
grep: /usr/include/php/Zend/zend_modules.h: No such file or directory
grep: /usr/include/php/Zend/zend_extensions.h: No such file or directory
Configuring for:
PHP Api Version:
Zend Module Api No:
Zend Extension Api No: 

出现这个错误的原因是Apple用SIP提高了系统安全性,禁止用户(包括su用户)操作如/usr目录的系统目录。又因反对/usr/include与sdk不同移除了/usr/include目录,所以无法直接在/usr目录下创建include目录或软连接。并且OSX10.15没有像OSX10.14一样提供头文件安装包,即使执行下面的命令:

xcode-select --install

安装了Xcode command line tools的情况下,依然没有/usr/include目录,还是无法使用phpize命令。且由于缺少头文件安装包,以下命令也无法正确执行:

cd /Library/Developer/CommandLineTools/Packages/
open macOS_SDK_headers_for_macOS_10.14.pkg

最终的解决办法是进入恢复模式禁用SIP,修改系统目录的写入权限,在/usr目录建立include的软连接,指向Xcode command line tools内的usr/include目录,这里要注意指向与操作系统匹配的MacOS.sdk版本。具体操作如下:

重启电脑按下Command+R,点亮屏幕后就开始按,直到出现苹果标志。进入恢复模式后,依次选择菜单栏上的“实用工具” => “终端”,打开终端界面,执行:

csrutil disable

执行后会输出:

Successfully disabled System Integrity Protection. Please restart the machine for the changes to take effect.

重启系统进入正常模式,执行下面的命令确认SIP已成功禁用:

csrutil status
System Integrity Protection status: disabled.

禁用SIP后,使用下面的命令,修改根目录的写入权限:

sudo mount -uw /

此时/usr目录已经有了写入权限,上面的修改命令仅在本次重新启动之前有效,重启之后会回到只读模式,除非再次执行该命令。

根目录有了写入权限后,就能在/usr目录下建立include的软件连接,但是需要注意从MacOS-10.15开始,MacOS.sdk在/Library/Developer/CommandLineTools/ SDKs/目录中,因此需要使用下面的命令建立软连接(以下为一行代码,没有回车):

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ /usr

成功创建软连接后,继续在php源码/ext目录下的某个扩展目录中执行phpize命令就能看到正确的信息,执行结果如下:

phpize
Configuring for:
PHP Api Version:         20180731
Zend Module Api No:      20180731
Zend Extension Api No:   320180731

此时为MacOS内置的PHP安装扩展就没有问题了,但我仍然计划下载一份PHP源码,手动编译安装!下载源码,并解压保存在/usr/local/src/php-7.3.8目录,然后开始编译。

四、编译PHP7.3.8

编译的重点是设置编译参数,这里参考了一份7.2的编译参数,再结合MacOS内置PHP的编译参数,修改出一份集成了freetype的编译参数:

这是用于参考的PHP7.2编译参数:

./configure --prefix=/usr/local/php/7.2 \
--with-config-file-path=/usr/local/etc/php/7.2 \
--with-config-file-scan-dir=/usr/local/etc/php/7.2/conf.d \
--enable-fpm \
--with-fpm-user=www \
--with-fpm-group=www \
--with-mysqli \
--with-pdo-mysql \
--with-iconv-dir=/usr/local \
--enable-short-tags \
--with-zlib \
--with-libxml-dir=/usr/bin/xml2-config \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-sysvsem \
--enable-inline-optimization \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--with-mcrypt-dir=/usr/local/Cellar/mcrypt/2.6.8/ \
--with-gd \
--with-openssl=/usr/local/opt/openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-zip \
--enable-soap \
--without-pear \
--disable-fileinfo \
--enable-maintainer-zts \
--enable-mysqlnd \
--with-freetype-dir=/usr/local/Cellar/freetype/2.9.1/

这是MacOS内置PHP7.3.8的编译参数:

./configure --prefix=/usr \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--disable-dependency-tracking \
--sysconfdir=/private/etc \
--with-libdir=lib \
--enable-cli \
--with-iconv=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-config-file-path=/etc \
--with-libxml-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-openssl=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr/local/libressl \
--with-kerberos=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-zlib=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-bcmath \
--with-bz2=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-calendar \
--disable-cgi \
--with-curl=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-dba \
--with-ndbm=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-exif \
--enable-fpm \
--enable-ftp \
--with-gd \
--with-freetype \
--with-png \
--with-jpeg \
--enable-gd-native-ttf \
--with-icu-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-ldap=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-ldap-sasl=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-libedit=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-mbstring \
--enable-mbregex \
--with-mysqli=mysqlnd \
--without-pcre-jit \
--with-pdo-pgsql=/Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.15.xctoolchain/usr/local/bin \
--with-pgsql=/Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.15.xctoolchain/usr/local/bin \
--without-pear \
--with-pear=no \
--with-pdo-mysql=mysqlnd \
--with-mysql-sock=/var/mysql/mysql.sock \
--disable-phpdbg \
--with-readline=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-shmop \
--with-snmp=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-soap \
--enable-sockets \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--with-tidy=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--enable-wddx \
--with-xmlrpc \
--with-iconv-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-xsl=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/usr \
--with-apxs2=/Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.15.xctoolchain/usr/local/bin/apxs \
YACC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/bison

经过多次尝试,包括进入恢复模式用SIP,都未能覆盖内置PHP,只能将PHP编译安装到其他目录,调整后的编译参数为:

./configure --prefix=/usr/local/php-7.3.8 \
--with-apxs2=/usr/local/opt/apache2/bin/apxs \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--sysconfdir=/private/etc \
--with-libdir=lib \
--enable-cli \
--with-config-file-path=/etc \
--with-libxml-dir=/usr/bin/xml2-config \
--with-openssl=/usr/local/opt/openssl \
--with-zlib=/usr/local/opt/zlib \
--enable-bcmath \
--enable-calendar \
--disable-cgi \
--with-curl=/usr/local/opt/curl \
--enable-dba \
--enable-exif \
--enable-fpm \
--enable-ftp \
--with-gd \
--with-freetype-dir=/usr/local/opt/freetype \
--with-png-dir=/usr/local/opt/libpng \
--with-jpeg-dir=/usr/local/opt/libjpeg \
--enable-mbstring \
--enable-mbregex \
--with-mysqli=mysqlnd \
--without-pcre-jit \
--without-pear \
--with-pear=no \
--with-pdo-mysql=mysqlnd \
--with-mysql-sock=/var/mysql/mysql.sock \
--disable-phpdbg \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--enable-wddx \
--with-xmlrpc \
--with-iconv=/usr/local/opt/libiconv

若在执行configure命令过程中出现缺库问题,可以通过brew命令进行安装,brew命令的详细使用方法参考二部分。

执行make命令编译PHP源码时,发生以下错误,错误消息:

Undefined symbols for architecture x86_64

发生这个错误的原因是不能使用系统自动生成的 -liconv 扩展库,须使用brew安装的扩展库。用brew安装扩展库时,会同时在/usr/local/opt目录中创建软连接到对应的安装目录,因此只要把PHP源码目录中由configure由命令生成的Makefile文件里面所有的 -liconv 都替换为以下内容即可:

/usr/local/opt/libiconv/lib/libiconv.dylib

替换之后的扩展库参数设置类似于:

EXTRA_LIBS = -lcrypto -lssl -lcrypto -lresolv -lpng -lz -ljpeg -lcrypto -lssl -lcrypto -lz -lcrypto -lssl -lcrypto -lm -lxml2 -lz -licucore -lm -lcurl -lldap -lz -lxml2 -lz -licucore -lm -lfreetype -lxml2 -lz -licucore -lm -lxml2 -lz -licucore -lm -lxml2 -lz -licucore -lm -lxml2 -lz -licucore -lm -lxml2 -lz -licucore -lm -lxml2 -lz -licucore -lm -lxml2 -lz -licucore -lm /usr/local/opt/libiconv/lib/libiconv.dylib

类似地,如果编译时OpenSSL扩展库出现问题,也可以用这个方法替换,只是替换的库对应地改为:-lcrypto和 -lssl。

再次执行编译前建议先清理然后编译(注意:上面的编译选项中多了--with-apxs2选项,实际上无法顺利完成编译,具体原因请继续向下阅读):

make clean
make

顺利通过编译后使用下面的命令完成安装:

sudo make install

若要停止运行PHP,可执行以下的命令:

ps -eaf |grep "php-fpm" | grep -v "grep"| awk '{print $2}'|xargs kill -9

五、编译PHP的libphp7.so文件

上面的编译选项无法通过编译是由于系统中没有apxs,无法配置--with-apxs2选项,也就无法生成so文件,因此要执行下面的命令重新安装apache2:

brew install apache2

brew把所有关于apache的依赖软件都安装了一套,这样我的电脑上就有了两套httpd服务软件,但是配置的监听端口不同,可同时启动运行。受到brew设置环境变量的影响,现在如果直接使用apachectl重启或停止服务,对应的命令已经不是默认内置的httpd服务,而变成了刚刚由brew安装的httpd服务。which命令执行结果:

which apachectl
/usr/local/bin/apachectl

而系统自带的httpd服务命令应该位于:

/usr/sbin/apachectl

这是在/etc/paths环境变量配置文件中目录配顺序和apachectl名称冲突而导致的结果。/etc/paths配置文件的内容为:

/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

这里简单地把/usr/loacl/bin目录中的apachectl重命名为apachectl2,这样就避免了冲突。可执行以下命令停用新安装的httpd服务:

sudo apachectl2 stop

新安装的这个apache2仅用于编译生成libphp7.so文件,继续沿用MacOS自带的httpd提供Web服务。

安装apache2后,在/usr/local/opt/apache2/bin目录内已经有了apxs程序,此时增加--with-apxs2编译选项,再次执行make命令编译php-7.3.8后,会在apxs程序对应的httpd的lib/httpd/modules目录中生成libphp7.so文件。

另外,libphp7.so文件在php-7.3.8(源码)/libs目录中有一份副本,php可执行程序在php-7.3.8(源码)/sapi/cli目录中有一份副本。

最后使用如下命令修改httpd的配置文件:

sudo vi /etc/apache2/httpd.conf

修改引用libphp7.so文件的位置,注释原始版本,使用刚刚编译生成的版本:

#LoadModule php7_module libexec/apache2/libphp7.so
LoadModule php7_module /usr/local/lib/httpd/modules/libphp7.so

六、写在最后

升级到最新的MacOS-10.15.1后发现,系统内置的PHP也已经升级到PHP-7.3.9,但是GD库依然不支持freetype,因此在MacOS上另外再安装一套PHP在所难免。

同时也发现MacOS系统封闭非常严重,从10.11开始变得越来越严重,尽管Apple称这是为了系统安全,避免/usr/include与sdk不一致,但是对于开发者来说,系统几乎没有提供多少可直接使用的第三方开发工具,只要不是Apple提供的,几乎都要重新安装。实际上这些内置开发工具,不如没有来的简单。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章