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

1. 前言

1.1. 问题说明

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

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文件无法正常下载。

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

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 安装命令给出。先是依赖项安装命令

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

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

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的这一步

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还差,所以我估计大概率是因为网络问题导致的这个错误。

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

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

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

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

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。

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命令(注意不要删除缓存文件夹),就可以正常构建成功了。

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

3. 问题解决

cmake构建成功的最终输出

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

image.png

后续的编译也没有问题:

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最终的输出

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"

至此,问题解决。