• vmware虚拟机下ubuntu 13.04使用zeranoe脚本交叉编译ffmpeg


    2013-07-01
    今天是建党节,习总书记指出,党的建设要以“照镜子、正衣冠、洗洗澡、治治病”为总要求。希望我们的党越来越纯洁,为人民谋福利。
    言归正传,每次项目中需要编译相应的ffmpeg,都很费时费力。这次记录下全过程,以便下次使用。
    windows下使用msys编译比较麻烦,而且由于安装了很多开源库,导致系统变量很复杂,容易出错。
    本次选择在ubuntu下使用zeranoe的脚本交叉编译,windows下使用的ffmpeg动态库。

    环境:ubuntu 13.04,vmware 8.0.2 build-591240
    ubuntu是在官网下载了镜像文件,通过vmware虚拟机安装后,没有更新直接使用。
    主要工具以及版本号:
    gcc 3.7.4
    make 3.8.1
    cmake 2.8.10.1
    automake 1.11.6
    yasm 1.2.0
    makeinfo 4.13
    curl 7.29.0
    pkg-config 0.26
    audoconf 2.69
    libtool 2.4.2
    flex 2.5.35
    bison 2.5

    明确需求:本次项目中需要ffmpeg帮助编解码,要求编译第三方的libaacplus和libx264.生成动态库,尽可能小,以便于软件打包。

    1. 首先下载 cross_compile_ffmpeg.sh ,本次下载的git上一个月以前更新的。
       地址在 https://github.com/rdp/ffmpeg-windows-build-helpers

       如果网络允许的话,可以直接运行
       a> $ wget https://raw.github.com/rdp/ffmpeg-windows-build-helpers/master/cross_compile_ffmpeg.sh -O cross_compile_ffmpeg.sh
       b> $ chmod u+x cross_compile_ffmpeg.sh
       c> $ ./cross_compile_ffmpeg.sh
       但是这种方法,往往会提示https……失败,换http或者git都失败。还是老老实实地下载了吧。
    2. 下载下来的 cross_compile_ffmpeg.sh 放到主目录下cross_compile_ffmpeg文件夹里。
       我的目录结构是这样的 /home/gong/cross_compile_ffmpeg/cross_compile_ffmpeg.sh
    3. 更改 cross_compile_ffmpeg.sh 的属性,使其可以执行。并执行它。
       $ chmod u+x cross_compile_ffmpeg.sh
       $ ./cross_compile_ffmpeg.sh
       如果提示某些命令没有安装,例如 'curl' 'pkg-config' 'make' 'git' 'svn' 'cmake' 'gcc' 'autoconf' 'libtool' 'automake' 'yasm' 'cvs' 'flex' 'bison' 'makeinfo'
       中的某一个。直接 sudo apt-get install xxx 对应安装即可。


    4. 一般来说上一步执行肯定会出错,但是会在 cross_compile_ffmpeg文件夹里生成一个sandbox的文件夹,这个文件夹里面有一个名为 mingw-w64-build-3.2.0 的文件(cross_compile_ffmpeg.sh里有下载该文件的语句)。
       会在脚本里被执行,下载安装我们本次编译需要的工具。我看到官网http://ffmpeg.zeranoe.com/blog/ 已经更新到 mingw-w64-build-3.2.3 了。但是 cross_compile_ffmpeg.sh 脚本里还是指定的是3.2.0版本。
       工具编译完成后,生成在路径/home/gong/cross_compile_ffmpeg/sandbox/mingw-w64-i686/i686-w64-mingw32/bin 下。
    5. 按照本次项目需求,更改脚本,中间会经历千万曲折,反复修改编译选项。最终脚本如下

    #!/usr/bin/env bash
    ################################################################################
    # ffmpeg windows cross compile helper/downloader script
    ################################################################################
    # Copyright (C) 2012 Roger Pack
    #
    # This program is free software: you can redistribute it and/or modify it under
    # the terms of the GNU General Public License as published by the Free Software
    # Foundation, either version 3 of the License, or (at your option) any later
    # version.
    #
    # This program is distributed in the hope that it will be useful, but WITHOUT
    # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    # details.
    #
    # You should have received a copy of the GNU General Public License along with
    # this program.  If not, see <http://www.gnu.org/licenses/>.
    #
    # The GNU General Public License can be found in the LICENSE file.
    
    yes_no_sel () {
    unset user_input
    local question="$1"
    shift
    while [[ "$user_input" != [YyNn] ]]; do
      echo -n "$question"
      read user_input
      if [[ "$user_input" != [YyNn] ]]; then
        clear; echo 'Your selection was not vaild, please try again.'; echo
      fi
    done
    # downcase it
    user_input=$(echo $user_input | tr '[A-Z]' '[a-z]')
    }
    
    check_missing_packages () {
    local check_packages=('curl' 'pkg-config' 'make' 'git' 'svn' 'cmake' 'gcc' 'autoconf' 'libtool' 'automake' 'yasm' 'cvs' 'flex' 'bison' 'makeinfo')
    for package in "${check_packages[@]}"; do
      type -P "$package" >/dev/null || missing_packages=("$package" "${missing_packages[@]}")
    done
    
    if [[ -n "${missing_packages[@]}" ]]; then
      clear
      echo "Could not find the following execs: ${missing_packages[@]}"
      echo 'Install the missing packages before running this script.'
      exit 1
    fi
    
    local out=`cmake --version` # like cmake version 2.8.7
    local version_have=`echo "$out" | cut -d " " -f 3`
    
    function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d
    ", $1,$2,$3,$4); }'; }
    
    if [[ $(version $version_have)  < $(version '2.8.10') ]]; then
      echo "your cmake version is too old $version_have wanted 2.8.10"
      exit 1
    fi
    
    }
    
    
    cur_dir="$(pwd)/sandbox"
    cpu_count="$(grep -c processor /proc/cpuinfo)" # linux only <sigh>
    if [ -z "$cpu_count" ]; then
      cpu_count=`sysctl -n hw.ncpu | tr -d '
    '` # OS X
      if [ -z "$cpu_count" ]; then
        echo "warning, unable to determine cpu count, defaulting to 1"
        cpu_count=1 # boxes where we don't know how to determine cpu count [OS X for instance], default to just 1, instead of blank, which means infinite 
      fi
    fi
    original_cpu_count=$cpu_count # save it away for some that revert it temporarily
    
    intro() {
      cat <<EOL
         ##################### Welcome ######################
      Welcome to the ffmpeg cross-compile builder-helper script.
      Downloads and builds will be installed to directories within $cur_dir
      If this is not ok, then exit now, and cd to the directory where you'd
      like them installed, then run this script again from there.  
      NB that once you build your compilers, you can no longer rename/move
      the sandbox directory, since it will have some hard coded paths in there.
      You can, of course, rebuild ffmpeg from within it, etc.
    EOL
      if [[ $sandbox_ok != 'y' ]]; then
        yes_no_sel "Is ./sandbox ok (requires ~ 5GB space) [y/n]?"
        if [[ "$user_input" = "n" ]]; then
          exit 1
        fi
      fi
      mkdir -p "$cur_dir"
      cd "$cur_dir"
      if [[ $disable_nonfree = "y" ]]; then
        non_free="n"
      else
        yes_no_sel "Would you like to include non-free (non GPL compatible) libraries, like many aac encoders
    The resultant binary will not be distributable, but might be useful for in-house use. Include non-free [y/n]?"
        non_free="$user_input" # save it away
      fi
    
      #yes_no_sel "Would you like to compile with -march=native, which can get a few percent speedup
    #but also makes it so you cannot distribute the binary to machines of other architecture/cpu 
    #(also note that you should only enable this if compiling on a VM on the same box you intend to target, otherwise
    #it makes no sense)  Use march=native? THIS IS JUST EXPERIMENTAL AND DOES NOT WORK FULLY YET--choose n typically. [y/n]?" 
      #march_native="$user_input"
    }
    
    pick_compiler_flavors() {
    
    while [[ "$build_choice" != [1-3] ]]; do
    if [[ -n "${unknown_opts[@]}" ]]; then
      echo -n 'Unknown option(s)'
      for unknown_opt in "${unknown_opts[@]}"; do
        echo -n " '$unknown_opt'"
      done
      echo ', ignored.'; echo
    fi
    cat <<'EOF'
    What version of MinGW-w64 would you like to build or update?
      1. Both Win32 and Win64
      2. Win32 (32-bit only)
      3. Win64 (64-bit only)
      4. Exit
    EOF
    echo -n 'Input your choice [1-5]: '
    read build_choice
    done
    case "$build_choice" in
      1 ) build_choice=multi ;;
      2 ) build_choice=win32 ;;
      3 ) build_choice=win64 ;;
      4 ) exit 0 ;;
      * ) clear;  echo 'Your choice was not valid, please try again.'; echo ;;
    esac
    }
    
    install_cross_compiler() {
      if [[ -f "mingw-w64-i686/compiler.done" || -f "mingw-w64-x86_64/compiler.done" ]]; then
       echo "MinGW-w64 compiler of some type or other already installed, not re-installing..."
       if [[ $rebuild_compilers != "y" ]]; then
         return # early exit
       fi
      fi
    
      pick_compiler_flavors 
      curl https://raw.github.com/rdp/ffmpeg-windows-build-helpers/master/patches/mingw-w64-build-3.2.0 -O  || exit 1
      chmod u+x mingw-w64-build-3.2.0
      # requires mingw-w64 svn: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55706
      # cpu count 1 because otherwise with 945 MB RAM it can segfault ?
      nice ./mingw-w64-build-3.2.0 --mingw-w64-ver=svn --disable-shared --default-configure --clean-build --cpu-count=1 --threads=pthreads-w32 --pthreads-w32-ver=2-9-1 --build-type=$build_choice || exit 1 # --disable-shared allows c++ to be distributed at all...which seemed necessary for some random dependency...
    
      if [ -d mingw-w64-x86_64 ]; then
        touch mingw-w64-x86_64/compiler.done
      fi
      if [ -d mingw-w64-i686 ]; then
        touch mingw-w64-i686/compiler.done
      fi
      clear
      echo "Ok, done building MinGW-w64 cross-compiler..."
    }
    
    setup_env() {
      export PKG_CONFIG_LIBDIR= # disable pkg-config from reverting back to and finding system installed packages [yikes]
    }
    
    do_svn_checkout() {
      repo_url="$1"
      to_dir="$2"
      if [ ! -d $to_dir ]; then
        echo "svn checking out to $to_dir"
        svn checkout $repo_url $to_dir.tmp || exit 1
        mv $to_dir.tmp $to_dir
      else
        cd $to_dir
        echo "not svn Updating $to_dir since usually svn repo's aren't frequently updated..."
        # svn up
        cd ..
      fi
    }
    
    update_to_desired_branch_or_revision() {
      local to_dir="$1"
      local desired_branch="$2"
      if [ -n "$desired_branch" ]; then
       pushd $to_dir
       cd $to_dir
          echo "git co $desired_branch"
          git checkout  "$desired_branch" || exit 1
          git merge "$desired_branch" || exit 1 # depending on which type it is :)
       popd # in case it's a cd to ., don't want to cd to .. here...
      fi
    }
    
    do_git_checkout() {
      local repo_url="$1"
      local to_dir="$2"
      local desired_branch="$3"
      if [ ! -d $to_dir ]; then
        echo "Downloading (via git clone) $to_dir"
        # prevent partial checkouts by renaming it only after success
        git clone $repo_url $to_dir.tmp || exit 1
        mv $to_dir.tmp $to_dir
        echo "done downloading $to_dir"
        update_to_desired_branch_or_revision $to_dir $desired_branch
      else
        cd $to_dir
        echo "Updating to latest $to_dir version..."
        old_git_version=`git rev-parse HEAD`
        git pull # if you comment out, add an echo :)
        update_to_desired_branch_or_revision "." $desired_branch
        new_git_version=`git rev-parse HEAD`
        if [[ "$old_git_version" != "$new_git_version" ]]; then
         echo "got upstream changes, forcing re-configure."
         rm already*
        else
         echo "this pull got no new upstream changes, possibly not forcing re-configure..."
        fi 
        cd ..
      fi
    }
    
    get_small_touchfile_name() { # have to call with assignment like a=$(get_small...)
      local beginning="$1"
      local extra_stuff="$2"
      local touch_name="${beginning}_$(echo -- $extra_stuff | /usr/bin/env md5sum)" # make it smaller
      touch_name=$(echo $touch_name | sed "s/ //g") # md5sum introduces spaces, remove them
      echo $touch_name # bash cruddy return system LOL
    } 
    
    do_configure() {
      local configure_options="$1"
      local configure_name="$2"
      if [[ "$configure_name" = "" ]]; then
        configure_name="./configure"
      fi
      local cur_dir2=$(pwd)
      local english_name=$(basename $cur_dir2)
      local touch_name=$(get_small_touchfile_name already_configured "$configure_options")
      if [ ! -f "$touch_name" ]; then
        make clean # just in case
        #make uninstall # does weird things when run under ffmpeg src
        if [ -f bootstrap.sh ]; then
          ./bootstrap.sh
        fi
        rm -f already_* # reset
        echo "configuring $english_name as $ PATH=$PATH $configure_name $configure_options"
        nice "$configure_name" $configure_options || exit 1
        touch -- "$touch_name"
        make clean # just in case
      else
        echo "already configured $(basename $cur_dir2)" 
      fi
    }
    
    do_make() {
      local extra_make_options="$1 -j $cpu_count"
      local cur_dir2=$(pwd)
      local touch_name=$(get_small_touchfile_name already_ran_make "$extra_make_options")
    
      if [ ! -f $touch_name ]; then
        echo "making $cur_dir2 as $ PATH=$PATH make $extra_make_options"
        nice make $extra_make_options || exit 1
        touch $touch_name
      else
        echo "already did make $(basename "$cur_dir2")"
      fi
    }
    
    do_make_install() {
      local extra_make_options="$1"
      do_make "$extra_make_options"
      local touch_name=$(get_small_touchfile_name already_ran_make_install "$extra_make_options")
      if [ ! -f $touch_name ]; then
        echo "make installing $cur_dir2 as $ PATH=$PATH make install $extra_make_options"
        nice make install $extra_make_options || exit 1
        touch $touch_name
      fi
    }
    
    build_x264() {
      #do_git_checkout "git://git.videolan.org/x264.git" "x264" "origin/stable"
      cd x264
      # TODO remove the no-aggressive-loop ... should be unneeded now
      do_configure "--extra-cflags=-fno-aggressive-loop-optimizations --host=$host_target  --enable-shared --disable-cli --disable-asm --cross-prefix=$cross_prefix --prefix=$mingw_w64_x86_64_prefix --enable-win32thread" # --enable-win32thread --enable-debug shouldn't hurt us since ffmpeg strips it anyway
    # no-aggressive ref: https://ffmpeg.org/trac/ffmpeg/ticket/2310
      # TODO more march=native here?
      # rm -f already_ran_make # just in case the git checkout did something, re-make
      do_make_install
      cd ..
    }
    
    
    build_librtmp() {
      #  download_and_unpack_file http://rtmpdump.mplayerhq.hu/download/rtmpdump-2.3.tgz rtmpdump-2.3 # has some odd configure failure
      #  cd rtmpdump-2.3/librtmp
    
      do_git_checkout "http://repo.or.cz/r/rtmpdump.git" rtmpdump_git 883c33489403ed360a01d1a47ec76d476525b49e # trunk didn't build once...this one i sstable
      cd rtmpdump_git/librtmp
      do_make_install "CRYPTO=GNUTLS OPT=-O2 CROSS_COMPILE=$cross_prefix SHARED=no prefix=$mingw_w64_x86_64_prefix"
      #make install CRYPTO=GNUTLS OPT='-O2 -g' "CROSS_COMPILE=$cross_prefix" SHARED=no "prefix=$mingw_w64_x86_64_prefix" || exit 1
      sed -i 's/-lrtmp -lz/-lrtmp -lwinmm -lz/' "$PKG_CONFIG_PATH/librtmp.pc"
      cd ../..
    }
    
    build_libsoxr() {
      download_and_unpack_file http://sourceforge.net/projects/soxr/files/soxr-0.1.0-Source.tar.xz soxr-0.1.0-Source # not /download since apparently some tar's can't untar it without an extension?
      cd soxr-0.1.0-Source
        cmake . -DENABLE_STATIC_RUNTIME=1 -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_RANLIB=${cross_prefix}ranlib -DCMAKE_C_COMPILER=${cross_prefix}gcc -DCMAKE_CXX_COMPILER=${cross_prefix}g++ -DCMAKE_RC_COMPILER=${cross_prefix}windres  -DCMAKE_INSTALL_PREFIX=$mingw_w64_x86_64_prefix -DHAVE_WORDS_BIGENDIAN_EXITCODE=0  -DBUILD_SHARED_LIBS:bool=off || exit 1
        # BUILD_TESTS:BOOL=ON instead of the below?
        rm -rf tests # disable tests. Is there another way?
        mkdir tests
        touch tests/CMakeLists.txt
        do_make_install
      cd ..
    }
    
    build_libxavs() {
      do_svn_checkout https://xavs.svn.sourceforge.net/svnroot/xavs/trunk xavs
      cd xavs
        export LDFLAGS='-lm'
        generic_configure "--cross-prefix=$cross_prefix" # see https://github.com/rdp/ffmpeg-windows-build-helpers/issues/3
        unset LDFLAGS
        do_make_install "CC=$(echo $cross_prefix)gcc AR=$(echo $cross_prefix)ar PREFIX=$mingw_w64_x86_64_prefix RANLIB=$(echo $cross_prefix)ranlib STRIP=$(echo $cross_prefix)strip"
      cd ..
    }
    
    build_libopenjpeg() {
      download_and_unpack_file http://openjpeg.googlecode.com/files/openjpeg_v1_4_sources_r697.tgz openjpeg_v1_4_sources_r697
      cd openjpeg_v1_4_sources_r697
      generic_configure
      sed -i "s//usr/lib/$(libdir)/" Makefile # install pkg_config to the right dir...
      cpu_count=1 # this one can't build multi-threaded <sigh> kludge
      do_make_install
      cpu_count=$original_cpu_count
      cd .. 
    
      #download_and_unpack_file http://openjpeg.googlecode.com/files/openjpeg-2.0.0.tar.gz openjpeg-2.0.0
      #cd openjpeg-2.0.0
      # cmake .  -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_RANLIB=${cross_prefix}ranlib -DCMAKE_C_COMPILER=${cross_prefix}gcc -DCMAKE_CXX_COMPILER=${cross_prefix}g++ -DCMAKE_RC_COMPILER=${cross_prefix}windres  -DCMAKE_INSTALL_PREFIX=$mingw_w64_x86_64_prefix -DBUILD_SHARED_LIBS:bool=off
      # do_make_install
      # cp $mingw_w64_x86_64_prefix/lib/libopenjp2.a $mingw_w64_x86_64_prefix/lib/libopenjpeg.a || exit 1
      # cp $mingw_w64_x86_64_prefix/include/openjpeg-2.0/* $mingw_w64_x86_64_prefix/include || exit 1
      #cd ..
    }
    
    build_libvpx() {
      do_git_checkout https://git.chromium.org/git/webm/libvpx.git "libvpx_git" 2d13e7b33e1ee
      cd libvpx_git
      export CROSS="$cross_prefix"
      if [[ "$bits_target" = "32" ]]; then
        do_configure "--extra-cflags=-DPTW32_STATIC_LIB --target=x86-win32-gcc --prefix=$mingw_w64_x86_64_prefix --enable-static --disable-shared"
      else
        do_configure "--extra-cflags=-DPTW32_STATIC_LIB --target=x86_64-win64-gcc --prefix=$mingw_w64_x86_64_prefix --enable-static --disable-shared "
      fi
      do_make_install
      unset CROSS
      cd ..
    }
    
    apply_patch() {
     local url=$1
     local patch_name=$(basename $url)
     local patch_done_name="$patch_name.done"
     if [[ ! -e $patch_done_name ]]; then
       curl $url -O || exit 1
       patch -p0 < "$patch_name" || exit 1
       touch $patch_done_name
     else
       echo "patch $patch_name already applied"
     fi
    }
    
    build_libutvideo() {
      download_and_unpack_file https://github.com/downloads/rdp/FFmpeg/utvideo-11.1.1-src.zip utvideo-11.1.1
      cd utvideo-11.1.1
        apply_patch https://raw.github.com/rdp/ffmpeg-windows-build-helpers/master/patches/utv.diff
        do_make_install "CROSS_PREFIX=$cross_prefix DESTDIR=$mingw_w64_x86_64_prefix prefix=" # prefix= to avoid it adding an extra /usr/local to it yikes
      cd ..
    }
    
    download_and_unpack_file() {
      url="$1"
      output_name=$(basename $url)
      output_dir="$2"
      if [ ! -f "$output_dir/unpacked.successfully" ]; then
        curl "$url" -O -L || exit 1
        tar -xf "$output_name" || unzip $output_name || exit 1
        touch "$output_dir/unpacked.successfully" || exit 1
        rm "$output_name"
      fi
    }
    
    generic_configure() {
      local extra_configure_options="$1"
      do_configure "--host=$host_target --prefix=$mingw_w64_x86_64_prefix --disable-shared --enable-static $extra_configure_options"
    }
    
    # needs 2 parameters currently
    generic_download_and_install() {
      local url="$1"
      local english_name="$2" 
      local extra_configure_options="$3"
      download_and_unpack_file $url $english_name
      cd $english_name || exit "needs 2 parameters"
      generic_configure_make_install $extra_configure_options
      cd ..
    }
    
    generic_configure_make_install() {
      generic_configure $1
      do_make_install
    }
    
    build_libilbc() {
      do_git_checkout https://github.com/dekkers/libilbc.git libilbc_git
      cd libilbc_git
      if [[ ! -f "configure" ]]; then
        autoreconf -fiv
      fi
      generic_configure_make_install
      cd ..
    }
    
    build_libflite() {
      download_and_unpack_file http://www.speech.cs.cmu.edu/flite/packed/flite-1.4/flite-1.4-release.tar.bz2 flite-1.4-release
      cd flite-1.4-release
       apply_patch https://raw.github.com/rdp/ffmpeg-windows-build-helpers/master/patches/flite_64.diff
       sed -i "s|i386-mingw32-|$cross_prefix|" configure*
       generic_configure
       do_make
       make install # it fails in error...
       if [[ "$bits_target" = "32" ]]; then
         cp ./build/i386-mingw32/lib/*.a $mingw_w64_x86_64_prefix/lib || exit 1
       else
         cp ./build/x86_64-mingw32/lib/*.a $mingw_w64_x86_64_prefix/lib || exit 1
       fi
      cd ..
    }
    
    build_libgsm() {
      download_and_unpack_file http://www.quut.com/gsm/gsm-1.0.13.tar.gz gsm-1.0-pl13
      cd gsm-1.0-pl13
      make CC=${cross_prefix}gcc AR=${cross_prefix}ar RANLIB=${cross_prefix}ranlib INSTALL_ROOT=${mingw_w64_x86_64_prefix} # fails, but in a way we expect (toast.c) LODO fix somehow?
      cp lib/libgsm.a $mingw_w64_x86_64_prefix/lib || exit 1
      mkdir -p $mingw_w64_x86_64_prefix/include/gsm
      cp inc/gsm.h $mingw_w64_x86_64_prefix/include/gsm || exit 1
      cd ..
    }
    
    build_libopus() {
      generic_download_and_install http://downloads.xiph.org/releases/opus/opus-1.0.1.tar.gz opus-1.0.1 
    }
    
    build_libopencore() {
      generic_download_and_install http://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-0.1.3.tar.gz/download opencore-amr-0.1.3
      generic_download_and_install http://sourceforge.net/projects/opencore-amr/files/vo-amrwbenc/vo-amrwbenc-0.1.2.tar.gz/download vo-amrwbenc-0.1.2
    }
    
    build_win32_pthreads() {
      download_and_unpack_file ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-2-9-1-release.tar.gz   pthreads-w32-2-9-1-release
      cd pthreads-w32-2-9-1-release
        do_make "clean GC-static CROSS=$cross_prefix"
        cp libpthreadGC2.a $mingw_w64_x86_64_prefix/lib/libpthread.a || exit 1
        cp pthread.h sched.h semaphore.h $mingw_w64_x86_64_prefix/include || exit 1
      cd ..
    }
    
    build_libdl() {
      #download_and_unpack_file http://dlfcn-win32.googlecode.com/files/dlfcn-win32-r19.tar.bz2 dlfcn-win32-r19
      do_svn_checkout http://dlfcn-win32.googlecode.com/svn/trunk/ dlfcn-win32
      cd dlfcn-win32
        ./configure --disable-shared --enable-static --cross-prefix=$cross_prefix --prefix=$mingw_w64_x86_64_prefix
        do_make_install
      cd ..
    }
    
    build_libogg() {
      generic_download_and_install http://downloads.xiph.org/releases/ogg/libogg-1.3.0.tar.gz libogg-1.3.0
    }
    
    build_libvorbis() {
      generic_download_and_install http://downloads.xiph.org/releases/vorbis/libvorbis-1.2.3.tar.gz libvorbis-1.2.3
    }
    
    build_libspeex() {
      generic_download_and_install http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz speex-1.2rc1
    }  
    
    build_libtheora() {
      cpu_count=1 # can't handle it
      generic_download_and_install http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2 libtheora-1.1.1
      cpu_count=$original_cpu_count
    }
    
    build_libfribidi() {
      # generic_download_and_install http://fribidi.org/download/fribidi-0.19.5.tar.bz2 fribidi-0.19.5 # got report of still failing?
      download_and_unpack_file http://fribidi.org/download/fribidi-0.19.4.tar.bz2 fribidi-0.19.4
      cd fribidi-0.19.4
        # make it export symbols right...
        apply_patch https://raw.github.com/rdp/ffmpeg-windows-build-helpers/master/patches/fribidi.diff
        generic_configure
        do_make_install
      cd ..
    
      #do_git_checkout http://anongit.freedesktop.org/git/fribidi/fribidi.git fribidi_git
      #cd fribidi_git
      #  ./bootstrap # couldn't figure out how to make this work...
      #  generic_configure
      #  do_make_install
      #cd ..
    }
    
    build_libass() {
      generic_download_and_install http://libass.googlecode.com/files/libass-0.10.1.tar.gz libass-0.10.1
      sed -i 's/-lass -lm/-lass -lfribidi -lm/' "$PKG_CONFIG_PATH/libass.pc"
    }
    
    build_gmp() {
      download_and_unpack_file ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.5.tar.bz2 gmp-5.0.5
      cd gmp-5.0.5
        generic_configure "ABI=$bits_target"
        do_make_install
      cd .. 
    }
    
    build_orc() {
      generic_download_and_install  http://code.entropywave.com/download/orc/orc-0.4.16.tar.gz orc-0.4.16
    }
    
    build_libbluray() {
      generic_download_and_install ftp://ftp.videolan.org/pub/videolan/libbluray/0.2.3/libbluray-0.2.3.tar.bz2 libbluray-0.2.3
    }
    
    build_libschroedinger() {
      download_and_unpack_file http://diracvideo.org/download/schroedinger/schroedinger-1.0.11.tar.gz schroedinger-1.0.11
      cd schroedinger-1.0.11
        generic_configure
        sed -i 's/testsuite//' Makefile
        do_make_install
        sed -i 's/-lschroedinger-1.0$/-lschroedinger-1.0 -lorc-0.4/' "$PKG_CONFIG_PATH/schroedinger-1.0.pc" # yikes!
      cd ..
    }
    
    build_gnutls() {
      download_and_unpack_file ftp://ftp.gnu.org/gnu/gnutls/gnutls-3.0.22.tar.xz gnutls-3.0.22
      cd gnutls-3.0.22
        generic_configure "--disable-cxx" # don't need the c++ version, in an effort to cut down on size... LODO test difference...
        do_make_install
      cd ..
      sed -i 's/-lgnutls *$/-lgnutls -lnettle -lhogweed -lgmp -lcrypt32 -lws2_32/' "$PKG_CONFIG_PATH/gnutls.pc"
    }
    
    build_libnettle() {
      generic_download_and_install http://www.lysator.liu.se/~nisse/archive/nettle-2.5.tar.gz nettle-2.5
    }
    
    build_bzlib2() {
      download_and_unpack_file http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz bzip2-1.0.6
      cd bzip2-1.0.6
        apply_patch https://raw.github.com/rdp/ffmpeg-windows-build-helpers/master/patches/bzip2_cross_compile.diff
        do_make "CC=$(echo $cross_prefix)gcc AR=$(echo $cross_prefix)ar PREFIX=$mingw_w64_x86_64_prefix RANLIB=$(echo $cross_prefix)ranlib libbz2.a bzip2 bzip2recover install"
      cd ..
    }
    
    build_zlib() {
      download_and_unpack_file http://zlib.net/zlib-1.2.8.tar.gz zlib-1.2.8
      cd zlib-1.2.8
        do_configure "--static --prefix=$mingw_w64_x86_64_prefix"
        do_make_install "CC=$(echo $cross_prefix)gcc AR=$(echo $cross_prefix)ar RANLIB=$(echo $cross_prefix)ranlib"
      cd ..
    }
    
    build_libxvid() {
      download_and_unpack_file http://downloads.xvid.org/downloads/xvidcore-1.3.2.tar.gz xvidcore
      cd xvidcore/build/generic
      if [ "$bits_target" = "64" ]; then
        local config_opts="--build=x86_64-unknown-linux-gnu --disable-assembly" # kludgey work arounds for 64 bit
      fi
      do_configure "--host=$host_target --prefix=$mingw_w64_x86_64_prefix $config_opts" # no static option...
      sed -i "s/-mno-cygwin//" platform.inc # remove old compiler flag that now apparently breaks us
      do_make_install
      cd ../../..
      # force a static build after the fact
      if [[ -f "$mingw_w64_x86_64_prefix/lib/xvidcore.dll" ]]; then
        rm $mingw_w64_x86_64_prefix/lib/xvidcore.dll || exit 1
        mv $mingw_w64_x86_64_prefix/lib/xvidcore.a $mingw_w64_x86_64_prefix/lib/libxvidcore.a || exit 1
      fi
    }
    
    build_fontconfig() {
      download_and_unpack_file http://www.freedesktop.org/software/fontconfig/release/fontconfig-2.10.1.tar.gz fontconfig-2.10.1
      cd fontconfig-2.10.1
        generic_configure --disable-docs
        do_make_install
      cd .. 
      sed -i 's/-L${libdir} -lfontconfig[^l]*$/-L${libdir} -lfontconfig -lfreetype -lexpat/' "$PKG_CONFIG_PATH/fontconfig.pc"
    }
    
    build_libaacplus() {
      #download_and_unpack_file http://217.20.164.161/~tipok/aacplus/libaacplus-2.0.2.tar.gz libaacplus-2.0.2
      cd libaacplus-2.0.2
        if [[ ! -f configure ]]; then
         ./autogen.sh --fail-early
        fi
        generic_configure_make_install 
      cd ..
    }
    
    build_openssl() {
      #download_and_unpack_file http://www.openssl.org/source/openssl-1.0.1c.tar.gz openssl-1.0.1c
      cd openssl-1.0.1c
      export cross="$cross_prefix"
      export CC="${cross}gcc"
      export AR="${cross}ar"
      export RANLIB="${cross}ranlib"
      if [ "$bits_target" = "32" ]; then
        do_configure "--prefix=$mingw_w64_x86_64_prefix no-shared mingw" ./Configure
      else
        do_configure "--prefix=$mingw_w64_x86_64_prefix no-shared mingw64" ./Configure
      fi
      do_make_install
      unset cross
      unset CC
      unset AR
      unset RANLIB
      cd ..
    }
    
    build_fdk_aac() {
      #generic_download_and_install http://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-0.1.0.tar.gz/download fdk-aac-0.1.0
      do_git_checkout https://github.com/mstorsjo/fdk-aac.git fdk-aac_git
      cd fdk-aac_git
        if [[ ! -f "configure" ]]; then
          autoreconf -fiv
        fi
        generic_configure_make_install
      cd ..
    }
    
    
    build_libexpat() {
      generic_download_and_install http://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0.tar.gz/download expat-2.1.0
    }
    
    build_iconv() {
      generic_download_and_install http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz libiconv-1.14
    }
    
    build_freetype() {
      generic_download_and_install http://download.savannah.gnu.org/releases/freetype/freetype-2.4.10.tar.gz freetype-2.4.10
    }
    
    build_vo_aacenc() {
      generic_download_and_install http://sourceforge.net/projects/opencore-amr/files/vo-aacenc/vo-aacenc-0.1.2.tar.gz/download vo-aacenc-0.1.2
    }
    
    build_sdl() {
      # apparently ffmpeg expects prefix-sdl-config not sdl-config that they give us, so rename...
      export CFLAGS=-DDECLSPEC=  # avoid trac tickets 939 and 282
      generic_download_and_install http://www.libsdl.org/release/SDL-1.2.15.tar.gz SDL-1.2.15
      unset CFLAGS
      mkdir temp
      cd temp # so paths will work out right
      local prefix=$(basename $cross_prefix)
      local bin_dir=$(dirname $cross_prefix)
      sed -i "s/-mwindows//" "$mingw_w64_x86_64_prefix/bin/sdl-config" # allow ffmpeg to output anything
      sed -i "s/-mwindows//" "$PKG_CONFIG_PATH/sdl.pc"
      cp "$mingw_w64_x86_64_prefix/bin/sdl-config" "$bin_dir/${prefix}sdl-config" # this is the only one in the PATH so use it for now
      cd ..
      rmdir temp
    }
    
    build_faac() {
      generic_download_and_install http://downloads.sourceforge.net/faac/faac-1.28.tar.gz faac-1.28 "--with-mp4v2=no"
    }
    
    build_lame() {
      generic_download_and_install http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz/download lame-3.99.5
    }
    
    build_frei0r() {
      #download_and_unpack_file http://www.piksel.no/frei0r/releases/frei0r-plugins-1.3.tar.gz frei0r-1.3
      #cd frei0r-1.3
        #do_configure " --build=mingw32  --host=$host_target --prefix=$mingw_w64_x86_64_prefix --disable-static --enable-shared" # see http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=5&t=312
        #do_make_install
        # we rely on external dll's for this one, so only need the header to enable it, for now
        #cp include/frei0r.h $mingw_w64_x86_64_prefix/include
      #cd ..
      if [[ ! -f "$mingw_w64_x86_64_prefix/include/frei0r.h" ]]; then
        curl https://raw.github.com/rdp/frei0r/master/include/frei0r.h > $mingw_w64_x86_64_prefix/include/frei0r.h || exit 1
      fi
    }
    
    build_ffmpeg() {
      local shared=$1
      # can't mix and match --enable-static --enable-shared unfortunately, or the final executable seems to just use shared if the're both present
      if [[ $shared == "shared" ]]; then
        #do_git_checkout https://github.com/FFmpeg/FFmpeg.git ffmpeg_git_shared
        local extra_configure_opts="--enable-shared --disable-static"
        cd ffmpeg_git_shared
      else
        do_git_checkout https://github.com/FFmpeg/FFmpeg.git ffmpeg_git
        local extra_configure_opts="--enable-static --disable-shared"
        cd ffmpeg_git
      fi
      if [ "$bits_target" = "32" ]; then
       local arch=x86
      else
       local arch=x86_64
      fi
    
    config_options="--arch=$arch --target-os=mingw32 --cross-prefix=$cross_prefix --pkg-config=pkg-config --enable-gpl --enable-version3 --enable-nonfree --enable-small --disable-pthreads --enable-w32threads --disable-doc --disable-debug --disable-network --disable-programs --disable-postproc --disable-avfilter --disable-avresample --enable-openssl --enable-libx264 --enable-libaacplus --disable-everything --enable-encoder=libx264 --enable-encoder=libaacplus --enable-decoder=h264 --enable-decoder=aac --extra-cflags=-DPTW32_STATIC_LIB  $extra_configure_opts " # others: --enable-w32threads --enable-libflite
      #if [[ "$non_free" = "y" ]]; then
       # config_options="$config_options --enable-nonfree  " # --enable-libaacplus --enable-libfaac -- faac deemed too poor quality and becomes the default -- add it in and uncomment the build_faac line to include it --enable-openssl --enable-libaacplus
     # else
      #  config_options="$config_options"
      #fi
    
      if [[ "$native_build" = "y" ]]; then
        config_options="$config_options --disable-runtime-cpudetect"
        # TODO --cpu=host ...
      else
        config_options="$config_options --enable-runtime-cpudetect"
      fi
      
      do_configure "$config_options"
      rm -f */*.a */*.dll *.exe # just in case some dependency library has changed, force it to re-link even if the ffmpeg source hasn't changed...
      rm already_ran_make*
      echo "doing ffmpeg make $(pwd)"
      do_make
      echo "Done! You will find $bits_target bit $shared binaries in $(pwd)/ff{mpeg,probe,play}*.exe"
      cd ..
    }
    
    build_dependencies() {
      build_win32_pthreads # vpx etc. depend on this--provided by the compiler build script now, though
      #build_libdl # ffmpeg's frei0r implentation needs this
      build_zlib # rtmp depends on it [as well as ffmpeg's optional but handy --enable-zlib]
      build_bzlib2 # in case someone wants it [ffmpeg uses it]
      #build_gmp # for libnettle
      #build_libnettle # needs gmp
      #build_gnutls # needs libnettle
    
      #build_frei0r
      #build_libutvideo
      #build_libflite # too big
      #build_libgsm
      build_sdl # needed for ffplay to be created
      build_libopus
      #build_libopencore
      #build_libogg
      #build_libspeex # needs libogg for exe's
      #build_libvorbis # needs libogg
      #build_libtheora # needs libvorbis, libogg
      #build_orc
      #build_libschroedinger # needs orc
      #build_libbluray
      #build_libxvid
      #build_libxavs
      build_libsoxr
      build_x264
      build_lame
      #build_libvpx
      #build_vo_aacenc
      # build_iconv # mplayer I think needs it for freetype [just it though]
      #build_freetype
      #build_libexpat
      #build_libilbc
      #build_fontconfig # needs expat, might need freetype, can use iconv, but I believe doesn't currently
      #build_libfribidi
      #build_libass # needs freetype, needs fribidi, needs fontconfig
      #build_libopenjpeg
      #if [[ "$non_free" = "y" ]]; then
        #build_fdk_aac
        # build_faac # not included for now, too poor quality :)
        # build_libaacplus # if you use it, you can't use any other AAC encoder, so disabled for now :)
      #fi
      #build_openssl # hopefully don't need it anymore, since we have gnutls...
      #build_librtmp # needs gnutls [or openssl...]
    }
    
    while true; do
      case $1 in
        -h | --help ) echo "options: --disable-nonfree=y --sandbox-ok=y --rebuild-compilers=y"; exit 0 ;;
        --sandbox-ok=* ) sandbox_ok="${1#*=}"; shift ;;
        --disable-nonfree=* ) disable_nonfree="${1#*=}"; shift ;;
        --rebuild-compilers=* ) rebuild_compilers="${1#*=}"; shift ;;
        -- ) shift; break ;;
        -* ) echo "Error, unknown option: '$1'."; exit 1 ;;
        * ) break ;;
      esac
    done
    
    intro # remember to always run the intro, since it adjust pwd
    check_missing_packages
    install_cross_compiler # always run this, too, since it adjust the PATH
    setup_env
    
    original_path="$PATH"
    if [ -d "mingw-w64-i686" ]; then # they installed a 32-bit compiler
      echo "Building 32-bit ffmpeg..."
      host_target='i686-w64-mingw32'
      mingw_w64_x86_64_prefix="$cur_dir/mingw-w64-i686/$host_target"
      export PATH="$cur_dir/mingw-w64-i686/bin:$original_path"
      export PKG_CONFIG_PATH="$cur_dir/mingw-w64-i686/i686-w64-mingw32/lib/pkgconfig"
      bits_target=32
      cross_prefix="$cur_dir/mingw-w64-i686/bin/i686-w64-mingw32-"
      mkdir -p win32
      cd win32
      build_dependencies
      #build_ffmpeg
      build_ffmpeg shared
      cd ..
    fi
    
    if [ -d "mingw-w64-x86_64" ]; then # they installed a 64-bit compiler
      echo "Building 64-bit ffmpeg..."
      host_target='x86_64-w64-mingw32'
      mingw_w64_x86_64_prefix="$cur_dir/mingw-w64-x86_64/$host_target"
      export PATH="$cur_dir/mingw-w64-x86_64/bin:$original_path"
      export PKG_CONFIG_PATH="$cur_dir/mingw-w64-x86_64/x86_64-w64-mingw32/lib/pkgconfig"
      mkdir -p x86_64
      bits_target=64
      cross_prefix="$cur_dir/mingw-w64-x86_64/bin/x86_64-w64-mingw32-"
      cd x86_64
      build_dependencies
      #build_ffmpeg
      build_ffmpeg shared
      cd ..
    fi
    
    echo "done with ffmpeg cross compiler script, it may have built the following binaries: 
    $(find . -name ffmpeg.exe)"
    View Code

    ……
       针对编译X264和aacplus遇到的错误,参考http://www.cnblogs.com/zzugyl/archive/2013/01/31/2887304.html  和 http://www.cnblogs.com/zzugyl/p/3163261.html 


    6. 重新执行,就会成功。
       $ ./cross_compile_ffmpeg.sh
       最后生成的结果并没有按照bin include lib文件夹分开,而是各自在各自的文件夹里。
       例如本次生成的是动态库,所以目录是在/home/gong/cross_compile_ffmpeg/sandbox/bin/ffmpeg-git-shared/
       avcodec-55.dll和avcodec.lib在libavcodec/下。并且avcodec-55.dll只有2.2M。
       关于windows下调用的inlcude路径,确实是个问题。自己在这个目录下总结头文件。我是按照http://ffmpeg.zeranoe.com/builds/ 他编译的结果对应找的头文件。需要对应版本号,不然不一定一样。还有一个方法是,在windows下虽然编译失败,但是编译ffmpeg的结果还是有include bin 和 lib  文件夹的,把include文件夹拷过来就可以了。同样,注意统一版本号。

  • 相关阅读:
    Python如何爬取淘宝MM呢?教你一招
    Python爬虫实战之如何爬取百度贴吧帖子?案例详解
    SpringBoot定时任务如何正确运用?案例详解
    JS数组之重排序方法
    JS数组之栈和队列
    JS数组之转换方法
    计算机相关推荐教程
    多维数组
    重新认识变量和数组
    数组
  • 原文地址:https://www.cnblogs.com/zzugyl/p/3164519.html
Copyright © 2020-2023  润新知