MAC OSX下opencv 4的静态库编译与连接/ compile and link opencv static library under OSX

我!终于!成功在MAC下面把opencv4程序静态编译起来了!
先上compile的命令:
g++ -std=c++11 main.cpp preprocess.cpp -framework Foundation -framework OpenCL -framework CoreMedia -framework AudioToolbox -framework CoreVideo -framework AVFoundation -framework CoreFoundation -framework CoreGraphics -I./include -L./lib -lopencv_videoio -lopencv_gapi -lopencv_features2d -lopencv_photo -lopencv_ts -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_core -lippiw -lippicv -ljpeg -llibpng -littnotify -lade -lIlmImf -lzlib -llibjpeg-turbo -lquirc -llibjasper -llibtiff -llibwebp -o main

有没有发现有什么不对?没错就是挂在-L和-I前的一堆 -framework,微笑,因为MAC OS下自己有一堆的framework,opencv在MAC下编译会依赖这些静态库,所以编译的时候需要把他们一起连接上,这也是为什么即使把opencv的静态库全部连接上并整理好依赖关系还会出现
Undefined symbols for architecture x86_64:
"_CFDataGetBytePtr", referenced from:
CvVideoWriter_AVFoundation::writeFrame(_IplImage const) in libopencv_videoio.a(cap_avfoundation_mac.mm.o)
"_CFRelease", referenced from:
CvCaptureFile::~CvCaptureFile() in libopencv_videoio.a(cap_avfoundation_mac.mm.o)
CvCaptureFile::grabFrame() in libopencv_videoio.a(cap_avfoundation_mac.mm.o)
releaseCallback(void
, void const) in libopencv_videoio.a(cap_avfoundation_mac.mm.o)
"_CGColorSpaceCreateDeviceRGB", referenced from:
CvVideoWriter_AVFoundation::writeFrame(_IplImage const
) in libopencv_videoio.a(cap_avfoundation_mac.mm.o)
"_CGColorSpaceRelease", referenced from:
CvVideoWriter_AVFoundation::writeFrame(_IplImage const*) in libopencv_videoio.a(cap_avfoundation_mac.mm.o)
类似于这种错误(方便复制错误的旁友搜到这个帖子)
回归正题

1. MAC OS下静态编译

参考https://shiffman.net/opencv/2011/01/23/how-to-build-opencv-static-libraries-mac-os-x/
这篇里的with_ffmpeg去掉的话就不能进行视频处理,所以如果要处理视频的话请看下面的更新。
其实就是在CMAKE里把BUILD_SHARED_LIBRARIES=OFF, CMAKE GUI的确很好用,安利。不过这样编译的静态库好像缺了一个libippicv.a,我是直接在opencv的安装目录下找到的,所以可能不用自己重新静态编译,直接下载的Opencv安装目录下的静态库也能用。

2. 静态链接

首先把头文件全部拷贝到当前目录的include下,静态库全部拷贝到当前目录的lib下。
因为opencv的静态库之间还有依赖性,所以直接一股脑放上去是不行的。在电脑里已经安装了opencv的情况下可以参考 pkg-config --cflags --libs opencv4出来的动态库的顺序。
如果依然搞不清顺序,可以查看undefined symbol的错误信息,比如“_WebPDecodeBGRAInto”, 利用 nm lib/*.a -A| grep "_WebPDecodeBGRAInto" 可以找到含有此标志的.a文件,其中U代表引用别的静态库此标志,D代表定义此标志(大概?不懂静态库编译,从我的搜索结果来看好像是这样)把D的文件放到U的后面就可以了,比如此处把-lwebp 放在-lopencv_imgcodecs的后面。
最后当你发现有的symbol在/usr/local/下所有的静态库文件都找不到的时候。。。。
谷歌会发现这个symbol原来在OSX的framework中,微笑.jpg。
于是我发现了-framework Foundation -framework OpenCL -framework CoreMedia -framework AudioToolbox -framework CoreVideo -framework AVFoundation -framework CoreFoundation -framework CoreGraphics,最后把这些framework都加上,终于大功告成啦!

(碎碎念:写Opencv的程序花了一天,想compile成独立的可执行程序断断续续花了三周真是遭不住。尝试过动态连接+用install_name_tool 修改程序动态库的路径,opencv的动态库是没问题了,但是opencv_core依赖的一个openblasp库不知道为什么即使打包在文件夹里依然会显示no suitable image found, did find error... 大概意思好像是虽然有这个文件但是文件有问题?不合适,这真的不合适_> 有旁友动态连接成功了的话请告诉我怎么搞! 拜谢!)


更新(错误方法):

程序运行时发现video capture报错无法运行,搜索之后发现是缺了ffmpeg的库,系统自带的ffmpeg有动态库和静态库,但是opencv编译时去掉了WITH_FFMPEG,没去掉的话也是默认连接动态库,因此在opencv的CMAKE里把ffmpeg相关的库都修改成静态库:


image.png

重新编译opencv,这时候make又会开始报Undefined symbol的错误,又要回过头调查每个ffmpeg的库依赖(MMP)


更更新:

上面的方法直接使用ffmpeg静态库的时候还不知道ffmpeg依赖libbz2和libiconv,libiconv的静态库标志和动态库标志又不一样,一个是_libiconv_open一个是_iconvopen,系统自己的ffmpeg里面的libavcodec又有一大堆依赖,纠结了很久libiconv怎么处理甚至还差点把电脑弄坏= =。
终于发现其实可以自己重新编译一次ffmpeg,有把iconv去掉这一个选项!
所以步骤为

  1. 下载ffmpeg源码并编译
    ./configure --enable-static --disable-iconv --disable-gnutls --disable-libbluray --disable-x86asm --enable-avresample
    gnutls和libbluray一个没找到静态库一个静态库有一堆依赖-皿-,系统自带的ffmpeg里有他们不过ffmpeg的configure默认是disable的,加一个保险一点。 --disable-iconv和--enable-avresample是必需的因为默认Iconv会编译进去以及不编译avresample的静态库,但是这个库又是opencv会引用的。
  2. 下载libbz2源码并编译
    因为这个静态库很好编译所以我没有尝试ffmpeg编译时能不能去掉这个库, 查看了一下configure里没有对这个库disable的说明所以我猜可能是不能去掉的。
  3. 修改opencv CMAKE
    shared-library和之前一样去掉✅
    新的ffmpeg路径:


    image.png

    这里虽然有libiconv的路径,但是因为这个是ffmpeg的dependency不是opencv的dependency,所以后面compile的时候可以忽略这个库,就不会发生symbol undifined的问题啦!
    要注意configure以后一定要往下拉看video IO模块ffmpeg有没有显示yes:


    image.png

    这些版本其实都是动态库的版本不用管
    generate并重新编译opencv。
  4. 用新的opencv和ffmpeg静态库替代之前的库, 在compile的时候添加依赖项然后就可以运行视频处理了!
    可能需要添加一些ffmpeg的依赖库,不过这个时候的依赖库都是系统里可以很容易找到静态库的了,找不到的symbol可以用nm $(find /usr/ -type f -name "*.a") -A |grep "_aom_codec_av1_cx"这个命令行寻找需要的symbol在哪。
    最后的compile命令:
    g++ -std=c++11 main.cpp preprocess.cpp -lavformat -lavcodec -lavdevice -lavfilter -lavutil -lswresample -lavresample -lswscale -llzma -framework Security -framework VideoToolbox -framework CoreServices -framework Foundation -framework OpenCL -framework CoreMedia -framework AudioToolbox -framework CoreVideo -framework AVFoundation -framework CoreFoundation -framework CoreGraphics -framework Cocoa -framework Accelerate -framework QuartzCore -I./include -L./lib -lopencv_videoio -lopencv_gapi -lopencv_features2d -lopencv_photo -lopencv_ts -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_core -lippiw -lippicv -ljpeg -llibpng -littnotify -lade -lIlmImf -lzlib -llibjpeg-turbo -lquirc -llibjasper -llibtiff -llibwebp -lssl -lcrypto -lcharset -lbz2 -lxvidcore -o main
    新加的有ffmpeg的几个库,Security, VideoToolBox, CoreServices framework, 还有最后的ssl, crypto, charset, bz2, xvidcore库,除了libbz2需要自己编译静态库,别的都是系统里就有的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342