ubuntu 14.04 交叉编译ffmpeg

因为工作的关系和自己的兴趣原因,我尝试了自己从ubuntu 14.04 交叉编译ffmpeg。

我交叉编译ffmpeg的方法,完全是摸索得到的。在这之前,我从来没有试过交叉编译。

在从ubuntu成功交叉编译之前,我多次尝试了在MingW、cygwin编译ffmpeg,无一例外全部失败。

这次的成功完全是巧合,因为换个电脑我不确定我会不会还是成功。虽然如此我依然要把这次经历写下来。

首先,我在https://github.com/rdp/ffmpeg-windows-build-helpers获得一个交叉编译的脚本。

这个连接从http://trac.ffmpeg.org/wiki/CompilationGuide/CrossCompilingForWindows获得。

下载它,在/home/username/目录下解压它,然后,

cd ffmpeg-windows-build-helpers-master
chmod 777 cross_compile_ffmpeg.sh
./cross_compile_ffmpeg.sh

得到一个这样的界面:

2016年 01月 03日 星期日 23:16:00 CST
     ##################### Welcome ######################
  Welcome to the ffmpeg cross-compile builder-helper script.
  Downloads and builds will be installed to directories within /home/ldxn/tmp/sandbox
  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.
Is /home/ldxn/tmp/sandbox ok (requires ~ 5GB space) [Y/n]?

直接回车,使用默认的Y选项。

using default y
Would you like to include non-free (non GPL compatible) libraries, like many high quality aac encoders [libfdk_aac]
The resultant binary may not be distributable, but can be useful for in-house use. Include these non-free-license libraries [y/N]?

直接回车,使用默认的N选项。

using default n
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
Input your choice [1-4]: 2

问你要编译32位还是64位,还是32和64位,我使用2,怕有些电脑不支持64。虽然我的电脑是64的。键入2,回车。

Input your choice [1-4]: 2
starting to download and build cross compile version of gcc [requires working internet access] with thread count 8...

building win32 cross compiler
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 77026  100 77026    0     0   9480      0  0:00:08  0:00:08 --:--:-- 19275
[1/49]: Downloading config.guess... done
[2/49]: Downloading mingw-w64-4.0.4.tar.bz2...

运气好的话,这个时候就已经开始下载了。运气差的话,连不上网,以上步骤重新走一次就可以了。

理论上,网络畅通,操作系统环境没问题,当这个脚本运行结束的时候,也就是你获得一个ffmpeg的时候了。

但程序员的日常是绝对不会如此一帆风顺,一波九折绝对不是夸张。

写这篇文章的时候,我已经完成了编译。我没有写博客的习惯,所以我没有在编译的过程中随时记录当时的状态。

现在我仅仅靠记忆,来记录一些我碰到的问题。

1.找不到libpthread

make的时候找不到libpthread,这是下不了这个包,所以没编译。网上找到这个包的地址,在sandbox/cross_compilers/mingw-w64-build-3.6.7.local中替换原来的地址,第二个解决办法是如果是网络超时无法下载,就可以先把地址提取出来,去下好,放在正确的位置,修改mingw-w64-build-3.6.7.local的脚本,然后编译完成后再改回来,我忘了我是使用哪种方法了。

在我的mingw-w64-build-3.6.7.local版本中,搜索build_pthreads_w32,会转到一个函数,如下:

build_pthreads_w32 () {
if [[ -z "$pthreads_w32_ver" ]]; then
  pthreads_w32_ver='cvs'
fi

local target prefix
target="$1"
prefix="$2"

shift 2
cd "$pkgs_dir" || print_error
create_pkg_dirs 'pthread-w32' || print_error

if [[ "$pthreads_w32_ver" = "$pthreads_w32_release_ver" ]]; then
  download_extract "ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-$pthreads_w32_release_ver-release.tar.gz"
  if [[ ! -d "pthreads-w32-$pthreads_w32_release_ver" ]]; then
    mv "pthreads-w32-$pthreads_w32_release_ver-release" "pthreads-w32-$pthreads_w32_release_ver" || print_error
  fi
else
  unset oldmd5 newmd5
  if cd 'pthreads-w32-cvs' 2>/dev/null; then
    build_progress 'pthreads-w32 cvs' 'Updating'
    cvs update > >(build_log) 2>&1 || print_error
    build_progress 'done'
    cd '..'
  else
    build_progress 'pthreads-w32 cvs' 'Downloading'
    cvs -d :pserver:anonymous@sourceware.org:/cvs/pthreads-win32 checkout pthreads > >(build_log) 2>&1 || print_error
    build_progress 'done'
    mv 'pthreads' 'pthreads-w32-cvs'
  fi
fi

cd "pthreads-w32-$pthreads_w32_ver" || print_error
make realclean > >(build_log) 2>&1 || print_error
if [[ "${static_build[@]}" != *"disable-shared"* ]]; then
  build_progress 'pthreads-w32 shared' 'Building'
  make CROSS="$target-" realclean GC ARCH="$pthread_arch" > >(build_log) 2>&1 || print_error
  build_progress 'done'

  cp 'pthreadGC2.dll' "$prefix/lib/" || print_error
  cd "$prefix/lib" || print_error
  ln -s "./pthreadGC2.dll" "./libpthread.dll"
  cd "$pkgs_dir/pthread-w32/source/pthreads-w32-$pthreads_w32_ver" || print_error
fi
build_progress 'pthreads-w32 static' 'Building'
make CROSS="$target-" realclean GC-static ARCH="$pthread_arch" > >(build_log) 2>&1 || print_error
build_progress 'done'

cp 'libpthreadGC2.a' "$prefix/lib/" || print_error
cp 'pthread.h' 'sched.h' 'semaphore.h' "$prefix/include/" || print_error
cd "$prefix/lib" || print_error
ln -s "./libpthreadGC2.a" "./libpthread.a"
cd '../include' || print_error

for file in 'pthread.h' 'sched.h' 'semaphore.h'; do
  if ! ed -s "$prefix/include/$file" <<< $',s/ __declspec (dllexport)//g\n,s/ __declspec (dllimport)//g\nw\nq' > >(build_log) 2>&1; then
    mv "$file" "$file".orig
    sed 's/ __declspec (dllexport)//g;s/ __declspec (dllimport)//g' "$file".orig > "$file"
    rm -f "$file".orig
  fi
done
}

download_extract "ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-$pthreads_w32_release_ver-release.tar.gz"就是它的地址了

你想办法弄到一个这样的有效的地址贴在那里就可以通过了。

你还需要在sandbox/mingw-w64-i686文件夹中删除compiler.done文件,这是
cross_compile_ffmpeg.sh赖以判断mingw是否正确安装的文件。

删了之后,注释以下代码:

rm -f $zeranoe_script_name || exit 1
curl -4 https://raw.githubusercontent.com/rdp/ffmpeg-windows-build-helpers/master/patches/$zeranoe_script_name -O  || exit 1

因为mingw-w64-build-3.6.7.local是被下载的,重新安装mingw是会删掉原来的配置,而如果删掉了你的修改也就没了。。。

注释掉后的cross_compile_ffmpeg.sh install_cross_compiler 函数如下:

install_cross_compiler() {
  if [[ -f "mingw-w64-i686/compiler.done" && -f "mingw-w64-x86_64/compiler.done" ]]; then
   echo "MinGW-w64 compilers already installed, not re-installing..."
   return # early exit just assume they want both, don't even prompt :)
  fi

  if [[ -z $compiler_flavors ]]; then
    pick_compiler_flavors
  fi

  if [[ $compiler_flavors == "win32" && -f "mingw-w64-i686/compiler.done" ]]; then
    echo "win32 cross compiler already installed, not reinstalling"
    return
  fi

  if [[ $compiler_flavors == "win64" && -f "mingw-w64-x86_64/compiler.done" ]]; then
    echo "win64 cross compiler already installed, not reinstalling"
    return
  fi

  # if they get this far, they want a compiler that's not installed, I think...fire away! XXXX if 32 bit compiler installed, and request both, rebuilds 32...

  local zeranoe_script_name=mingw-w64-build-3.6.7.local
  #rm -f $zeranoe_script_name || exit 1
  #curl -4 https://raw.githubusercontent.com/rdp/ffmpeg-windows-build-helpers/master/patches/$zeranoe_script_name -O  || exit 1
  chmod u+x $zeranoe_script_name
  unset CFLAGS # don't want these for the compiler itself since it creates executables to run on the local box (we have a parameter allowing them to set them for the script "all builds" basically)
  # pthreads version to avoid having to use cvs for it
  echo "starting to download and build cross compile version of gcc [requires working internet access] with thread count $gcc_cpu_count..."
  echo ""
  # --disable-shared allows c++ to be distributed at all...which seemed necessary for some random dependency...
  nice ./$zeranoe_script_name --clean-build --disable-shared --default-configure  --pthreads-w32-ver=2-9-1 --cpu-count=$gcc_cpu_count --build-type=$compiler_flavors --gcc-ver=5.3.0 || exit 1 
  export CFLAGS=$original_cflags # reset it
  if [[ ! -f mingw-w64-i686/bin/i686-w64-mingw32-gcc && ! -f mingw-w64-x86_64/bin/x86_64-w64-mingw32-gcc ]]; then
    echo "no gcc cross compiler(s) seem built [?] (build failure [?]) recommend nuke sandbox dir (rm -rf sandbox) and try again!"
    exit 1
  fi
  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
  rm -f build.log
  clear
  echo "Ok, done building MinGW-w64 cross-compiler(s) successfully..."
}

2.在安装libsndfile-1.0.25的时候卡住

因为GFW的存在,和跨太平洋的网络通信,很多时候有些软件是下不下来的,不是被qiang就是下载速度不给力,

这个包无法安装在我觉得应该是第一个原因。

我在163的镜像站找到了它的源码下载地址,把163的镜像地址替换上去,替换后如下:

build_libsndfile() {
#  generic_download_and_install http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.25.tar.gz libsndfile-1.0.25
  generic_download_and_install http://mirrors.163.com/ubuntu/pool/main/libs/libsndfile/libsndfile_1.0.25.orig.tar.gz libsndfile-1.0.25
}

把第一个的地址注释,改为163的地址,瞬间解决了问题。其他的下不下来也可以这样解决,主要版本号相差不大应该都是可以的。

无法安装gnutls-3.3.19,也可以这样解决。或者重头开始,多调用几次cross_compile_ffmpeg.sh,也可以解决。

downloading ftp://ftp.gnutls.org/gcrypt/gnutls/v3.3/gnutls-3.3.19.tar.xz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:27 --:--:--     0curl: (7) Failed to connect to ftp.gnutls.org port 21: 拒绝连接

3.因为网络不给力,祭出大招

像无法安装gnutls-3.3.19的问题,不断地./cross_compile_ffmpeg.sh,然后输入n,输入2,我受够了。所以我学了下bash,写下了如此脚本,死循环!!!
#!/bin/bash
while true
do
    ./cross_compile_ffmpeg.sh
    wait
done

新建文本,重命名为tmp.sh,把以上代码贴上去,放在和cross_compile_ffmpeg.sh同一目录:

chmod 777 tmp.sh./tmp.sh

然后要修改一下cross_compile_ffmpeg.sh,因为每次执行cross_compile_ffmpeg.sh都需要n或者2,以做一些设定,把

修改它的目的就把这些设定内置了。修改之后的cross_compile_ffmpeg.sh如下:

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' && ! -d sandbox ]]; then
    yes_no_sel "Is $PWD/sandbox ok (requires ~ 5GB space) [Y/n]?" "y"
    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
    if  [[ $disable_nonfree = "n" ]]; then
      non_free="y" 
    else
#      yes_no_sel "Would you like to include non-free (non GPL compatible) libraries, like many high quality aac encoders [libfdk_aac]
#The resultant binary may not be distributable, but can be useful for in-house use. Include these non-free-license libraries [y/N]?" "n"
      non_free="n" #$user_input" # save it away
    fi
  fi
}

把non_free的值设为默认n

第二处:

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
Input your choice [1-4]:

把它的预设值改为2,修改后的代码如下:

pick_compiler_flavors() {
compiler_flavors=win32
#  while [[ "$compiler_flavors" != [1-4] ]]; 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-4]: '
#    read compiler_flavors
#  done
#  case "$compiler_flavors" in
#  1 ) compiler_flavors=multi ;;
#  2 ) compiler_flavors=win32 ;;
#  3 ) compiler_flavors=win64 ;;
#  4 ) echo "exiting"; exit 0 ;;
#  * ) clear;  echo 'Your choice was not valid, please try again.'; echo ;;
#  esac
}

这样,调用tmp.sh之后,cross_compile_ffmpeg.sh就不断地重复调用,直到编译完成为止也不会停止,bash的高手请告诉我怎么让它在编译完成后停下来。。。

当然,如果你碰上了无法下载包的问题。tmp.sh并不能帮你完成这个。所以你还是需要是不是地看看,是不是在哪里卡了很久了,如果是,你就应该按下ctrl+c,和改下地址了。

4.不断地重复检查新版本

像安装x265 的时候,这个脚本需要x265的最新版本。所以在build_libx265函数中,它会不断地查询x265的最新版本。

但我在边下载边编译ffmpeg的过程中,可能会中断无数次,而build_libx265这个函数检查x265的最新版本非常消耗时间。

所以我,就,注释掉它。你也可以这样做。

总结:

1.我是幸运的,我没有碰到其他奇形怪状我无法解决的问题。

2.因为完成ffmpeg的交叉编译有几天了,我不知道是否遗漏了哪些必要的东西没有记录。所以如果大家看到我的随笔后无法解决问题,可以在回复里联系我,虽然我不一定能够及时看得到。。。

题外:

我现在在尝试交叉编译vlc,编不过去,搞了很久了,都没用。

转载请注明出处:http://www.cnblogs.com/ldxn/p/5097553.html
原文链接: https://www.cnblogs.com/ldxn/p/5097553.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/226830

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午1:23
下一篇 2023年2月13日 下午1:23

相关推荐