到底用静态连接还是用动态连接?

static or share
当你连接库文件时,到底应该连接它的静态库,还是动态库,这是个问题.
谁更好,各有千秋, 下面看看我的经历就说明问题了.
有一个项目,用到了ffmpeg 库.
首先,我选择了静态连接, 为什么? 因为这样发布的时候简单,生成的文件虽然大点,此时运行文件会包含所有依赖的部分.
好,其它问题都解决了,只剩下几十个ffmpeg 的连接错误了. 未定义的引用 ....

类似于下面的形式: 好在我对这些函数的来历还是了解的,就是ffmpeg库中的函数.

multiview/sub.cpp:351:对‘av_dict_set(AVDictionary**, char const*, char const*, int)’未定义的引用
multiview/sub.cpp:352:对‘avformat_open_input(AVFormatContext**, char const*, AVInputFormat*, AVDictionary**)’未定义的引用
multiview/sub.cpp:358:对‘avformat_find_stream_info(AVFormatContext*, AVDictionary**)’未定义的引用
multiview/sub.cpp:364:对‘av_find_best_stream(AVFormatContext*, AVMediaType, int, int, AVCodec**, int)’未定义的引用
multiview/sub.cpp:366:对‘av_get_media_type_string(AVMediaType)’未定义的引用
multiview/sub.cpp:380:对‘av_dict_free(AVDictionary**)’未定义的引用
multiview/sub.cpp:381:对‘avformat_close_input(AVFormatContext**)’未定义的引用
multiview/sub.cpp:384:对‘av_dict_free(AVDictionary**)’未定义的引用
multiview/sub.cpp:385:对‘avformat_close_input(AVFormatContext**)’未定义的引用

按照网上所说,咱们按照顺序加载ffmpeg 静态连接库
LIBS += /opt/ffmpeg_build/lib/libavdevice.a
LIBS += /opt/ffmpeg_build/lib/libavfilter.a
LIBS += /opt/ffmpeg_build/lib/libswscale.a
LIBS += /opt/ffmpeg_build/lib/libpostproc.a
LIBS += /opt/ffmpeg_build/lib/libavformat.a
LIBS += /opt/ffmpeg_build/lib/libavcodec.a
LIBS += /opt/ffmpeg_build/lib/libswresample.a
LIBS += /opt/ffmpeg_build/lib/libavutil.a
重新编译,

还好我记录了一下它的错误: 鉴赏一下, 难过的是我对这些函数已无所知,也不知道它在那个库中,

但一样要消灭它.

# cat error.txt
/usr/local/lib/libavfilter.a(vf_pp.o):在函数‘pp_filter_frame’中:
/opt/env/ffmpeg/libavfilter/vf_pp.c:143:对‘pp_postprocess’未定义的引用            //属于libpostproc
/usr/local/lib/libavfilter.a(vf_pp.o):在函数‘pp_config_props’中:
/opt/env/ffmpeg/libavfilter/vf_pp.c:109:对‘pp_get_context’未定义的引用
/usr/local/lib/libavfilter.a(vf_pp.o):在函数‘pp_uninit’中:
/opt/env/ffmpeg/libavfilter/vf_pp.c:163:对‘pp_free_mode’未定义的引用
/usr/local/lib/libavfilter.a(vf_pp.o):在函数‘pp_init’中:
/opt/env/ffmpeg/libavfilter/vf_pp.c:58:对‘pp_get_mode_by_name_and_quality’未定义的引用
/usr/local/lib/libavfilter.a(vf_pp.o):在函数‘pp_uninit’中:
/opt/env/ffmpeg/libavfilter/vf_pp.c:165:对‘pp_free_context’未定义的引用
/usr/local/lib/libavfilter.a(vf_scale_npp.o):在函数‘nppscale_interleave’中:
/opt/env/ffmpeg/libavfilter/vf_scale_npp.c:746:对‘nppiYCbCr420_8u_P3P2R’未定义的引用
/usr/local/lib/libavfilter.a(vf_scale_npp.o):在函数‘nppscale_resize’中:
/opt/env/ffmpeg/libavfilter/vf_scale_npp.c:723:对‘nppiResizeSqrPixel_8u_C1R’未定义的引用
/usr/local/lib/libavfilter.a(vf_scale_npp.o):在函数‘nppscale_deinterleave’中:
/opt/env/ffmpeg/libavfilter/vf_scale_npp.c:694:对‘nppiYCbCr420_8u_P2P3R’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):在函数‘setup_frame’中:
/opt/env/ffmpeg/libavcodec/libx264.c:437:对‘x264_picture_init’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):在函数‘reconfig_encoder’中:
/opt/env/ffmpeg/libavcodec/libx264.c:309:对‘x264_encoder_reconfig’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):在函数‘X264_frame’中:
/opt/env/ffmpeg/libavcodec/libx264.c:577:对‘x264_encoder_encode’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:610:对‘x264_encoder_delayed_frames’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):在函数‘reconfig_encoder’中:
/opt/env/ffmpeg/libavcodec/libx264.c:224:对‘x264_encoder_reconfig’未定义的引用            //属于libx264
/opt/env/ffmpeg/libavcodec/libx264.c:229:对‘x264_encoder_reconfig’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:236:对‘x264_encoder_reconfig’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:262:对‘x264_encoder_reconfig’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:242:对‘x264_encoder_reconfig’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):/opt/env/ffmpeg/libavcodec/libx264.c:249:  //跟着更多未定义的参考到 x264_encoder_reconfig
/usr/local/lib/libavcodec.a(libx264.o):在函数‘X264_close’中:
/opt/env/ffmpeg/libavcodec/libx264.c:686:对‘x264_param_cleanup’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:690:对‘x264_encoder_close’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):在函数‘parse_opts’中:
/opt/env/ffmpeg/libavcodec/libx264.c:702:对‘x264_param_parse’未定义的引用
/usr/local/lib/libavcodec.a(libx264.o):在函数‘X264_init’中:
/opt/env/ffmpeg/libavcodec/libx264.c:780:对‘x264_param_default’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:785:对‘x264_param_default_preset’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:810:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:844:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:876:对‘x264_levels’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:901:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:902:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:903:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:904:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:964:对‘x264_param_apply_fastfirstpass’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:1005:对‘x264_param_apply_profile’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:1093:对‘x264_param_parse’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:1113:对‘x264_encoder_open_164’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:1122:对‘x264_encoder_headers’未定义的引用
/opt/env/ffmpeg/libavcodec/libx264.c:1153:对‘x264_encoder_maximum_delayed_frames’未定义的引用
/usr/local/lib/libavfilter.a(vf_sharpen_npp.o):在函数‘nppsharpen_sharpen’中:
/opt/env/ffmpeg/libavfilter/vf_sharpen_npp.c:165:对‘nppiFilterSharpenBorder_8u_C1R’未定义的引用
/usr/local/lib/libavfilter.a(vf_transpose_npp.o):在函数‘npptranspose_transpose’中:
/opt/env/ffmpeg/libavfilter/vf_transpose_npp.c:332:对‘nppiTranspose_8u_C1R’未定义的引用
/usr/local/lib/libavfilter.a(vf_transpose_npp.o):在函数‘npptranspose_rotate’中:
/opt/env/ffmpeg/libavfilter/vf_transpose_npp.c:308:对‘nppiRotate_8u_C1R’未定义的引用
collect2: error: ld returned 1 exit status
make: *** [Makefile:356:multiview] 错误 1

这一下搞得天昏地暗,怪招频出, 1.百度,2.locate,3.yum search,4.nm,grep,bash散手
有的就是从批量库文件中找出来的,好,补充了下面这么多库,还剩一个未定义引用了.
LIBS += -lz -lX11 -lasound -lxcb-randr -lva -lva-drm -lva-x11 -lxcb -lxcb-xfixes -lxcb-shm -lxcb-shape -lx264 -lnppicc_static
这可都是自己亲自找的. 其中绝大部分库名字是我闻所未闻,只是望文生义猜加找出来的.我太难了!

不过这也就不用再怕"未定义引用了"
大概是连了nppicc_static库之后, 这是个nvidia-cuda库, 一下子跳出了几千个未定义引用, 我知道了它要把几百兆的cuda库都包含进去,
太shit了,果断放弃.

把上面的ffmeg 库全部改为动态连接.如下示:
LIBS += /opt/ffmpeg_build/lib/libavdevice.so
LIBS += /opt/ffmpeg_build/lib/libavfilter.so
LIBS += /opt/ffmpeg_build/lib/libswscale.so
LIBS += /opt/ffmpeg_build/lib/libpostproc.so
LIBS += /opt/ffmpeg_build/lib/libavformat.so
LIBS += /opt/ffmpeg_build/lib/libavcodec.so
LIBS += /opt/ffmpeg_build/lib/libswresample.so
LIBS += /opt/ffmpeg_build/lib/libavutil.so
一个依赖库都不用添加,直接编译通过!!
动态编译库连接没有顺序,你还可以简化成下面方式写:
LIBS += /opt/ffmpeg_build/lib/lib*.so  //你要确保不要多包含其它东西
这就是动态连接的好处!
当然,你发布的时候还要把它依赖的动态库一起发布(如果目标机没有安装这些基础库的话)

猜你喜欢

转载自blog.csdn.net/hejinjing_tom_com/article/details/129331007