博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
静态编译expect以及大坑
阅读量:6447 次
发布时间:2019-06-23

本文共 2418 字,大约阅读时间需要 8 分钟。

expect是脚本处理有交互命令的利器,但是这货依赖tcl,并且默认没有安装。为了方便分发到测试服务器上,尝试了下静态编译。结果以失败告终。下面是整个编译的过程。

编译tcl静态库

由于expect依赖tcl,必须先编译一个静态版本的tcl库。tcl的源码可以从阿里云镜像下载:

wget http://mirrors.aliyun.com/gentoo/distfiles/tcl-core8.6.4-src.tar.gz

编译的方式和编译普通应用类似,唯一需要注意的是,我们只需要编译出静态库即可。

tar vxf tcl-core8.6.4-src.tar.gz cd tcl8.6.4/unix/./configure --disable-shared --prefix=$HOME/source/targetmakemake install

这里我们直接安装到指定的路径,并且关闭动态链接库的编译。这样在$HOME/source/target里面,就会tcl的静态库。

编译expect

首先还是从镜像下载expect源码。

wget http://mirrors.aliyun.com/gentoo/distfiles/expect5.45.tar.gz

然后运行configure的时候,需要指定tcl的路径,并且关闭动态链接。

tar vxf expect5.45.tar.gz ./configure --with-tcl=$HOME/source/target --disable-sharedmake
这里遇到了很多链接的问题。首先是

expect.c:(.text+0xbc):对‘tclStubsPtr’未定义的引用exp_main_sub.c:(.text+0x6fb):对‘tclIntStubsPtr’未定义的引用tclUnixThrd.c:(.text+0x31):对‘pthread_key_delete’未定义的引用

这些符号无法找到,无法进行链接。向上查找这些错误对应的编译命令,发现已经在链接最终的expect命令了。此时的编译命令为:

gcc      -pipe -O2 -fomit-frame-pointer -Wall       -Wl,--export-dynamic      -o expect exp_main_exp.o     -L/alidata1/6080/source/expect5.45 -lexpect5.45     -L/alidata1/6080/source/target/lib -ltcl8.6     -ldl  -lieee -lm     -Wl,-rpath,/alidata1/6080/source/target/lib     -Wl,-rpath,/alidata1/6080/source/target/lib/expect5.45
查阅了tcl的faq,前面遇到无法链接的符号在tclstub库中,同时还发现少了pthread库的一些符号。加上这些之后,编译命令变成:

gcc      -pipe -O2 -fomit-frame-pointer -Wall       -Wl,--export-dynamic      -o expect exp_main_exp.o     -L/alidata1/6080/source/expect5.45 -lexpect5.45     -L/alidata1/6080/source/target/lib -ltcl8.6     -ldl  -lieee -lm     -Wl,-rpath,/alidata1/6080/source/target/lib     -Wl,-rpath,/alidata1/6080/source/target/lib/expect5.45 -ltclstub8.6 -lpthread
此时tcl和一些基础库的链接失败消失,但是出现了

pty_termios.c:(.text+0x116):对‘openpty’未定义的引用

这个错误。同样需要去查找这个函数实现的库,最终定位到了libutil。

最终将编译命令修改成:

gcc      -pipe -O2 -fomit-frame-pointer -Wall       -Wl,--export-dynamic      -o expect exp_main_exp.o     -L/alidata1/6080/source/expect5.45 -lexpect5.45     -L/alidata1/6080/source/target/lib -ltcl8.6     -ldl  -lieee -lm     -Wl,-rpath,/alidata1/6080/source/target/lib     -Wl,-rpath,/alidata1/6080/source/target/lib/expect5.45 -ltclstub8.6 -lpthread -lutil

终于能够正常编译出静态编译的expect命令了。

就在以为完事大吉的时候,发现这个静态编译的expect命令,虽然已经静态链接了tcl库,但是在其他没有tcl的机器上运行的时候,会提示:

Tcl_Init failed: Can't find a usable init.tcl in the following directories

原来为了支持扩展,tcl会要求初始化的时候执行这个初始化脚本。查阅了tcl的文档,要编译一个完全不依赖机器上tcl库的程序比较麻烦。最终,找到了一个简单的命令来处理命令的交互。

转载自:https://coolex.info/blog/515.html

你可能感兴趣的文章