這兩天折騰了一下徹底靜態編譯ffmpeg,指望經過這種方式實現編譯出來的ffmpeg可以在各個linux發現版上運行。進而能夠延伸到編譯出來徹底靜態的依賴ffmpeg庫的應用程序,從而簡化產品在各個linux發行版的產品編譯和部署區分,減小開發和維護成本。linux
通過嘗試,最終確實編譯出來徹底靜態的ffmpeg,可是也發現了隱患,具體在"一些問題"中描述。因此,我對徹底靜態編譯持保留意見,須要根據實際的使用狀況來定。下面的文字,就是我整理的本次嘗試的要點了。c++
首先,查看一下以前編譯出來的ffmpeg的動態庫連接狀況。能夠看出它連接了許多動態庫,這些庫有些是系統自帶的,有的須要本身安裝。redis
[root@root tmp]# ldd ffmpeg linux-vdso.so.1 => (0x00007fff133fe000) libm.so.6 => /lib64/libm.so.6 (0x00007fb094f81000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb094d65000) librt.so.1 => /lib64/librt.so.1 (0x00007fb094b5c000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fb094958000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fb094650000) libnuma.so.1 => /lib64/libnuma.so.1 (0x00007fb094444000) liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fb09421f000) libbz2.so.1 => /lib64/libbz2.so.1 (0x00007fb09400f000) libz.so.1 => /lib64/libz.so.1 (0x00007fb093df8000) libc.so.6 => /lib64/libc.so.6 (0x00007fb093a36000) /lib64/ld-linux-x86-64.so.2 (0x00007fb09528c000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb093820000)
而徹底靜態的ffmepg是這樣的:shell
[root@root tmp]# ldd ffmpeg not a dynamic executable
下面就是靜態編譯的要點,具體能夠參考文檔結尾附的編譯腳本內容。api
1.1 安裝標準靜態庫bash
安裝linux c標準庫: yum install glibc-staticapp
安裝stdc++靜態庫: yum install libstdc++-static函數
1.2 編譯第三方靜態庫post
ffmpeg一般會使用一些第三方庫,例如: x264, x265, libfdk-aac等。這些第三方庫一般都是能夠經過configure配置(--enable-static=yes --enable-shared=no)控制產生靜態庫,不建立動態庫。對於一些沒有configure的庫,其實也是有編譯出靜態庫的方法,注意發現就OK。該過程的編譯腳本,能夠參考文後附的編譯腳本內容。測試
1.3 編譯靜態ffmpeg
具體的configure配置,能夠參考附的編譯腳本內容。
在編譯過程當中遇到的大部分問題都是連接庫出錯,對於這種問題,基本就是安裝或編譯須要的靜態庫,偶爾也多是庫的順序問題。
不過,在嘗試編譯支持nvenc的時候,出現了warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking警示信息,由於已經編譯出靜態文件,因此當時並無在乎。不過在後來的測試中,發如今使用nvenc環境進行nvenc編解碼操做的的時候,程序會段錯誤。原來,像"dlopen"這樣的函數,是依賴運行環境的,須要使用運行環境的動態庫。故,徹底靜態編譯存在這樣的隱患,就是有些函數依賴運行環境的動態庫(其實這些庫自己也是爲了兼容性,不一樣平臺提供相同的接口),因此,標準庫除非要求,不然儘可能使用動態庫吧。
ffmpeg: http://pan.baidu.com/s/1kVfOY7H
ffprobe: http://pan.baidu.com/s/1boS8cJt
#!/bin/bash set -e current_dir=$(cd ../; pwd -P) build_dir="${current_dir}/_build" release_dir="${current_dir}/_release" echo "start to build the tools for transcode system(current_dir: ${current_dir}, build_dir: ${build_dir}, release_dir: ${release_dir})..." mkdir -p ${build_dir} mkdir -p ${release_dir} cp -rf yasm-1.3.0.tar.gz fdk-aac-0.1.4.tar.gz faac-1.28.tar.bz2 lame-3.98.4.tar.gz opencore-amr-0.1.2.tar.gz x264-snapshot-20140803-2245.tar.bz2 x265_1.9.tar.gz ${build_dir} cp -rf libxml2-2.9.4.tar.gz libpng-1.6.24.tar.xz freetype-2.7.tar.bz2 fribidi-0.19.7.tar.bz2 fontconfig-2.12.1.tar.bz2 libass-0.13.2.tar.gz ffmpeg-3.0.1.tar.bz2 ${build_dir} cp -rf zlib-1.2.8.tar.gz bzip2-1.0.6.tar.gz libevent-2.0.22-stable.tar.gz xz-5.2.2.tar.gz numactl_2.0.8.orig.tar.gz ${build_dir} export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:${release_dir}/lib/pkgconfig export PATH=${PATH}:${release_dir}/bin # libaacplus not support in ffmpeg3.0.1 # yasm pushd ${build_dir} if ! [ -e "yasm" ] then echo "########## yasm begin ##########" if ! [ -e "yasm-1.3.0.tar.gz" ] then # download yasm echo "########## to download yasm ##########" wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz fi tar xf yasm-1.3.0.tar.gz pushd yasm-1.3.0 ./configure --prefix=${release_dir} make make install popd touch yasm echo "########## yasm ok ##########" else echo "########## yasm has been installed ##########" fi popd # libevent pushd ${build_dir} if ! [ -e "libevent" ] then echo "########## libevent begin ##########" tar xf libevent-2.0.22-stable.tar.gz pushd libevent-2.0.22-stable ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch libevent echo "########## libevent ok ##########" else echo "########## libevent has been installed ##########" fi popd # libz pushd ${build_dir} if ! [ -e "zlib" ] then echo "########## zlib begin ##########" # wget http://zlib.net/zlib-1.2.8.tar.gz tar xf zlib-1.2.8.tar.gz pushd zlib-1.2.8 ./configure --prefix=${release_dir} --static make make install popd touch zlib echo "########## zlib ok ##########" else echo "########## zlib has been installed ##########" fi popd # libbz2 pushd ${build_dir} if ! [ -e "libbz2" ] then echo "########## libbz2 begin ##########" # wget http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz tar xf bzip2-1.0.6.tar.gz pushd bzip2-1.0.6 make PREFIX=${release_dir} make PREFIX=${release_dir} install popd touch libbz2 echo "########## libbz2 ok ##########" else echo "########## libbz2 has been installed ##########" fi popd # fdk-aac pushd ${build_dir} if ! [ -e "fdk-aac" ] then echo "########## fdk-aac begin ##########" tar xf fdk-aac-0.1.4.tar.gz pushd fdk-aac-0.1.4 ./autogen.sh ./configure --prefix=${release_dir} make make install popd touch fdk-aac echo "########## fdk-aac ok ##########" else echo "########## fdk-aac has been installed ##########" fi popd # libfaac pushd ${build_dir} if ! [ -e "faac" ] then echo "########## libfaac begin ##########" tar xf faac-1.28.tar.bz2 pushd faac-1.28 ./configure --prefix=${release_dir} --enable-static --without-mp4v2 make make install popd touch faac echo "########## libfaac ok ##########" else echo "########## libfaac has been installed ##########" fi popd # libmp3lame pushd ${build_dir} if ! [ -e "mp3lame" ] then echo "########## libmp3lame begin ##########" tar xf lame-3.98.4.tar.gz pushd lame-3.98.4 ./configure --prefix=${release_dir} --enable-static make make install popd touch mp3lame echo "########## libmp3lame ok ##########" else echo "########## libmp3lame has been installed ##########" fi popd # libopencore_amrnb pushd ${build_dir} if ! [ -e "opencore_amrnb" ] then echo "########## libopencore_amrnb begin ##########" tar xf opencore-amr-0.1.2.tar.gz pushd opencore-amr-0.1.2 ./configure --prefix=${release_dir} --enable-static make make install popd touch opencore_amrnb echo "########## libopencore_amrnb ok ##########" else echo "########## libopencore_amrnb has been installed ##########" fi popd # libx264 pushd ${build_dir} if ! [ -e "x264" ] then echo "########## libx264 begin ##########" tar xf x264-snapshot-20140803-2245.tar.bz2 pushd x264-snapshot-20140803-2245 ./configure --prefix=${release_dir} --enable-static --disable-opencl sed -i -e 's/-s //' -e 's/-s$//' config.mak make make install popd touch x264 echo "########## libx264 ok ##########" else echo "########## libx264 has been installed ##########" fi popd # libnuma (for x265) pushd ${build_dir} if ! [ -e "numa" ] then if ! [ -e "numactl_2.0.8.orig.tar.gz" ] then # download yasm echo "########## to download numa ##########" wget http://numactl.sourcearchive.com/downloads/2.0.8/numactl_2.0.8.orig.tar.gz fi tar xf numactl_2.0.8.orig.tar.gz pushd numactl-2.0.8 make PREFIX=${release_dir} make PREFIX=${release_dir} install rm -rf ${release_dir}/lib64/libnuma.so* popd touch numa echo "########## numa ok ##########" else echo "########## numa has been built ##########" fi popd # libx265 pushd ${build_dir} if ! [ -e "x265" ] then echo "########## libx265 begin ##########" # download page: https://bitbucket.org/multicoreware/x265/downloads tar xf x265_1.9.tar.gz pushd x265_1.9 cmake ./source -DCMAKE_INSTALL_PREFIX=${release_dir} -DBUILD_SHARED_LIBS=OFF make make install popd touch x265 echo "########## libx265 ok ##########" else echo "########## libx265 has been installed ##########" fi popd # lzma (requried by ffmpeg drawtext) pushd ${build_dir} if ! [ -e "lzma" ] then echo "########## lzma begin ##########" tar xf xz-5.2.2.tar.gz pushd xz-5.2.2 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch lzma echo "########## lzma ok ##########" else echo "########## lzma has been installed ##########" fi popd # libpng (requried by freetype) pushd ${build_dir} if ! [ -e "libpng" ] then echo "########## libpng begin ##########" echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* tar xf libpng-1.6.24.tar.xz pushd libpng-1.6.24 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch libpng echo "########## libpng ok ##########" else echo "########## libpng has been installed ##########" fi popd # libxml2 (requried by fontconfig) pushd ${build_dir} if ! [ -e "libxml2" ] then echo "########## libxml2 begin ##########" echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* tar xf libxml2-2.9.4.tar.gz pushd libxml2-2.9.4 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch libxml2 echo "########## libxml2 ok ##########" else echo "########## libxml2 has been installed ##########" fi popd # freetype (requried by libass) pushd ${build_dir} if ! [ -e "freetype" ] then echo "########## freetype begin ##########" echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* # wget http://downloads.sourceforge.net/freetype/freetype-2.7.tar.bz2 tar xf freetype-2.7.tar.bz2 pushd freetype-2.7 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch freetype echo "########## freetype ok ##########" else echo "########## freetype has been installed ##########" fi popd # fribidi (requried by libass) pushd ${build_dir} if ! [ -e "fribidi" ] then echo "########## fribidi begin ##########" echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* tar xf fribidi-0.19.7.tar.bz2 pushd fribidi-0.19.7 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch fribidi echo "########## fribidi ok ##########" else echo "########## fribidi has been installed ##########" fi popd # fontconfig (requried by libass) pushd ${build_dir} if ! [ -e "fontconfig" ] then echo "########## fontconfig begin ##########" echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* tar xf fontconfig-2.12.1.tar.bz2 pushd fontconfig-2.12.1 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no --enable-libxml2 make make install popd touch fontconfig echo "########## fontconfig ok ##########" else echo "########## fontconfig has been installed ##########" fi popd # libass pushd ${build_dir} if ! [ -e "libass" ] then echo "########## libass begin ##########" echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* tar xf libass-0.13.2.tar.gz pushd libass-0.13.2 ./configure --prefix=${release_dir} --enable-static=yes --enable-shared=no make make install popd touch libass echo "########## libass ok ##########" else echo "########## libass has been installed ##########" fi popd # ffmpeg pushd ${build_dir} if ! [ -e "ffmpeg3.0.1" ] then echo "########## ffmepg begin ##########" set -x if ! [ -d "ffmpeg-3.0.1" ] then tar xf ffmpeg-3.0.1.tar.bz2 fi echo "remove all so to force the ffmpeg to build in static" rm -f ${release_dir}/lib/*.so* pushd ffmpeg-3.0.1 export ffmpeg_exported_release_dir=${release_dir} echo ${ffmpeg_exported_release_dir}/include echo ${ffmpeg_exported_release_dir}/lib ./configure --prefix=${release_dir} --cc=$CC \ --extra-cflags="-I${release_dir}/include -I${release_dir}/include/hiredis" \ --extra-ldflags="-L${release_dir}/lib -L${release_dir}/lib64 -ldl -lm -lpthread -lrt -lstdc++ -static" \ --pkg-config-flags="--static" \ --enable-gpl --enable-static --enable-nonfree --enable-version3 --disable-ffplay --disable-ffserver \ --enable-postproc \ --enable-demuxer=oss \ --disable-vaapi --disable-indev=alsa --disable-outdev=alsa \ --enable-libopencore-amrnb --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libfaac --enable-libfdk-aac \ --enable-libass --enable-libfreetype --enable-libfontconfig --enable-libfribidi \ --extra-libs=-lhiredis --extra-libs=-lnuma --extra-libs=-levent #--extra-libs=-lstdc++ --extra-libs=-lc echo "ffmpeg3.0.1 begin make" make make install popd #touch ffmpeg3.0.1 echo "########## ffmpeg3.0.1 ok ##########" else echo "########## ffmpeg3.0.1 has been installed ##########" fi popd