资讯动态

Ubuntu 16.04 源码编译 OpenVINO 2021.4:避开 GLIBC 版本坑

发布时间:2026/10/19 5:17:45 来源:尧图企业网站定制
如果你手头还有一批跑在 Ubuntu 16.04 上的工控机或服务器又想把推理组件升级到 OpenVINO 2021.4那你大概率会在第一步就卡住官方预编译包默认面向 18.04 和 20.04 构建直接搬到 16.04 上跑最常见的报错就是GLIBC_2.27 not found或者GLIBCXX_3.4.22 not found。这个组合的痛点在于系统基础库太老官方发布包不可能回头兼容这么旧的发行版。不过只要拿到源码自己编译一遍是完全可行的而且能自己控制依赖版本和构建项。这篇文章我会把从环境准备、依赖升级到最终编译运行的全过程写下来包括实际环境里踩过的坑。适合部署环境被锁死在 16.04、又需要更新推理能力的开发者和运维参考。1. 为什么要在老系统上折腾 OpenVINO 2021.41.1 预编译包和源码编译的区别先说清楚问题的根源。OpenVINO 预编译包在发布时是带 glibc 版本要求的。Ubuntu 16.04 的 glibc 是 2.23而 2021.4 的官方二进制包基本是针对 glibc 2.27 以上构建的所以你会看到类似version GLIBC_2.27 not found的动态链接报错。这不是你少装了某个库而是系统底层的 C 运行库根本不满足要求。系统运行库这种东西不能随便替换强行升级 glibc 极有可能搞挂整个系统所以在 16.04 上走源码编译反而是最安全的路线。源码编译的逻辑是从源码把推理引擎和它依赖的第三方库重新构建出来最终产物链接的是当前环境的运行库版本。也就是说针对 glibc 2.23 的 16.04 环境编译出的库在运行时就不会再挑 glibc 版本毛病。代价是你需要准备一套可用的编译链包括较新的 CMake、GCC 和 Python这些工具的版本门槛会在后面详细展开。1.2 什么场景适合选择源码编译实际上并不是所有机器都需要源码编译。如果你的系统是 18.04 及以上直接下载官方 tar 包或者 pip 包跑setupvars.sh就能用。但下面这几类场景源码编译几乎是绕不开的系统被安全策略或业务约束固定在 16.04不批准升级发行版。机器没有外网访问受限不便从官方源拉预编译包但可以内网访问代码仓库和本地依赖源。需要裁剪组件只保留 CPU 推理插件去掉 GPU、VPU、GNA 等不用的部分。需要把编译产物放到多台相同系统的机器上复用此时源码编译一次rsync 分发即可。我自己遇到的主要是第一种和第三种。一台现场设备上的系统不能动但算法模型需要迁移到新版本推理框架上所以只能选择在构建机上编译好再拷贝过去。源码编译看起来费时间实际上只要配置对整个流程比反复排查动态链接错误要快得多。2. 编译前的环境检查与依赖准备2.1 先盘点系统现状不要上来就编译编译 OpenVINO 之前先确认本机环境。建议按顺序执行下面几条命令lsb_release -a gcc --version cmake --version python3 --version ldd --version | head -n 1在一台典型的 Ubuntu 16.04 机器上你大概率会看到这样的结果Ubuntu 16.04.7 LTSGCC 5.4.0CMake 3.5.1Python 3.5.2glibc 2.23这套组合基本没法直接编译 OpenVINO 2021.4。核心问题是 CMake 太旧GCC 5.4 对 C17 的支持不完整Python 3.5 不在官方 Python API 支持范围内。你需要按下面的顺序升级工具链。2.2 CMake 升级是第一道门槛OpenVINO 2021.4 要求 CMake 3.13 或更高版本而 Ubuntu 16.04 自带的 3.5.1 差得太远。不要用源码去编译安装 CMake那会浪费大量时间。最省事的方式是下载官方编译好的二进制 tar.gz 包放到/usr/local下wget https://github.com/Kitware/CMake/releases/download/v3.16.9/cmake-3.16.9-Linux-x86_64.tar.gz sudo tar -zxvf cmake-3.16.9-Linux-x86_64.tar.gz -C /opt sudo ln -s /opt/cmake-3.16.9-Linux-x86_64/bin/cmake /usr/local/bin/cmake装完以后执行cmake --version确认版本。这里有一个经验如果你的 shell 之前已经缓存过旧版的路径执行hash -r刷新一下命令缓存否则可能还会调到老版本的 CMake。2.3 Python 环境处理思路2021.4 的 Python API 支持 Python 3.6 到 3.9Ubuntu 16.04 自带的 Python 3.5 不满足条件。如果不需要 Python API只想用 C 接口可以跳过 Python 升级。但如果需要跑 Python 推理脚本就得装一个更新的 Python。我建议通过第三方工具链 PPA 安装 Python 3.6装完以后不要把它设为系统默认的python3而是在编译时通过参数显式指定路径。这样做的好处是避免干扰系统里已有的 Python 3.5 脚本sudo add-apt-repository ppa:deadsnakes/ppa sudo apt-get update sudo apt-get install python3.6 python3.6-dev python3.6-distutils之后编译时加上-DPYTHON_EXECUTABLE/usr/bin/python3.6参数OpenVINO 会基于 3.6 生成对应的 Python 模块。需要说明的是用 Python 3.6 编译出的openvino包只能在 Python 3.6 环境里加载这就意味着运行时也要用同一个 Python 版本。为了不污染系统环境建议建一个 venv/usr/bin/python3.6 -m venv /opt/ovenv source /opt/ovenv/bin/activate2.4 GCC 版本升级是避坑关键GCC 5.4 在编译 OpenVINO 的部分组件时会出现结构体初始化、正则表达式相关的问题根本原因是它对 C17 的支持不完整。OpenVINO 2021.4 在 18.04 上官方使用 GCC 7.5 构建所以我们也要在 16.04 上装一套 GCC 7。同样是走第三方 PPAsudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc-7 g-7安装完成后编译时直接指定CCgcc-7 CXXg-7即可不需要修改系统默认 GCC。这样可以避免把系统里其他 C 代码的编译环境搞乱。我踩过一次坑想直接把软链接全局切到 GCC 7结果系统里某些旧模块重新编译时出现了二进制不兼容问题所以还是建议只在 OpenVINO 构建时临时指定编译器。3. 源码结构与编译参数详解3.1 源码目录里有哪些东西拿到 OpenVINO 2021.4 源码后先看清楚目录结构再动手。克隆代码git clone --recursive https://github.com/openvinotoolkit/openvino.git cd openvino git checkout 2021.4 git submodule update --init --recursive源码根目录下主要有这几个部分inference-engine推理引擎核心包含 CPU、GPU、VPU 等插件。ngraph模型解析和计算图优化层OpenVINO 通过它把不同框架的模型统一成中间表示。openvino新版本的顶层封装和 Python API 绑定。docs文档和示例程序。cmake公共的 CMake 工具脚本。编译入口在inference-engine目录OpenVINO 2021.4 的构建流程会把ngraph和inference-engine一起构建。实际上你也可以在根目录创建build目录再指向inference-engine目录进行配置两种方式等价。3.2 关键 CMake 选项说明编译 OpenVINO 时有一批 CMake 选项需要提前理解。下面列出我实际用到的几个并说明每个的作用选项作用建议值-DCMAKE_BUILD_TYPERelease编译优化级别Release 模式性能更好必选-DCMAKE_INSTALL_PREFIX指定安装目录/opt/openvino-DTHREADINGSEQ使用顺序线程模式不依赖额外线程库无 TBB 时使用-DENABLE_VPUOFF关闭 VPU 插件不需要神经棒时关闭-DENABLE_GNAOFF关闭 GNA 插件不需要语音加速时关闭-DENABLE_CLDNNOFF关闭 GPU 插件相关代码不跑 GPU 推理时关闭-DENABLE_OPENCLOFF关闭 OpenCL 运行时不使用 GPU 时不开启-DENABLE_PYTHONON构建 Python API需要 Python 时开启-DPYTHON_EXECUTABLE指定 Python 解释器路径指向 Python 3.6如果你不需要 GPU 推理千万记得把ENABLE_CLDNN和ENABLE_OPENCL关掉。这两个组件编译时会引入大量 GPU 相关依赖开着会显著拉长编译时间而且 16.04 上配套的 OpenCL 运行库版本也不好凑。3.3 推荐用于 16.04 的编译配置综合上面的考虑我的推荐配置如下cd inference-engine mkdir build cd build cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX/opt/openvino \ -DCMAKE_C_COMPILERgcc-7 \ -DCMAKE_CXX_COMPILERg-7 \ -DTHREADINGSEQ \ -DENABLE_VPUOFF \ -DENABLE_GNAOFF \ -DENABLE_CLDNNOFF \ -DENABLE_OPENCLOFF \ -DENABLE_PYTHONON \ -DPYTHON_EXECUTABLE/usr/bin/python3.6这里解释一下THREADINGSEQ的选择。OpenVINO 默认会尝试集成 TBB 线程库而 2021.4 的 TBB 版本在 16.04 上需要额外处理链接路径。如果我只需要 CPU 推理且没有特殊并发要求直接用顺序线程模型可以少绕很多坑。如果后续需要 TBB可以在编译好 TBB 之后再加-DTBB_DIR指定路径这个后面会在问题排查里提到。关于编译的并发度内存有限的机器建议make -j4如果内存小于 8GB-j2更稳妥。我以前在 4GB 内存的小机器上用-j8编译跑到一半直接被 kill浪费了整整半天时间。编译是一个内存和 CPU 双重消耗的过程不要贪并行度。4. 完整实操流程记录4.1 编译前需要安装的本地软件包正式编译之前先把系统内的基础依赖装齐。OpenVINO 构建过程中会用到一些开发头文件缺了会在 CMake 配置阶段报错sudo apt-get update sudo apt-get install build-essential pkg-config sudo apt-get install libgtk-2.0-dev libcanberra-gtk-module sudo apt-get install libssl-dev libffi-dev sudo apt-get install libusb-1.0-0-devlibgtk-2.0-dev主要影响 OpenCV 和推理示例的构建。如果你不需要编译带 GUI 的示例程序可以暂时不装但建议还是装上避免后续跑 demo 时缺图形库依赖。另外 OpenVINO 构建过程中会检测系统中的 OpenCV。如果系统已有 OpenCV 2.4可能会出现版本冲突这个到第 5 节再讲处理办法。4.2 模块初始化和生成构建文件OpenVINO 源码仓库包含多个子模块clone 时必须用--recursive。如果你 clone 时漏掉了子模块或者只想下载特定版本可以手动初始化git checkout 2021.4 git submodule update --init --recursive然后进入构建目录进行 CMake 配置。CMake 配置阶段结束以后认真看一遍屏幕输出的Features表格确认CPU插件是开启状态VPU、GNA等插件是关闭状态。这一步值得多看两眼因为如果漏了某个依赖CMake 也会在配置阶段直接报错而不是等到编译阶段。配置成功后会生成 Makefile下面可以开始编译。4.3 编译安装和产物确认执行编译make -j4编译时间取决于机器性能。我在一台 16 核的机器上大约花费 40 分钟在 4 核的机器上则接近 2 小时。编译过程中如果发现某个文件报语法错误先回想一下 GCC 版本是否设置正确不要一味修改源码。OpenVINO 这种大型项目的源码经过大量测试大多数编译错误都是工具链不匹配引起的。编译完成后执行make install安装完成后确认一下关键产物ls /opt/openvino/bin/ ls /opt/openvino/lib/正常情况下bin目录会包含benchmark_app、setupvars.sh等可执行文件和脚本lib目录会包含libinference_engine.so、libngraph.so等库文件。看到这些文件基本说明推理引擎编译成功了。4.4 运行环境和快速验证每次使用前需要加载环境变量source /opt/openvino/bin/setupvars.sh验证编译产物是否可用的最快方法是跑一下benchmark_app./benchmark_app -h如果能看到帮助信息说明推理引擎核心库加载正常。想要完整验证模型推理准备一个 OpenVINO IR 格式的模型运行./benchmark_app -m /path/to/model.xml -i /path/to/input.jpg -d CPU -api sync我第一次跑的时候遇到过一个动态链接问题libinference_engine.so找不到libngraph.so。原因是setupvars.sh没有正确配置LD_LIBRARY_PATH或者安装目录被移动过。解决办法是手动把安装目录追加到环境变量export LD_LIBRARY_PATH/opt/openvino/lib:$LD_LIBRARY_PATH4.5 多台机器分发部署的注意事项OpenVINO 编译完成后产物可以直接拷贝到其他同样版本的系统上使用。我实际分发的文件包括bin目录下的可执行文件和脚本lib目录下的所有.so库文件share目录下的模型转换相关辅助文件Python API 模块文件如果开启拷贝后必须在目标机器上重新执行setupvars.sh并且确认目标机器的 GLIBC 版本不低于编译机。虽然源码编译理论上生成的是当前环境的兼容产物但如果编译机和目标机的系统版本差距过大仍可能出现 libstdc 不兼容的问题这个问题在下一节详细展开。5. 遇到的典型错误与排查实录5.1 运行时 GLIBCXX 版本报错场景编译机器是 18.04目标机器是 16.04把编译产物拷到 16.04 上运行报错libstdc.so.6: version GLIBCXX_3.4.22 not found这个问题的根源不是 OpenVINO而是编译机 GCC 7 的运行时库比 16.04 自带的 libstdc 新。解决办法有两种一种是在编译机下载老版本 libstdc 并静态链接一种是在目标机上把 GCC 7 的 libstdc 通过LD_LIBRARY_PATH带上。最稳妥的方案是让编译机和目标机系统保持同版本。如果确实做不到建议用下面的命令确认当前 libstdc 提供的最高版本strings /usr/lib/x86_64-linux-gnu/libstdc.so.6 | grep GLIBCXX | sort -V | tail -n 5如果在 16.04 上连GLIBCXX_3.4.22都没有就需要用 GCC 7 自带的新 libstdc并将它的路径提前到LD_LIBRARY_PATH最前面。5.2 编译过程中内存耗尽被杀死编译 OpenVINO 的ngraph组件时GCC 的内存占用非常高。某些复杂模板元编程代码会让单进程占用 1GB 以上内存。如果同时用-j8编译8 个进程叠加起来内存很容易爆掉。系统日志里面会出现 OOM kill 记录。解决思路很简单降低并行度。建议先free -h看下可用内存内存 8GB 以下用-j216GB 左右用-j4。另外可以在make命令后面加上-l参数限制系统负载make -j4 -l 4-l 4表示当系统平均负载超过 4 时不再启动新任务对共享编译资源的机器尤其有用。5.3 系统已安装 OpenCV 导致链接冲突OpenVINO 构建过程中如果检测到系统里有 OpenCV它可能会优先尝试使用系统版本。但系统上的 OpenCV 多半是 2.4 或 3.x 的老版本和 OpenVINO 自带的 OpenCV 头文件不一致结果就是编译出来的程序在运行时出现大量undefined reference或者直接崩溃。排查思路是看 CMake 配置阶段的日志搜索OpenCV相关信息。如果发现它使用了系统路径可以在 CMake 配置时显式指定-DOpenCV_DIR/usr/share/OpenCV \ -DENABLE_OPENCVOFF我这里更推荐直接把ENABLE_OPENCV关掉因为 OpenVINO 自身的推理示例对 OpenCV 的依赖并不多关掉反而少一个变量。如果你确实需要跑带图像解码的 demo再单独编译配套的 OpenCV 版本并让 OpenVINO 使用它。5.4 Python 模块导入报错如果开启 Python API 后执行import openvino报错ModuleNotFoundError: No module named openvino或者ImportError: libpython3.6m.so.1.0: cannot open shared object file前者通常是环境变量没配置好setupvars.sh里已经写了 Python 模块路径需要确认你当前使用的 Python 版本正是编译时指定的那一个。后者是因为构建时虽然指定了 Python 3.6 的头文件和库路径但运行时系统的动态库搜索路径不包含 Python 自身库目录需要单独加入export LD_LIBRARY_PATH/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH这个坑比较隐蔽因为 Python 模块使用的是编译期的 Python 路径而 OpenVINO 的 Python 绑定又通过ctypes加载底层库这个组合在非标准 Python 安装路径下特别容易出现。6. 一些实际体会与调整建议OpenVINO 2021.4 在 Ubuntu 16.04 上编译难度主要集中在前期的工具链准备上真正跑起来之后问题反而不多。就我个人的体验而言下面这几条是值得一开始就做对的第一尽量使用独立的编译目录。不要直接在源码目录下编译因为 OpenVINO 的子模块比较多一旦编译残留物混进源码目录后续切换分支或重新生成 CMake 配置时很容易因缓存产生诡异问题。我就是一直保持inference-engine/build目录的独立出问题直接删掉整个 build 目录重新生成成本最低。第二认真对待 CMake 配置输出。OpenVINO 配置完成以后会在终端打印一张组件开关表包括各个插件的构建状态。每次我用grep检查输出都确认 CPU 插件是ON状态。很多人编译完以后发现没有 CPU 推理能力基本都是ENABLE_MKL_DNNOFF或 CPU 插件构建状态异常。第三不要在同一台机器上反复用不同的 GCC 版本切换编译。GCC 5 和 GCC 7 编译出的对象文件混在同一个 build 目录里链接时会出现奇奇怪怪的符号冲突。如果你尝试过不同编译器版本建议彻底清空 build 目录再重新配置。第四如果只是想要一个能跑的推理环境而目标机器有网络可以先用 18.04 的 Docker 容器完成全流程验证再把编译好的产物带到 16.04 上测试运行。我这里试过最顺利的部署方式其实是在一台 16.04 的构建机上用 GCC 7 编译产物直接放到同样 16.04 的目标机全程不出现 GLIBC 和 GLIBCXX 报错。如果你有两台相同版本的系统这会是最省心的方案。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑