.NET Core|--调用C++库|--LibraryImport docker环境下,处理依赖问题--GCC--Docker
前言
万恶之源在于, C#程序中需要调用C++的一个函数库,
在Windows环境下, 只要保证引用的相关dll存在, 就是ok的,
但是在Linux环境下, 并且我的Webapi程序是部署在docker中的,
问题就比较麻烦一些.
经历了
新建软链接,
缺失".so"文件,
有了".so"文件后, 版本错误 : libstdc++.so.6: version `GLIBCXX_3.4.29' not found,
环境信息
#SkiaSharp - 版本
2.88.3
#SkiaSharp.NativeAssets.Linux.NoDependencies - 版本
2.88.3
#部署服务器环境
Linux / docker /
#Visual Studio 版本
Microsoft Visual Studio Professional 2022 (64 位)
#C#语言版本
10.0
解决方案
1.先下载一个gcc11的docker镜像( gcc版本按需来下载 )
2.根据gcc11的镜像, 跑起来一个docker容器, 我们称这个容器为"GccNet"
3.在此gcc11的容器中, 安装.net core的SDK,
4.将此"GccNet"容器, 打包为一个镜像"GccNet_Image"
5.以此镜像为基础, 跑起来一个容器即可
#Dockerfile内容如下
# 这个镜像里面既有gcc , 还有.net core环境
FROM GccNet_Image
EXPOSE 80
#环境端口
EXPOSE 5500
WORKDIR /app
COPY . /app
ENTRYPOINT ["dotnet", "WebApi.dll"]
总结
我刚开始的思路就是, 在.Net Core的基础上安装gcc那一套,( 因为调用的那个C++函数库需要用到gcc)
所以路走的很曲折, 各种问题,
后来和同事一起讨论下, 试了下这个方案,
先搞一个gcc的容器, 然后在这个容器里安装.net core的环境,
最终可以了...
附录--软链接
将.so文件放到指定目录之下后, 还是报错,
问了下同事, 是需要软连接
#具体用法是 "ln -s [源文件] [软链接文件]"
ln -s libabc.so.3.3.3 libabc.so
#查看
#ls -l
#修改软链接
#ln –snf [新的源文件或目录] [软链接文件]
#删除软链接
#rm –rf ./软链接名称
#rm -rf ./软链接名称/ (这样就会把软链接以及软链接指向下的内容删除)
#正确的删除方式(删除软链接,但不删除实际数据)
rm -rf ./libabc.so
附录--环境变量
在执行ldd libabc.so
的时候, 发现很多明明存在这个目录下的so文件, "not found",
黄色警告...
后来看了下路径, 发现是需要更改一下环境变量
export LD_LIBRARY_PATH=/app/runtimes/linux-x64/native/
附录--缺少"libgomp.so.1"
#网络上关于这个问题搜索到了很多, 结果直接使用apt-get安装了一下就行了
#如果不更新一下的话,可能会提示失败 : Unable to lcate package libgomp1...
apt-get update
apt-get install libgomp1
刚开始我是进入容器中执行了这个命令,
这就会导致一个问题, 每次重新发布容器的时候, 都需要再重新apt-get一下该包,
然后我就直接在服务器上, 进行这个操作了,
温馨提示 : 如果觉得国外镜像实在慢的, 可以更换镜像为国内的...
#在服务器上执行, 巧了, 我的服务器上还没有apt-get, 服务器上使用了yum命令...
yum install libgomp1
yum
附录--libstdc++.so.6: version `GLIBCXX_3.4.29' not found
#报错信息
./libabc.so: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./libabc.so)
#切换目录到错误目录下
cd /usr/lib/x86_64-linux-gnu/
strings libstdc++.so.6 | grep GLIBCXX
#如果strings命令没有的话, 需要安装一下,
# apt-get install binutils
root@abc:/usr/lib/x86_64-linux-gnu# strings libstdc++.so.6 | grep GLIBCXX_3.4.2
GLIBCXX_3.4.2
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_3.4.26
GLIBCXX_3.4.27
GLIBCXX_3.4.28
#会发现, 确实没有"GLIBCXX_3.4.29"
#升级一下
apt-get install --only-upgrade libstdc++6
#输出内容↓ -- 提示我已经是最新版本 ...
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
libstdc++6 is already the newest version (10.2.1-6).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
#如果不出意外的话, 这就是最后一个问题了吧? -- 这不是最后一个问题...
#在网络上下载了一个29版本的文件, "libstdc++.so.6.0.29"
#删除libstdc++原来的软链接 -- libstdc++.so.6 -> libstdc++.so.6.0.28
rm -rf /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#将下载的版本复制到指定目录下
cp libstdc++.so.6.0.29 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.29
#ln -s [源文件] [链接文件]
ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.29 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#查看libstdc++的文件和软链接
ls -n /usr/lib/x86_64-linux-gnu/ | grep libstdc
docker 容器中安装gcc 11以上的版本
更换apt-get镜像源
#进入Docker容器内查看镜像debian版本
cat /etc/debian_version
#我使用中科大的镜像源作为替换
sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
#查看源
cat /etc/apt/sources.list
#还有一种方式更换镜像源
tee /etc/apt/sources.list << EOF
deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb http://mirrors.aliyun.com/debian-security stretch/updates main
deb-src http://mirrors.aliyun.com/debian-security stretch/updates main
deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
EOF
tee /etc/apt/sources.list << EOF
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe
EOF
附录--将libstdc++.so.6升级到libstdc++.so.6.0.29
#a.下载到文件, libstdc++.so.6.0.29
#b.将下载到的文件拷贝到指定的目录下, 比如"/usr/lib/x86_64-linux-gnu"
#c.切换目录
cd /usr/lib/x86_64-linux-gnu
#d. 备份一下( 有备无患 )
mv ./libstdc++.so.6.0.29 ./libstdc++.so.6.0.bak
#e. 软链接
ln -s libstdc++.so.6.29 libstdc++.so.6
#f. 查看是否软链接建立成功
ls -l libstdc++.so.6
附录--辅助命令 -- strings
#安装strings -- docker环境中默认是没有的
apt-get install binutils
辅助命令 -- ldd
ldd libabc.so
辅助命令 -- find
#查找["libstdc++.so.6.0.29"等...]
find / -name "libstdc++.so.6.0*"
辅助命令 -- ls -lh
ls -lh libstdc++.so.6.0.29
-rw-r--r-- 1 root root 2.1M Aug 17 09:39 libstdc++.so.6.0.29
杂言碎语
#有的时候, 执行的命令有了, 但是你不知道去哪里执行...