天天看點

ffmpeg 純靜态編譯,以及添加自定義庫流程摘要

需求:

   1. 純靜态編譯ffmpeg ,即ldd ./ffmpeg 的結果是:not a dynamic executable

   2.  修改ffmpeg 項目,添加自定義功能庫

   3. 自定義庫由c++實作,要求能被純c的ffmpeg項目調用

   4. 自定義庫必須使用g++ 的一些進階特性編譯,要求g++支援c++11

   5. 自定義庫使用了pthread庫 和openmp 庫

   6. 自定義庫使用了opencv 3.0.0庫,

   7. 禁用所有的圖形顯示庫x11,xcb,聲音裝置avdevice等等,靜态連結這些庫,會很痛苦。

動手之前需要注意:

./configure *** --enable-shared=no --enable-static=yes --with-***=/dir

C.要求c++打包的庫能夠被ffmpeg的項目連結,要求libstdc++.a (-lstdc++);能夠使用openmp,要求libgomp.a ( -fopenmp); libstdc++.a可以通過yum install libstdc++-static得到,但是libgomp.a則沒有對應的方法。

綜合B和C的注意事項,我們應該自行編譯gcc,而不是使用系統自帶的gcc或者yum apt-get下載下傳安裝的,因為自行編譯gcc能夠直接得到libstdc++.a和libgomp.a這些靜态庫。我選用的版本是gcc4.8.4,同樣地配置它編譯出靜态庫。配套的Binutils也需要重新編譯。

D. glibc是GNU的标準C庫實作,如果要靜态連結glibc這些底層的庫_——libc.a,libm.a,librt.a,libdl.a,libpthread.a ,需要安裝glibc的靜态版本

#yum install glibc-static, 

#whereis libc.a(找到路徑)

#cp 路徑/libc.a ~mydir/(其它4個庫類似,重新拷貝到一個新的位置,以防連結時優先選擇動态連結,當然把這個路徑放在LDFLAGS最前面)

E.opencv 和ffmpeg在配置階段(分别使用cmake和configure),務必關閉所有的與圖形IO相關的依賴,因為圖形庫的靜态版本,太難找了,依賴關系特别冗長繁雜。

F. 最終連結ffmpeg時候,由于ffmpeg依賴了一些庫如x264,x265,freetype等,它們各自依賴了glibc的一些庫如librt,libm,libc,libdl。因而原始指令(#make -n|grep ffmpeg_g)中glibc的一些庫(libm,libc,librt,libdl,libpthread)被反複調用,分布于多個地方,如下:

 gcc  -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -L/home/ffmpeg/ffmpeg_sjtu/lib  -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample   -o ffmpeg_g cmdutils.o ffmpeg_opt.o ffmpeg_filter.o ffmpeg.o   -lavdevice -lavfilter -lavformat -lavcodec -lpostproc -lswresample -lswscale -lavutil  -L/home/ffmpeg/ffmpeg_build/lib -lx265 -lstdc++-lm -lrt -ldl -L/home/ffmpeg/ffmpeg_build/lib -lx264 -lpthread -lm -ldl -L/home/ffmpeg/ffmpeg_build/lib -lvpx -lm -lpthread -L/home/ffmpeg/ffmpeg_build/lib -lvpx -lm -lpthread -L/home/ffmpeg/ffmpeg_build/lib -lvpx -lm -lpthread -L/home/ffmpeg/ffmpeg_build/lib -lvpx -lm -lpthread -ltheoraenc -ltheoradec -logg -L/home/ffmpeg/ffmpeg_build/lib -lopus -lm -lmp3lame -L/home/ffmpeg/ffmpeg_build/lib -lfribidi -L/home/ffmpeg/ffmpeg_build/lib -lfreetype -lz -L/home/ffmpeg/ffmpeg_build/lib -lfontconfig -lxml2 -llzma -lm -lfreetype -lz -L/home/ffmpeg/ffmpeg_build/lib -lfdk-aac -lm -L/home/ffmpeg/ffmpeg_build/lib -lass -lharfbuzz -lfontconfig -lenca -lfribidi -lxml2 -llzma -lm -lfreetype -lz -lm -llzma -lbz2 -lz -pthread -lrt -lstdc++      -L/home/ffmpeg/sjtu_fruc/lib -lsjtu_fruc  -fopenmp   -L/usr/local/lib -L/usr/local/share/OpenCV/3rdparty/lib -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core -lopencv_hal -lzlib -llibjpeg -llibwebp -llibpng -llibtiff -llibjasper -ltbb -lippicv -lstdc++ -ldl -lm -lpthread -lrt   

是以,為了能夠靜态連結glibc的幾個庫,需要手動修改這條最終的連結指令:把所有glibc的庫放到最後,以如下方式:

 -lm -lrt -ldl  -lm -lpthread -lrt   -static -lc

注意,-static -lc (libc.a)必須放到最後(pthread之後),因為pthread和c庫有函數重定義的沖突。

這條語句最終為:

printf "LD\t%s\n" ffmpeg_g; gcc  -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -L/home/ffmpeg/ffmpeg_sjtu/lib  -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample   -o ffmpeg_g cmdutils.o ffmpeg_opt.o ffmpeg_filter.o ffmpeg.o   -lavdevice -lavfilter -lavformat -lavcodec -lpostproc -lswresample -lswscale -lavutil  -L/home/ffmpeg/ffmpeg_build/lib -lx265 -L/home/ffmpeg/ffmpeg_build/lib -lx264 -L/home/ffmpeg/ffmpeg_build/lib -lvpx  -L/home/ffmpeg/ffmpeg_build/lib -lvpx  -L/home/ffmpeg/ffmpeg_build/lib -lvpx  -L/home/ffmpeg/ffmpeg_build/lib -lvpx -ltheoraenc -ltheoradec -logg -L/home/ffmpeg/ffmpeg_build/lib -lopus -lmp3lame -L/home/ffmpeg/ffmpeg_build/lib -lfribidi -L/home/ffmpeg/ffmpeg_build/lib -lfreetype -lz -L/home/ffmpeg/ffmpeg_build/lib -lfontconfig -lxml2 -llzma -lfreetype -lz -L/home/ffmpeg/ffmpeg_build/lib -lfdk-aac -L/home/ffmpeg/ffmpeg_build/lib -lass -lharfbuzz -lfontconfig -lenca -lfribidi -lxml2 -llzma -lfreetype -lz  -llzma -lbz2 -lz   -L/home/ffmpeg/sjtu_fruc/lib -lsjtu_fruc  -fopenmp   -L/usr/local/lib -L/usr/local/share/OpenCV/3rdparty/lib -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core -lopencv_hal -lzlib -llibjpeg -llibwebp -llibpng -llibtiff -llibjasper -ltbb -lippicv -lstdc++ -lm -lrt -ldl  -lm -lpthread -lrt   -static -lc

盡管它執行會報出一些warnning,但是,不影響生成ffmpeg_g可執行檔案。

然後執行,

#cp ffmpeg_g ffmpeg

#strip ffmpeg

即可

測試ffmpeg