Alpine静态编译PHP 8.1.7添加--with-readline时报readline库未找到错误
Alpine Linux静态编译带readline支持的PHP 8.1.7报错解决
问题场景
在最新版Alpine Linux环境中静态编译PHP 8.1.7,无readline支持时使用以下命令可顺利完成编译:
./configure LDFLAGS=-static --disable-all --enable-cli --enable-mbstring --enable-static=yes sed -ie 's/-export-dynamic//g' "Makefile" && \ sed -ie 's/-o $(SAPI_CLI_PATH)/-all-static -o $(SAPI_CLI_PATH)/g' "Makefile" make LDFLAGS="-ldl" -j12 make install
后续需要添加readline支持,先安装readline、ncurses相关的运行时、开发包及静态库,再重新执行configure命令添加--with-readline参数:
apk add readline readline-dev readline-static ncurses-static ncurses-dev ./configure LDFLAGS=-static --disable-all --enable-cli --enable-mbstring --enable-static=yes --with-readline
执行configure配置阶段直接报错中断:
checking for libedit readline replacement... no checking for readline support... yes checking for tgetent in -lncurses... no checking for tgetent in -ltermcap... no checking for readline in -lreadline... no configure: error: readline library not found
查看config.log对应报错片段,核心错误有两个:
- 链接阶段提示
cannot find -lncurses、cannot find -ltermcap - 尝试链接
libreadline.a时出现大量tputs符号未定义错误
configure:84994: checking for tgetent in -lncurses configure:85017: cc -o conftest -g -O2 -fvisibility=hidden -static conftest.c -lncurses -lrt -lm >&5 /usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lncurses collect2: error: ld returned 1 exit status configure:85027: result: no configure:85059: checking for tgetent in -ltermcap configure:85082: cc -o conftest -g -O2 -fvisibility=hidden -static conftest.c -ltermcap -lrt -lm >&5 /usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -ltermcap collect2: error: ld returned 1 exit status configure:85092: result: no configure:85235: checking for readline in -lreadline configure:85258: cc -o conftest -g -O2 -fvisibility=hidden -Wl,-rpath,/usr/local/lib -L/usr/local/lib -static conftest.c -lreadline -lrt -lm >&5 /usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/local/lib/libreadline.a(display.o): in function `_rl_move_cursor_relative': /root/static-php-cli/docker/source/readline-8.1/display.c:2805: undefined reference to `tputs' /usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/local/lib/libreadline.a(display.o): in function `_rl_move_vert': /root/static-php-cli/docker/source/readline-8.1/display.c:2857: undefined reference to `tputs' /usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/local/lib/libreadline.a(terminal.o):/root/static-php-cli/docker/source/readline-8.1/terminal.c:764: more undefined references to `tputs' follow collect2: error: ld returned 1 exit status configure:85268: result: no configure:85381: error: readline library not found
故障根因
- Alpine官方源的ncurses静态包默认只提供宽字符版本的静态库
libncursesw.a,没有生成libncurses.a、libtermcap.a的兼容软链,导致configure默认查找规则匹配不到库文件 - 静态链接对库的顺序有严格要求,被依赖的库必须放在依赖它的库后面,PHP的configure脚本检测readline时默认不会主动追加ncurses链接参数,导致readline依赖的终端控制符号找不到
解决步骤
- 创建ncurses库兼容软链,匹配configure的默认查找规则
ln -sf /usr/lib/libncursesw.a /usr/lib/libncurses.a ln -sf /usr/lib/libncursesw.a /usr/lib/libtermcap.a
- 清空之前编译生成的缓存文件,重新执行configure,显式追加ncurses链接参数
make clean rm -f config.cache ./configure LDFLAGS="-static -L/usr/local/lib -L/usr/lib" \ --disable-all --enable-cli --enable-mbstring --enable-static=yes \ --with-readline LIBS="-lncurses"
- configure执行通过后,修改Makefile移除动态链接参数,同时修正静态链接的库顺序
sed -ie 's/-export-dynamic//g' "Makefile" && \ sed -ie 's/-o $(SAPI_CLI_PATH)/-all-static -o $(SAPI_CLI_PATH)/g' "Makefile" && \ sed -ie 's/-lreadline/-lreadline -lncurses/g' "Makefile"
- 执行编译安装
make LDFLAGS="-ldl -lncurses" -j$(nproc) make install
结果验证
- 执行
php -m | grep readline,输出readline即模块加载正常 - 执行
ldd $(which php),输出not a dynamic executable即确认为静态编译版本
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

