.NET Core|--调用C++库|--LibraryImport docker环境下,处理依赖问题--GCC--Docker

发布时间 2023-09-27 17:34:29作者: zh89233

前言

万恶之源在于, 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

9ce0598796b266bed90bd8b10ead0a7e.png

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

杂言碎语

#有的时候, 执行的命令有了, 但是你不知道去哪里执行...


摘抄文档