目录
Q1.cmake 过程遇到以下报错:
Q2.make过程中找不到stdlib.h:
Q3.make过程找不到sys/sysctl.h :
Q4. cap_ffmpeg_impl.hpp文件中相关宏的更新:
opencv2与opencv4的(手动源码)安装路径结构差异:
编译器版本:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
手动编译安装opencv2.4.13版本源码过程中遇到以下错误:
CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:85 (list):
list GET given empty list
Call Stack (most recent call first):
CMakeLists.txt:89 (include)
CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:86 (list):
list GET given empty list
Call Stack (most recent call first):
CMakeLists.txt:89 (include)
CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:89 (math):
math cannot parse the expression: "*100 + ": syntax error, unexpected
exp_TIMES (1).
Call Stack (most recent call first):
CMakeLists.txt:89 (include)
原因是OpenCVDetectCXXCompiler.cmake中,必须将“dumpversion”更改为“dumpfullversion”
因为在更高版本的gcc中,dumpversion函数无法获取编译器的真实完整版本号,因此cmake过程将失败。
解决办法:在cmake/OpenCVDetectCXXCompiler.cmake文件第81行添加以下代码:
#dumpversion prints only major version since gcc7
if((NOT CMAKE_GCC_REGEX_VERSION) AND (${CMAKE_OPENCV_GCC_VERSION_FULL} GREATER 6))
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dumpfullversion
OUTPUT_VARIABLE CMAKE_OPENCV_GCC_VERSION_FULL
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CMAKE_GCC_REGEX_VERSION "${CMAKE_OPENCV_GCC_VERSION_FULL}")
endif()
更改的完整文件OpenCVDetectCXXCompiler.cmake在这里:
cmake: fix gcc version detection by sovrasov · Pull Request #9430 · opencv/opencv · GitHub
/usr/include/c++/11/cstdlib:75:15: fatal error: stdlib.h: 没有那个文件或目录
75 | #include_next
| ^~~~~~~~~~
compilation terminated.
原因是gcc 的一些弱微改动导致找不到该文件,在cmake时,关闭预编译头文件即可:
cmake -DENABLE_PRECOMPILED_HEADERS=OFF ..
/home/jadrian/opencv-2.4.13/modules/core/src/parallel.cpp:60:18: fatal error: sys/sysctl.h: 没有那个文件或目录
60 | #include
| ^~~~~~~~~~~~~~
compilation terminated.
这个报错的主要原因是随着 glibc 2.32( Linux 下使用的开源的标准 C 库,由GNU 发布) 的发布,Linux 系统删除了sys/sysctl.h:
The GNU C Library version 2.32 is now available
这里说明了这个头文件及其函数已经弃用,可以直接将其注释掉。随后几个由这一头文件引起的报错,均将之对引用的头文件行注释掉。
这一条参考:https://github.com/OGRECave/ogre-next/issues/132
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp:1481:21: error: ‘CODEC_FLAG_GLOBAL_HEADER’ was not declared in this scope; did you mean ‘AV_CODEC_FLAG_GLOBAL_HEADER’?
1481 | c->flags |= CODEC_FLAG_GLOBAL_HEADER;
| ^~~~~~~~~~~~~~~~~~~~~~~~
| AV_CODEC_FLAG_GLOBAL_HEADER
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp: In function ‘int icv_av_write_frame_FFMPEG(AVFormatContext*, AVStream*, uint8_t*, uint32_t, AVFrame*)’:
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp:1505:30: error: ‘AVFMT_RAWPICTURE’ was not declared in this scope
1505 | if (oc->oformat->flags & AVFMT_RAWPICTURE) {
| ^~~~~~~~~~~~~~~~
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp: In member function ‘void CvVideoWriter_FFMPEG::close()’:
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp:1679:35: error: ‘AVFMT_RAWPICTURE’ was not declared in this scope
1679 | if( (oc->oformat->flags & AVFMT_RAWPICTURE) == 0 )
| ^~~~~~~~~~~~~~~~
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp: In member function ‘bool CvVideoWriter_FFMPEG::open(const char*, int, double, int, int, bool)’:
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp:1913:32: error: ‘AVFMT_RAWPICTURE’ was not declared in this scope
1913 | if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
| ^~~~~~~~~~~~~~~~
In file included from /home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg.cpp:45:
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp: In static member function ‘static AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext*, AVCodecID, int, int, int, double, AVPixelFormat)’:
/home/jadrian/opencv-2.4.13/modules/highgui/src/cap_ffmpeg_impl.hpp:2207:25: error: ‘CODEC_FLAG_GLOBAL_HEADER’ was not declared in this scope; did you mean ‘AV_CODEC_FLAG_GLOBAL_HEADER’?
2207 | c->flags |= CODEC_FLAG_GLOBAL_HEADER;
| ^~~~~~~~~~~~~~~~~~~~~~~~
| AV_CODEC_FLAG_GLOBAL_HEADER
解决办法:修改相关宏定义,在modules/highgui/src/cap_ffmpeg_api.hpp(cap_ffmpeg_impl.hpp的上层头文件)添加宏:(我在13行之后)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
#define AVFMT_RAWPICTURE 0x0020
至此,opencv2编译完毕。
(1)/usr/local/include下新建了opencv和opencv2两个文件夹,opencv4则是opencv4一个文件夹。
(2)opencv2在/usr/local/lib下除了存放了一些带有版本数字后缀的共享库文件,然后只新建了pkgconfig文件夹(内只有opencv.pc一个文件);而opencv4除了在该目录下安装共享库文件外,只安装了一些.cmake文件在/usr/local/lib/cmake/opencv4下。
(3)如(2)所说,.cmake文件opencv4是安装在/usr/local/lib/cmake/opencv4下,而opencv2是安装在/usr/local/share/Opencv下:
而opencv4的/usr/local/share/目录下是这样的: