【说明】
在ARM64环境安装一个包的思路有两个:
第一,安装现有的rpm包
第二,下载源码在本地环境编译,安装编译后的rpm包
【方法一】
我们先尝试第一种方法,安装现有的rpm包。如下
发现需要升级基础包glibc,一般需要升级glibc的话不建议再往下执行了。换第二种方法。
【方案二】
下载源码包tesseract-4.1.0~git3915-1.1.src.rpm
Wget https://download.opensuse.org/repositories/home:/Alexander_Pozdnyakov/CentOS_7/src/tesseract-4.1.0~git3915-1.1.src.rpm
说明,之所以没有从github上直接取源码,是因为该包在github上没有对应版本的spec文件。而opensuse工程直接有配套的可用的源码和spec。
安装源码包,rpm -ivh tesseract-4.1.0~git3915-1.1.src.rpm
进到编译目录,cd /root/rpmbuild/SPECS/
开始编译,rpmbuild -ba tesseract.spec
出现下面的编译依赖问题
说明,如果依赖包是xxx-devel,那一定要安装对应的xxx包,因为devel包依赖主包。
先尝试使用yum安装上面的依赖。
Yum install xxxx
六个包没有一个可以用yum安装的。
那就从http://rpmfind.net网站查找是否有包了。
如上图,1的位置输入包名称leptonica,2的位置输入架构aarch64
找到了,我一般下载满足条件的最低版本的rpm包,因为低版本依赖包的版本也较低,如果依赖环境上的基础包,那当前环境满足的可能性更大。
下载leptonica-1.72-2.el7.aarch64.rpm,leptonica-devel-1.72-2.el7.aarch64.rpm包,注意,两个包的版本要求一致!
wget http://rpmfind.net/linux/epel/7/aarch64/Packages/l/leptonica-1.72-2.el7.aarch64.rpm
Wget http://rpmfind.net/linux/epel/7/aarch64/Packages/l/leptonica-devel-1.72-2.el7.aarch64.rpm
安装leptonica-1.72-2.el7.aarch64.rpm包,
rpm -ivh leptonica-1.72-2.el7.aarch64.rpm
如上报错信息,存在so文件依赖。
从rpmfind网站获取libwebp-0.6.1-8.fc28.aarch64.rpm包,安装解决上述so文件依赖。
wget http://rpmfind.net/linux/fedora/linux/releases/28/Everything/aarch64/os/Packages/l/libwebp-0.6.1-8.fc28.aarch64.rpm
先不要安装,先查看rpm包中so文件的版本是否匹配
rpm -qlp libwebp-0.6.1-8.fc28.aarch64.rpm
上图看到libwebp.so.7与依赖的libwebp.so.4版本不一致。说明这个包不可用。该rpm包是rpmfind网站最低版本的了。那就从其它地方找更低版本的libwebp包来安装。
下载libwebp包的源码包
Wget https://download.opensuse.org/repositories/home:/Alexander_Pozdnyakov/RHEL_7/src/libwebp-0.3.0-7.1.src.rpm
安装编译,编译过程报错,依赖太多基础包,比如libjb
查看昨天安装tesseract-3.004.00版本的环境,rpm -qf /usr/lib64/libwebp.so.4
查询到libwebp.so.4所属的rpm包版本信息,
尝试从华为镜像下载该rpm包。
Wget https://mirrors.huaweicloud.com/euler/2.3/os/aarch64/Packages/libwebp-0.3.0-5.aarch64.rpm
安装,成功。
安装leptonica及leptonica-devel包。
再重新尝试编译tesseract源码,出现了下面./configure阶段的报错
Configure对leptonica包的版本有依赖。
卸载已经安装好的leptonica及leptonica-devel包。重新下载高版本rpm安装。
下载leptonica-1.75.3-2.fc28.aarch64.rpm和leptonica-1.78.0-1.fc30.aarch64.rpm
安装时出现下面的报错
基础包的升级依赖。此时,这条路又走不通了。
下载leptonica的源码来编译吧。
Wget
编译tesseract源码,出现下面的报错:
宏没有定义。到github Issue去查找,有一样的问题。是centos环境的libicu版本低于52.需要升级。
下载libicu安装包,安装,出现下面的报错信息
Libstdc.so.6(CXXABI_1.3.8) is needed by libicuxxx.rpm
使用strings /usr/lib64/libstdc++.so.6 | grep CXXABI查看当前环境的CXXABI版本信息
果真只到1.3.6,没有1.3.8.那我们就需要安装更高版本的libstdc++包了。
Wget http://rpmfind.net/linux/fedora/linux/releases/28/Everything/aarch64/os/Packages/l/libstdc++-8.0.1-0.20.fc28.aarch64.rpm
rpm -ivh libstdc++-8.0.1-0.20.fc28.aarch64.rpm
报错,libstdc++.so.6文件与低版本的libstdc++冲突,此类冲突可以通过先卸载低版本,再安装高版本包解决。也可以直接--force安装。
安装好libstdc++版本后,再安装libicu包。
开始编译tesseract源码吧。但愿这次没有问题了
还是出错了。
/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libicui18n.so: undefined reference to `__cxa_throw_bad_array_new_length@CXXABI_1.3.8'
查看错误,明显是libicui18n.so文件错误。那我们使用指定so路径的方式。-L/usr/lib64/libicui18n.so
vi src/training/Makefile
修改 -licui18n和-licuuc为-L/usr/lib64/libicui18n.so和-L/usr/lib64/libicuuc.so
重新编译,上述问题解决。
然而出现了新的问题,如下:
[root@arm-app-0003 training]# g++ -g -O2 -std=c++11 -o .libs/combine_lang_model combine_lang_model.o ./.libs/libtesseract_training.a ./.libs/libtesseract_tessopt.a -L/usr/lib64/libicui18n -L/usr/lib64/libicuuc -licudata ../api/.libs/libtesseract.so -llept -lpthread -fopenmp -Wl,-rpath -Wl,//lib -DCMAKE_EXE_LINKER_FLAGS=’-static-libstdc++’
./.libs/libtesseract_training.a(unicharset_training_utils.o): In function `tesseract::SetupBasicProperties(bool, bool, UNICHARSET*)':
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:64: undefined reference to `u_isalpha_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:65: undefined reference to `u_islower_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:66: undefined reference to `u_isupper_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:67: undefined reference to `u_isdigit_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:68: undefined reference to `u_ispunct_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:79: undefined reference to `uscript_getScript_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:79: undefined reference to `uscript_getName_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:108: undefined reference to `u_charMirror_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:92: undefined reference to `u_toupper_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:92: undefined reference to `u_tolower_60'
/root/small7/tesseract-4/tesseract_4.0.0/src/training/unicharset_training_utils.cpp:112: undefined reference to `u_charDirection_60'
./.libs/libtesseract_training.a(icuerrorcode.o): In function `tesseract::IcuErrorCode::~IcuErrorCode()':
/root/small7/tesseract-4/tesseract_4.0.0/src/training/icuerrorcode.cpp:22: undefined reference to `icu_60::ErrorCode::~ErrorCode()'
./.libs/libtesseract_training.a(icuerrorcode.o): In function `tesseract::IcuErrorCode::~IcuErrorCode()':
/root/small7/tesseract-4/tesseract_4.0.0/src/training/icuerrorcode.cpp:26: undefined reference to `icu_60::UMemory::operator delete(void*)'
./.libs/libtesseract_training.a(icuerrorcode.o): In function `tesseract::IcuErrorCode::handleFailure() const':
/root/small7/tesseract-4/tesseract_4.0.0/src/training/icuerrorcode.h:52: undefined reference to `icu_60::ErrorCode::errorName() const'
好多的错误呀!
我们第一步先去找第一个undefined函数是哪个文件和so里面定义的。
不断总结输出是程序员必备成长技能。如何写的更清醒,欢迎来007不出局一起践行写作*^_^*