MAC搭建Linux x86_64交叉编译环境
MAC搭建Linux交叉编译环境准备工作运行脚本准备工作用mac自带的磁盘工具新建一个区分大小写的硬盘分区,后续的操作建议都在此分区进行,不然会出现文件找不到等错误。运行脚本需要gnu-sed,不是OSX上自带的sed,所以需要先下载一个,修改PATH变量,并用ln建立链接sed指向gsedbrew install gnu-sedexport PATH=/usr/local/Cellar/...
·
MAC搭建Linux交叉编译环境
准备工作
用mac自带的磁盘工具新建一个区分大小写的硬盘分区,后续的操作建议都在此分区进行,不然会出现文件找不到等错误。运行脚本需要gnu-sed,不是OSX上自带的sed,所以需要先下载一个,修改PATH变量,并用ln建立链接sed指向gsed
brew install gnu-sed
export PATH=/usr/local/Cellar/gnu-sed/4.7/bin:$PATH
其他一些前提依赖项
ulimit -n 8192
brew install gawk wget autoconf gettext
运行脚本
根据here和here,前者是arm平台,主要根据后者,结合自己需要,修改了gcc版本和一些环境参数
vars.sh
#! /bin/bash
INSTALL_PATH=/Volumes/Develop/cross_compile/x86_64
TARGET=x86_64-linux
USE_NEWLIB=0
LINUX_ARCH=x86_64
CONFIGURATION_OPTIONS="--disable-multilib --disable-nls --disable-werror" # --disable-threads --disable-shared
PARALLEL_MAKE=
BINUTILS_VERSION=binutils-2.25
GCC_VERSION=gcc-4.8.5
LINUX_KERNEL_VERSION=linux-3.17.2
GLIBC_VERSION=glibc-2.20
MPFR_VERSION=mpfr-3.1.2
GMP_VERSION=gmp-6.0.0a
MPC_VERSION=mpc-1.0.2
ISL_VERSION=isl-0.12.2
CLOOG_VERSION=cloog-0.18.1
export PATH=$INSTALL_PATH/bin:$PATH
build.sh
#! /bin/bash
set -e
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
trap 'echo FAILED COMMAND: $previous_command' EXIT
#-------------------------------------------------------------------------------------------
# This script will download packages for a GCC cross-compiler.
# Customize the variables (INSTALL_PATH, TARGET, etc.) in vars.sh to your liking before running.
#
# See: http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler
#-------------------------------------------------------------------------------------------
source ./vars.sh
# Download packages
export http_proxy=$HTTP_PROXY https_proxy=$HTTP_PROXY ftp_proxy=$HTTP_PROXY
wget -nc https://ftp.gnu.org/gnu/binutils/$BINUTILS_VERSION.tar.gz
wget -nc https://ftp.gnu.org/gnu/gcc/$GCC_VERSION/$GCC_VERSION.tar.gz
if [ $USE_NEWLIB -ne 0 ]; then
wget -nc -O newlib-master.zip https://github.com/bminor/newlib/archive/master.zip || true
unzip -qo newlib-master.zip
else
wget -nc https://www.kernel.org/pub/linux/kernel/v3.x/$LINUX_KERNEL_VERSION.tar.xz
wget -nc https://ftp.gnu.org/gnu/glibc/$GLIBC_VERSION.tar.xz
fi
wget -nc https://ftp.gnu.org/gnu/mpfr/$MPFR_VERSION.tar.xz
wget -nc https://ftp.gnu.org/gnu/gmp/$GMP_VERSION.tar.xz
wget -nc https://ftp.gnu.org/gnu/mpc/$MPC_VERSION.tar.gz
wget -nc ftp://gcc.gnu.org/pub/gcc/infrastructure/$ISL_VERSION.tar.bz2
wget -nc ftp://gcc.gnu.org/pub/gcc/infrastructure/$CLOOG_VERSION.tar.gz
# Extract everything
for f in *.tar*; do tar xfk $f; done
# Make symbolic links
cd $GCC_VERSION
ln -sf `ls -1d ../mpfr-*/` mpfr
ln -sf `ls -1d ../gmp-*/` gmp
ln -sf `ls -1d ../mpc-*/` mpc
ln -sf `ls -1d ../isl-*/` isl
ln -sf `ls -1d ../cloog-*/` cloog
cd ..
trap - EXIT
echo 'Success!'
download.sh
#! /bin/bash
set -e
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
trap 'echo FAILED COMMAND: $previous_command' EXIT
#-------------------------------------------------------------------------------------------
# This script will configure, build and install a GCC cross-compiler.
# It assumes that all packages have been downloaded using download.sh before this file is run.
# Customize the variables (INSTALL_PATH, TARGET, etc.) in vars.sh to your liking before running.
# If you get an error and need to resume the script from some point in the middle,
# just delete/comment the preceding lines before running it again.
#
# See: http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler
#
# This script requires gnu-sed, not the normal sed that comes with OSX. If you don't want to
# mess with the normal sed, perhaps add to the front of PATH the path to gnu-sed before you
# run this script? e.g. export PATH=/path/to/gnu-sed-directory/bin:$PATH
#
# This script should be run in a case-sensitive partition which you can make using OSX's disk
# utility.
#-------------------------------------------------------------------------------------------
source ./vars.sh
# extra flags and env variables are needed to get this to compile on OSX
export BUILD_ALL_BASE_DIR=`pwd`
export HOST_EXTRACFLAGS="-I$BUILD_ALL_BASE_DIR/endian"
# these are needed for gettext and assuming that it was installed using brew
export BUILD_CPPFLAGS='-I/usr/local/Cellar/gettext/0.20.1/include'
export BUILD_LDFLAGS='-L/usr/local/Cellar/gettext/0.20.1/lib -lintl'
# Step 1. Binutils
echo -e "\nStep 1 - building binutils...\n" && sleep 2
mkdir -p build-binutils
cd build-binutils
../$BINUTILS_VERSION/configure --prefix=$INSTALL_PATH --target=$TARGET $CONFIGURATION_OPTIONS
make $PARALLEL_MAKE
make install
cd ..
# Step 2. Linux Kernel Headers
echo -e "\nStep 2 - Linux kernel headers...\n" && sleep 2
if [ $USE_NEWLIB -eq 0 ]; then
cd $LINUX_KERNEL_VERSION
make V=1 ARCH=$LINUX_ARCH INSTALL_HDR_PATH=$INSTALL_PATH/$TARGET headers_install
cd ..
fi
# Step 3. C/C++ Compilers
echo -e "\nStep 3 - C/C++ compilers...\n" && sleep 2
mkdir -p build-gcc
cd build-gcc
if [ $USE_NEWLIB -ne 0 ]; then
NEWLIB_OPTION=--with-newlib
fi
../$GCC_VERSION/configure --prefix=$INSTALL_PATH --target=$TARGET --enable-languages=c,c++ $CONFIGURATION_OPTIONS $NEWLIB_OPTION
make $PARALLEL_MAKE gcc_cv_libc_provides_ssp=yes all-gcc
make install-gcc
cd ..
if [ $USE_NEWLIB -ne 0 ]; then
# Steps 4-6: Newlib
echo -e "\nSteps 4-6 - newlib...\n" && sleep 2
mkdir -p build-newlib
cd build-newlib
../newlib-master/configure --prefix=$INSTALL_PATH --target=$TARGET $CONFIGURATION_OPTIONS
make $PARALLEL_MAKE
make install
cd ..
else
# Step 4. Standard C Library Headers and Startup Files
echo -e "\nStep 4 - standard lib headers...\n" && sleep 2
mkdir -p build-glibc
cd build-glibc
../$GLIBC_VERSION/configure --prefix=$INSTALL_PATH/$TARGET --build=$MACHTYPE --host=$TARGET --target=$TARGET --with-headers=$INSTALL_PATH/$TARGET/include $CONFIGURATION_OPTIONS libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make $PARALLEL_MAKE csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o $INSTALL_PATH/$TARGET/lib
$TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $INSTALL_PATH/$TARGET/lib/libc.so
touch $INSTALL_PATH/$TARGET/include/gnu/stubs.h
cd ..
# Step 5. Compiler Support Library
echo -e "\nStep 5 - building libgcc...\n" && sleep 2
cd build-gcc
make $PARALLEL_MAKE all-target-libgcc
make install-target-libgcc
cd ..
# Step 6. Standard C Library & the rest of Glibc
echo -e "\nStep 6 - standard C library and the rest of glibc...\n" && sleep 2
cd build-glibc
make $PARALLEL_MAKE
make install
cd ..
fi
# Step 7. Standard C++ Library & the rest of GCC
echo -e "\nStep 7 - building C++ library and rest of gcc\n" && sleep 2
cd build-gcc
make $PARALLEL_MAKE all
make install
cd ..
trap - EXIT
echo 'Success!'
依次执行download.sh和build.sh即可
编译开源代码遇到的一些问题
ffmpeg
./config.h:17:19: error: expected identifier or '(' before 'void'
#define getenv(x) NULL
^
./config.h:17:19: error: expected ')' before numeric constant
#define getenv(x) NULL
^
在config.h中注释掉:
//#define getenv(x) NULL
In file included from libavformat/asfdec_o.c:30:0:
./libavutil/time_internal.h:26:26: error: static declaration of 'gmtime_r' follows non-static declaration
static inline struct tm *gmtime_r(const time_t* clock, struct tm *result)
^
In file included from ./libavutil/time_internal.h:22:0,
from libavformat/asfdec_o.c:30:
/Volumes/Develop/cross_compile/x86_64/x86_64-linux/include/time.h:249:19: note: previous declaration of 'gmtime_r' was here
extern struct tm *gmtime_r (const time_t *__restrict __timer,
^
In file included from libavformat/asfdec_o.c:30:0:
./libavutil/time_internal.h:37:26: error: static declaration of 'localtime_r' follows non-static declaration
static inline struct tm *localtime_r(const time_t* clock, struct tm *result)
^
In file included from ./libavutil/time_internal.h:22:0,
from libavformat/asfdec_o.c:30:
/Volumes/Develop/cross_compile/x86_64/x86_64-linux/include/time.h:254:19: note: previous declaration of 'localtime_r' was here
extern struct tm *localtime_r (const time_t *__restrict __timer,
^
参照here将下列定义从0改为1
#define HAVE_LLRINT 1
#define HAVE_LLRINTF 1
#define HAVE_LRINT 1
#define HAVE_LRINTF 1
#define HAVE_ROUND 1
#define HAVE_ROUNDF 1
#define HAVE_CBRT 1
#define HAVE_CBRTF 1
#define HAVE_COPYSIGN 1
#define HAVE_TRUNC 1
#define HAVE_TRUNCF 1
#define HAVE_RINT 1
#define HAVE_HYPOT 1
#define HAVE_ERF 1
或者
sed -i -e 's/#define HAVE_LLRINT 0/#define HAVE_LLRINT 1/g' config.h
sed -i -e 's/#define HAVE_LLRINTF 0/#define HAVE_LLRINTF 1/g' config.h
sed -i -e 's/#define HAVE_LRINT 0/#define HAVE_LRINT 1/g' config.h
sed -i -e 's/#define HAVE_LRINTF 0/#define HAVE_LRINTF 1/g' config.h
sed -i -e 's/#define HAVE_ROUND 0/#define HAVE_ROUND 1/g' config.h
sed -i -e 's/#define HAVE_ROUNDF 0/#define HAVE_ROUNDF 1/g' config.h
sed -i -e 's/#define HAVE_CBRT 0/#define HAVE_CBRT 1/g' config.h
sed -i -e 's/#define HAVE_CBRTF 0/#define HAVE_CBRTF 1/g' config.h
sed -i -e 's/#define HAVE_COPYSIGN 0/#define HAVE_COPYSIGN 1/g' config.h
sed -i -e 's/#define HAVE_TRUNC 0/#define HAVE_TRUNC 1/g' config.h
sed -i -e 's/#define HAVE_TRUNCF 0/#define HAVE_TRUNCF 1/g' config.h
sed -i -e 's/#define HAVE_RINT 0/#define HAVE_RINT 1/g' config.h
sed -i -e 's/#define HAVE_HYPOT 0/#define HAVE_HYPOT 1/g' config.h
sed -i -e 's/#define HAVE_ERF 0/#define HAVE_ERF 1/g' config.h
sed -i -e 's/#define HAVE_GMTIME_R 0/#define HAVE_GMTIME_R 1/g' config.h
sed -i -e 's/#define HAVE_LOCALTIME_R 0/#define HAVE_LOCALTIME_R 1/g' config.h
sed -i -e 's/#define HAVE_INET_ATON 0/#define HAVE_INET_ATON 1/g' config.h
CC libavdevice/alldevices.o
In file included from ./libavutil/common.h:36:0,
from ./libavutil/avutil.h:289,
from ./libavutil/log.h:25,
from libavdevice/avdevice.h:46,
from libavdevice/alldevices.c:22:
./libavutil/libm.h:86:38: error: expected identifier or '(' before 'sizeof'
static av_always_inline av_const int isinf(float x)
^
./libavutil/libm.h:96:38: error: expected identifier or '(' before 'sizeof'
static av_always_inline av_const int isnan(float x)
^
make: *** [libavdevice/alldevices.o] Error 1
michaels-MBP:ffmpeg michael$ make clean;make
CC libavdevice/alldevices.o
In file included from ./libavutil/common.h:36:0,
from ./libavutil/avutil.h:289,
from ./libavutil/log.h:25,
from libavdevice/avdevice.h:46,
from libavdevice/alldevices.c:22:
./libavutil/libm.h:96:38: error: expected identifier or '(' before 'sizeof'
static av_always_inline av_const int isnan(float x)
^
make: *** [libavdevice/alldevices.o] Error 1
修改
#define HAVE_ISINF 1
#define HAVE_ISNAN 1
../ffmpeg/libavutil/libavutil.a(file.o): In function `av_tempfile':
file.c:(.text+0x15d): warning: the use of `tempnam' is dangerous, better use `mkstemp'
修改
#define HAVE_MKSTEMP 1
编译过程坑比较多,小心谨慎
更多推荐



所有评论(0)