这两天折腾了一下彻底静态编译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