前言
上文介绍过使用Tree-sitter进行语言结构分析的前提是生成可以解析你想要解析语言的动态解析库,然后在项目中加载该动态库解析目标源码;其中编译的动态解析库对运行环境很敏感,必须在该动态库使用的运行环境中编译对应的动态库,才能正常运行;
由于我参与项目主要部署在服务器环境上运行,所以本文就以我项目部署的服务器环境为例,讲解详细的编译解析库过程:
编译过程
Docker是一个开源的应用容器引擎,我们可以在Docker中创建容器配置任意的运行环境,具体Docker容器创建流程可以参考Docker官网;我就以搭建我的项目部署的服务器环境为例介绍大致流程和遇到的坑:
起初没意识到编译库对环境非常敏感时,我就直接在Docker中搭建了CentOS的系统,编译出了一个java-tree-sitter解析库;当部署到运行的服务器环境时,就报了下面这个错误:
原因是服务器环境是CentOS 6.9,我在编译so库时系统用了较新版本的 C++运行库,在运行的服务器环境中加载的 C++运行库比较老,所以编译so库时我们需要模拟跟服务器端必须一致的环境。
1.下载CentOS release 6.9并启动docker。
docker pull centos:6.9
第一次运行命令
docker run -it centos:6.9 /bin/bash
后续在docker desktop中点击需要运行的容器
然后执行命令启动名称为condescending_torvalds的容器:
docker exec -it condescending_torvalds bash
2.docker下载安装的centos镜像无法使用yum命令(需要替换yum的源)
- 打开yum的配置文件:
vi /etc/yum.repos.d/CentOS-Base.repo
- 注释掉所有以mirrorlist开头的行,解开所有以baseurl开头的行 修改baseurl,参考示例如下:
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
baseurl=http://mirrors.aliyun.com/centos-vault/6.9/os/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#released updates
[updates]
name=CentOS-$releasever - Updates
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
baseurl=http://mirrors.aliyun.com/centos-vault/6.9/updates/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
baseurl=http://mirrors.aliyun.com/centos-vault/6.9/extras/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
baseurl=http://mirrors.aliyun.com/centos-vault/6.9/centosplus/x86_64/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib&infra=$infra
baseurl=http://mirrors.aliyun.com/centos-vault/6.9/contrib/x86_64/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
~
3.安装gcc
yum update
yum install gcc
gcc --version
4.安装jdk1.8
yum install -y java-1.8.0-openjdk-devel
java -version
配置JDK的环境变量:
不这样配置的话运行python脚本时会报错cc1plus: error: /usr/bin/java/include: Not a directory
查找Java相关文件路径:运行以下命令来查找Java相关文件的路径:
find / -name "jni.h" 2>/dev/null
这将在整个文件系统中搜索名为"jni.h"的文件,并将搜索结果输出。寻找类似/usr/lib/jvm/java-<version>/include/jni.h的路径,这是Java开发环境的包含文件路径。
vi /etc/profile
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.171-8.b10.el6_9.x86_64
export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile
使环境变量生效
5.安装python(默认下载的3.4版本运行有问题,需安装3.6.9版本)
安装必要的软件包,以便构建Python 3.6.9。运行以下命令:
yum install -y wget gcc openssl-devel bzip2-devel libffi-devel
下载Python 3.6.9源代码。运行以下命令:
wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
解压缩源代码并进入目录。运行以下命令:
tar xzf Python-3.6.9.tgz
cd Python-3.6.9
配置和构建Python。运行以下命令:
./configure --enable-optimizations
make -j 8
make altinstall
查找Python 3.6.9的安装位置:
find / -name python3.6
更改Python的符号链接:
ln -sf /usr/local/bin/python3.6 /usr/bin/python
验证Python 3.6.9安装。运行以下命令:
python --version
6.编译so库,可以参考上一篇文章:
git clone https://github.com/serenadeai/java-tree-sitter.git --recursive
or
git clone https://github.com/serenadeai/java-tree-sitter.git
git submodule update --init --recursive
7、将编译好的so库从docker容器中拷贝到本地电脑,即可将该动态库部署到服务器环境:
docker cp linux-mint:/usr/local/java-tree-sitter/libjava-tree-sitter.so {目标路径}
结语
上文只是介绍了我部署服务器环境的具体配置搭建,具体运行环境配置还要以自己解析库所处的运行环境进行容器环境配置;