引言:
最近在搭建php web server的各种环境,期间遇到各种各样神奇的问题,也挺有意思的。反正对未知的探索。一个技术工人最大的喜悦莫过于碰到各种各样神奇而又不知所措的问题,然后在不停的折腾、反复尝试之后终于将技术的真相和细节托出水面,见证脱俗而清纯的技术胴体,让她一览无余的躺在你眼前。欣然灵动,超赞!
缘起:
在安装php的扩展opcache的时候,发现 ./configure 命令之后一直有一个check的问题卡在这里:
checking for mmap() using MAP_ANON shared memory support... no
checking for mmap() using /dev/zero shared memory support... no
checking for mmap() using shm_open() shared memory support... no
checking for mmap() using regular file shared memory support... no
checking "whether flock struct is linux ordered"... "no"
checking "whether flock struct is BSD ordered"... "no"
configure: error: Don't know how to define struct flock on this system, set --enable-opcache=no
折腾:
既然不让过,而且是有这个引用又是在check的时候找不到这个so库和头文件。那么问题来了,找so库和头文件哪家强?
对于一个在web的前端的路上走久了人,如何能找到山东蓝翔?而是找呀找。终于发现了一个叫做ld.so.conf 和 LD_LIBRARY_PATH 的东东。这两个是干嘛的?请听小白娓娓道来:
ld.so.conf:这个东东是告诉linux 要怎么样去加载动态so库,这样的话,linux 才能更清楚的找到程序运行的库。
那么问题来了,我上面操作和这个并不冲突,php configure的时候我添加了我新安装的目录路径,为啥还找不到呢?
猜测:这里可能是某个so(假定a.so)在linux的某个路径也存在,在我最新的安装里面也存在,但是php在configure 的时候,由于这个 a.so 的默认路径的原因,导致了configure的是没有到我安装的目录去读取头文件和a.so。
结合上面的提到的 ld.so.conf ,自然想到要把我新安装的软件的目录添加到这个文件下以便让linux能找到。那么问题又来了? 你在添加的时候,还会发现:
test64:/etc # cat ld.so.conf
/usr/X11R6/lib64/Xaw3d
/usr/X11R6/lib64
/usr/X11R6/lib/Xaw3d
/usr/X11R6/lib
/usr/x86_64-suse-linux/lib
/usr/local/lib
/opt/kde3/lib
/opt/gnome/lib
/lib64
/lib
/usr/lib64
/usr/lib
/usr/local/lib64
/opt/kde3/lib64
/opt/gnome/lib64
include /etc/ld.so.conf.d/*.conf
这个文件的下面这个include 很显然是动态的配置方式,能更好的明确的加载so库而不影响d.so.conf 的内容。这个方式很好。打开 ld.so.conf.d 目录,添加我安装路径的文件:
test64:/etc/ld.so.conf.d # ls -lt
total 28
-rw-r--r-- 1 root root 48 Oct 14 19:15 1.ieod-libxslt1.1.2.conf
-rw-r--r-- 1 root root 47 Oct 11 16:13 1.ieod-libxml2.conf
-rw-r--r-- 1 root root 50 Oct 11 16:12 1.ieod-freetds.conf
-rw-r--r-- 1 root root 45 Oct 11 16:11 1.ieod-curl.conf
-rw-r--r-- 1 root root 48 Oct 11 16:10 1.ieod-freetype.conf
-rw-r--r-- 1 root root 48 Oct 11 16:09 1.ieod-openssl.conf
-rw-r--r-- 1 root root 17 Oct 11 15:47 mysql-x86_64.conf
文件的内容就是安装路径,比如
test64:/etc/ld.so.conf.d # cat 1.ieod-libxslt1.1.2.conf
/data/home/xingzheng/install/libxslt-1.1.21/lib
添加完毕,继续configure ,发现问题依然存在。网上找了下,原来要 ldconfig 来更新当前的。继续configure ,问题好了。编译和安装都ok了,欣喜若狂。
未了的噩梦:
一切欣喜的时候,往往是又一个悲剧的开始。
我以为我搞定了所有的问题,搞定php 配置和apache的配置,启动apache,开始我们的web server愉快之旅。但是在启动apache的时候发现:
test64:/data/home/xingzheng/php-5.5.15/apache/bin # ./apachectl start
httpd: Syntax error on line 149 of /data/home/xingzheng/php-5.5.15/apache/conf/httpd.conf: Cannot load modules/libphp5.so into server: /data/home/xingzheng/php-5.5.15/apache/modules/libphp5.so: undefined symbol: xmlTextReaderSetup
依然没有找到新安装的so库,导致libphp5.so加载到apache 中加载失败。当时真是百思不得其姐...搞得我情怀碎一地,差点不相信技术能改变ds的命运了。
而是继续折腾,问题还是要解决的,正如钱是要花的一样。从头开始理清:
1.因为找不so和源文件 导致 configure的时候不通过
2.在ld.so.conf.d 下面添加了 新的路径,ldconfig 后,结果configure 的时候编译通过,找到了。
3.但是动态加载的还是报错找不到?
起码说明 1、2 步是对的。那么为什么3还是有问题呢?是不是1、2只是告诉了路径可以找到,编译通过。但是真正去加载的时候又加载了 默认的目录的a.so呢?这就对了。应该是我配置的路径不能被优先用到,导致加载a.so的时候依然优先使用了默认路径下的a.so。那么怎么来改变这个优先级呢?
直接将新安装的目录加到 ld.so.conf 文件的前面,让linux默认优先使用安装库的路径。
ldconfig 后,到apache的bin,启动apache,启动ok。至此问题解决了。欣喜若狂ing,但即刻又回归了淡定,因为还有很多事情搞...