ubuntu 18.04 使用 cmake 编译安装 OpenCV 3.2.0 时出现哈希错误。

1. 前言

1.1. 问题说明

在 amd64 的 ubuntu 18.04 desktop 上编译安装 OpenCV 3.2.0 的时候,我遇到了 cmake 构建错误。错误的核心报错如下

plaintext
1
2
3
4
for file: [/home/king/slam/pkg/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e/ippicv_linux_20151201.tgz]
expected hash: [808b791a6eac9ed78d32a7666804320e]
actual hash: [d41d8cd98f00b204e9800998ecf8427e]
status: [7;"Couldn't connect to server"]

说来奇怪,之前在 ubuntu 22.04 arm 中启动的 ubuntu 18.04 docker 容器内编译安装 OpenCV 3.2.0 时并没有遇到此报错。可能是网络因素导致 ippicv_linux_20151201.tgz 文件无法正常下载。

完整的错误输出如下所示:

plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-- Looking for sys/videoio.h
-- Looking for sys/videoio.h - not found
CMake Warning at 3rdparty/ippicv/downloader.cmake:56 (message):
ICV: Local copy of ICV package has invalid MD5 hash:
8b449a536a2157bcad08a2b9f266828b (expected:
808b791a6eac9ed78d32a7666804320e)
Call Stack (most recent call first):
3rdparty/ippicv/downloader.cmake:110 (_icv_downloader)
cmake/OpenCVFindIPP.cmake:243 (include)
cmake/OpenCVFindLibsPerf.cmake:37 (include)
CMakeLists.txt:558 (include)


-- ICV: Downloading ippicv_linux_20151201.tgz...
CMake Error at 3rdparty/ippicv/downloader.cmake:73 (file):
file DOWNLOAD HASH mismatch

for file: [/home/king/slam/pkg/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e/ippicv_linux_20151201.tgz]
expected hash: [808b791a6eac9ed78d32a7666804320e]
actual hash: [d41d8cd98f00b204e9800998ecf8427e]
status: [7;"Couldn't connect to server"]

Call Stack (most recent call first):
3rdparty/ippicv/downloader.cmake:110 (_icv_downloader)
cmake/OpenCVFindIPP.cmake:243 (include)
cmake/OpenCVFindLibsPerf.cmake:37 (include)
CMakeLists.txt:558 (include)


CMake Error at 3rdparty/ippicv/downloader.cmake:77 (message):
ICV: Failed to download ICV package: ippicv_linux_20151201.tgz.
Status=7;"Couldn't connect to server"
Call Stack (most recent call first):
3rdparty/ippicv/downloader.cmake:110 (_icv_downloader)
cmake/OpenCVFindIPP.cmake:243 (include)
cmake/OpenCVFindLibsPerf.cmake:37 (include)
CMakeLists.txt:558 (include)


-- Configuring incomplete, errors occurred!
See also "/home/king/slam/pkg/opencv-3.2.0/build/CMakeFiles/CMakeOutput.log".
See also "/home/king/slam/pkg/opencv-3.2.0/build/CMakeFiles/CMakeError.log".

1.2. 使用的安装命令

提出解决方案之前,先把我使用的 OpenCV 3.2.0 安装命令给出。先是依赖项安装命令

bash
1
2
3
4
5
6
7
8
9
10
11
12
# 依赖项
sudo apt-get install -y \
build-essential libgtk2.0-dev \
libavcodec-dev libavformat-dev \
libjpeg.dev libtiff5.dev libswscale-dev \
libcanberra-gtk-module \
libavresample-dev libgphoto2-dev
# 添加新源后继续安装
sudo apt-get install -y software-properties-common
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt-get -y update
sudo apt-get install -y libjasper1 libjasper-dev

随后是下载软件包和构建安装命令

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 下载和解压
wget -O opencv-3.2.0.tar.gz https://github.com/opencv/opencv/archive/refs/tags/3.2.0.tar.gz
tar -zxvf opencv-3.2.0.tar.gz
# 开始编译和安装
pushd opencv-3.2.0
rm -rf build
mkdir build && cd build
# 构建和编译安装,-j4代表4线程并发
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j$(nproc)
make install
# 刷新动态库
ldconfig
popd

出现问题的是 cmake 的这一步

bash
1
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

2. 解决方案

参考:https://github.com/opencv/opencv/issues/5973

报错提到了一个文件,这个文件其实是要被 cmake 主动下载的,但是并没有被下载下来。在 opencv-3.2.0/3rdparty/ippicv/ 目录下可以找到一个 downloader.cmake 文件,里面就有文件的下载链接。链接的域名是 raw.githubusercontent.com 链接,这个域名的国内联通性比 github.com 还差,所以我估计大概率是因为网络问题导致的这个错误。

cmake
1
set(OPENCV_ICV_URL "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_BINARIES_COMMIT}/ippicv")

cmake 的报错中给出了两个哈希值,我们本地已有的文件 hash 是 d41d8cd98f00b204e9800998ecf8427e,这是 md5 的空文件哈希。如果使用 ls -l 查看这个文件,你会发现它就是一个 0KB 的空文件

bash
1
ls -l /home/king/slam/pkg/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e/ippicv_linux_20151201.tgz

所以我们要做的就是把正确的文件手动下载下来,这里给出 github 的下载链接

plaintext
1
https://github.com/opencv/opencv_3rdparty/raw/ippicv/master_20151201/ippicv/ippicv_linux_20151201.tgz

注意,上面贴出的 issue 5973 中给出的 ippicv 下载链接 版本是不对的,要和 cmake 报错中提到的版本号 ippicv_linux_20151201.tgz 保持一致。否则即便你重新下载了版本号不对的文件,cmake 依旧会报错 hash 值不一致。

下载好了 ippicv_linux_20151201.tgz 这个文件之后,将其放置到 /home/king/slam/pkg/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e/ 目录中,替换掉刚刚的 ippicv_linux_20151201.tgz 空文件即可。有效文件大小约 36.5MB。

plaintext
1
2
3
$ ls -l /home/king/slam/pkg/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e/
total 35680
-rw-rw-r-- 1 king king 36533175 Feb 28 17:37 ippicv_linux_20151201.tgz

替换完毕之后重新执行 cmake 命令(注意不要删除缓存文件夹),就可以正常构建成功了。

bash
1
2
cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr/local ..

3. 问题解决

cmake 构建成功的最终输出

plaintext
1
2
3
-- Configuring done
-- Generating done
-- Build files have been written to: /home/king/slam/pkg/opencv-3.2.0/build

image.png

后续的编译也没有问题:

plaintext
1
2
3
4
5
[100%] Linking CXX executable ../../bin/opencv_test_calib3d
[100%] Built target opencv_test_calib3d
[100%] Linking CXX executable ../../bin/opencv_perf_stitching
[100%] Built target opencv_perf_stitching
king@ubuntu:~/slam/pkg/opencv-3.2.0/build$

image.png

执行 sudo make install,成功安装 OpenCV 3.2.0,以下是 make install 最终的输出

plaintext
1
2
3
4
-- Installing: /usr/local/bin/opencv_visualisation
-- Set runtime path of "/usr/local/bin/opencv_visualisation" to "/usr/local/lib"
-- Installing: /usr/local/bin/opencv_version
-- Set runtime path of "/usr/local/bin/opencv_version" to "/usr/local/lib"

至此,问题解决。