静态编译ffmpeg

我只是一个虾纸丫 提交于 2019-12-10 15:31:40

静态编译ffmpeg

这两天折腾了一下完全静态编译ffmpeg,期望通过这种方式实现编译出来的ffmpeg能够在各个linux发现版上运行。进而可以延伸到编译出来完全静态的依赖ffmpeg库的应用程序,从而简化产品在各个linux发行版的产品编译和部署区分,减少开发和维护成本。

经过尝试,最终确实编译出来完全静态的ffmpeg,但是也发现了隐患,具体在"一些问题"中描述。所以,我对完全静态编译持保留意见,需要根据实际的使用情况来定。下面的文字,就是我整理的本次尝试的要点了。

1. 静态编译

首先,查看一下之前编译出来的ffmpeg的动态库链接情况。可以看出它链接了许多动态库,这些库有些是系统自带的,有的需要自己安装。

[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是这样的:

[root@root tmp]# ldd ffmpeg
    not a dynamic executable

下面就是静态编译的要点,具体可以参考文档结尾附的编译脚本内容。

1.1 安装标准静态库

安装linux c标准库: yum install glibc-static

安装stdc++静态库: yum install libstdc++-static

1.2 编译第三方静态库

ffmpeg通常会使用一些第三方库,例如: x264, x265, libfdk-aac等。这些第三方库通常都是可以通过configure配置(--enable-static=yes --enable-shared=no)控制产生静态库,不创建动态库。对于一些没有configure的库,其实也是有编译出静态库的方法,注意发现就OK。该过程的编译脚本,可以参考文后附的编译脚本内容。

1.3 编译静态ffmpeg

具体的configure配置,可以参考附的编译脚本内容。

2. 一些问题

在编译过程中遇到的大部分问题都是链接库出错,对于这种问题,基本就是安装或编译需要的静态库,偶尔也可能是库的顺序问题。

不过,在尝试编译支持nvenc的时候,出现了warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking警示信息,因为已经编译出静态文件,所以当时并没有在意。不过在后来的测试中,发现在使用nvenc环境进行nvenc编解码操作的的时候,程序会段错误。原来,像"dlopen"这样的函数,是依赖运行环境的,需要使用运行环境的动态库。故,完全静态编译存在这样的隐患,就是有些函数依赖运行环境的动态库(其实这些库本身也是为了兼容性,不同平台提供相同的接口),所以,标准库除非要求,否则尽量使用动态库吧。

3. 附静态ffmpeg下载

ffmpeg: http://pan.baidu.com/s/1kVfOY7H

ffprobe: http://pan.baidu.com/s/1boS8cJt

4. 附静态ffmpeg编译脚本

#!/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



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!