背景介绍
树莓派自带的编译工具是基于Linux
的,在Mac OSX
上是无法正常使用的,因此比较简单的方法就是使用crosstool-ng
来建立交叉编译环境。
配置编译环境
1.安装HomeBrew
,方便各种工具的安装
2.使用HomeBrew
安装crosstool-ng
1 |
$ sudo brew install crosstool-ng |
3.链接Mac OSX
上的install
到ginstall
。Mac OSX
上没有ginstall
1 |
$ sudo ln -s /usr/local/bin/ginstall /usr/bin/install |
如果不执行命令,则会报错
1 |
/Volumes/RPi-EABI/.build/tools/bin/install: line 2: exec: ginstall: not found |
4.使用HomeBrew
安装expat
1 |
$ sudo brew install expat |
不执行此命令,我的电脑会出现crosstool-ng
在配置expat
的时候失败,但是两者使用的版本并不相同,另外貌似出错后,重试即可,不需要安装expat
,但是稳妥起见,还是安装好了。
5.创建大小写区分的磁盘分区文件,并挂载(如果你系统创建的时候,系统分区以及区分大小写,则不必此项操作)
参考Mac OSX下执行crosstool-ng提示“Your file system ‘xxxx’ is *not* case-sensitive!”
6.在刚刚创建并挂载的大小写区分的磁盘上执行配置命令
1 |
$ ct-ng armv7-rpi2-linux-gnueabihf |
7.修改刚刚命令生成在当前目录下的配置文件
1 |
$ sudo vim .config |
找到
1 2 |
CT_WANTS_STATIC_LINK=y CT_CC_GCC_STATIC_LIBSTDCXX=y |
禁止使用静态链接(Mac OSX
下,无法提供对于libc
的静态链接,只能动态链接)
1 2 |
CT_WANTS_STATIC_LINK=n # set disabled CT_CC_GCC_STATIC_LIBSTDCXX=n # set disabled or comment out |
8.执行构建命令
1 |
$ ct-ng build |
构建中遇到的问题
如果构建出错,可以使用
1 |
$ ct-ng build.1 |
后面的数字代表几个并行的任务,单个任务可以更方便的查看出错的信息,多任务并发会导致日志打印的非常混乱。
在构建(ct-ng build
)的时候遇到任何问题,都应该查看当前构建目录下的build.log
文件,这个文件中详细记录了构建的过程信息,详细的出错信息等。
由于crosstool-ng
在构建过程中需要去服务器上下载源代码,难免出现文件下载不完整的情况,这种情况下,可以从build.log
文件中看到如下的内容:
1 2 3 4 5 6 7 8 9 |
[FILE ] tar: Retrying... [FILE ] tar: Damaged tar archive [FILE ] tar: Retrying... [FILE ] tar: Damaged tar archive [FILE ] tar: Retrying... [FILE ] tar: Damaged tar archive [FILE ] tar: Retrying... [FILE ] tar: Truncated tar archive [FILE ] tar: Error exit delayed from previous errors. |
则说明下载的源代码出现了问题。最容易出现这个问题的是gcc
.以gcc-5.2.0
为例子,修正的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ cd .build $ cd tarballs $ rm -rf gcc-5.2.0.tar.bz2 $ cd .. $ cd src $ rm -rf .gcc-5.2.0.extracting $ rm -rf gcc-5.2.0 |
简单解释一下代码,tarballs
存储了从服务器上下载的全部源代码的压缩包,解压缩出现问题,因此必须删除,让crosstool-ng
去重新下载,扩展名为.extracting
文件为crosstool-ng
的标记文件,用来标识这个包是不是已经被解压缩过,一旦这个文件存在crosstool-ng
就认为对应的工具已经就绪了,就不会处理这个工具了,最后删除的是工具源代码的目录。
如果提示安装binutils
的时候失败,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
[INFO ] Installing binutils for host [ERROR] /Volumes/raspberry/rpi-linux/.build/src/binutils-2.25.1/gold/gold-threads.cc:288:13: error: expected expression [ERROR] make[5]: *** [gold-threads.o] Error 1 [ERROR] make[4]: *** [all-recursive] Error 1 [ERROR] make[3]: *** [all] Error 2 [ERROR] make[2]: *** [all-gold] Error 2 [ERROR] make[1]: *** [all] Error 2 [ERROR] [ERROR] >> [ERROR] >> Build failed in step 'Installing binutils for host' [ERROR] >> called in step '(top-level)' [ERROR] >> [ERROR] >> Error happened in: CT_DoExecLog[scripts/functions@216] [ERROR] >> called from: do_binutils_backend[scripts/build/binutils/binutils.sh@240] [ERROR] >> called from: do_binutils_for_host[scripts/build/binutils/binutils.sh@105] [ERROR] >> called from: main[scripts/crosstool-NG.sh@646] [ERROR] >> [ERROR] >> For more info on this error, look at the file: 'build.log' [ERROR] >> There is a list of known issues, some with workarounds, in: [ERROR] >> '/usr/local/Cellar/crosstool-ng/1.22.0/share/doc/crosstool-ng/crosstool-ng-1.22.0/B - Known issues.txt' [ERROR] [ERROR] (elapsed: 36:53.00) [36:54] / make: *** [build] Error 1 |
查看build.log
可以看到如下的内容:
1 2 3 4 5 6 7 8 9 |
[ERROR] /Volumes/raspberry/rpi-linux/.build/src/binutils-2.25.1/gold/gold-threads.cc:288:13: error: expected expression [ALL ] : once_(PTHREAD_ONCE_INIT) [ALL ] ^ [ALL ] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/pthread.h:203:27: note: expanded from macro 'PTHREAD_ONCE_INIT' [ALL ] #define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}} [ALL ] ^ [ALL ] 1 error generated. [ERROR] make[5]: *** [gold-threads.o] Error 1 [ALL ] make[5]: *** Waiting for unfinished jobs.... |
这个BUG的原因是由于GCC
的版本问题导致的,低于4.7版本的GCC
无法理解这个语法,尽管Mac Osx
已经使用最新的LLVM
,但是遗憾的是,最新的LLVM
并没有支持这个语法。解决方法如下:
1 |
$ vim /Volumes/raspberry/rpi-linux/.build/src/binutils-2.25.1/gold/gold-threads.cc |
找到如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Class Once_initialize. This exists to hold a pthread_once_t // structure for Once. class Once_initialize { public: Once_initialize() : once_(PTHREAD_ONCE_INIT) { } // Return a pointer to the pthread_once_t variable. pthread_once_t* once_control() { return &this->once_; } private: pthread_once_t once_; }; |
修改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Class Once_initialize. This exists to hold a pthread_once_t // structure for Once. class Once_initialize { public: Once_initialize() {once_.__sig = _PTHREAD_ONCE_SIG_init; once_.__opaque[0] = 0;} // Return a pointer to the pthread_once_t variable. pthread_once_t* once_control() { return &this->once_; } private: pthread_once_t once_; }; |
如果出现了"fatal error: bracket nesting level exceeded maximum of 256
",如下所示:
1 2 3 4 5 6 7 8 9 |
[ERROR] /Volumes/raspberry/rpi-linux/.build/src/gcc-5.2.0/gcc/config/arm/neon.md:3463:10917: fatal error: bracket nesting level exceeded maximum of 256 [ALL ] /Volumes/raspberry/rpi-linux/.build/src/gcc-5.2.0/gcc/config/arm/neon.md:3463:10917: note: use -fbracket-depth=N to increase maximum nesting level [ALL ] 47 warnings and 1 error generated. [ERROR] make[2]: *** [insn-attrtab.o] Error 1 [ALL ] make[2]: *** Waiting for unfinished jobs.... [ALL ] 42 warnings generated. [ALL ] 18 warnings generated. [ALL ] rm gcc.pod [ERROR] make[1]: *** [all-gcc] Error 2 |
则修改方法如下:
1 |
$ ct-ng menuconfig |
在出现的界面中选择"Paths and misc options
"项目
在第二级界面中不断下拉,找到"Extra host compiler flags
",增加"-fbracket-depth=512
",这个选项。
然后重新执行
1 |
$ ct-ng build |
如果出现错误:
1 2 3 4 |
[ALL ] /var/folders/h8/_f6dzm814rn1pjrgxgfvcn900000gn/T//ccU8Jut6.s: Assembler messages: [ALL ] /var/folders/h8/_f6dzm814rn1pjrgxgfvcn900000gn/T//ccU8Jut6.s:81: Error: invalid constant (af) after fixup [ALL ] /var/folders/h8/_f6dzm814rn1pjrgxgfvcn900000gn/T//ccU8Jut6.s:163: Error: invalid constant (ff) after fixup [ERROR] make[3]: *** [/Volumes/raspberry/rpi-linux/.build/armv7-rpi2-linux-gnueabihf/build/build-libc-startfiles/csu/libc-start.o] Error 1 |
这个是由于LLVM
目前的版本还无法正确的理解部分GCC
的汇编部分的写法,导致编译失败,而这部分的语法一般都是用在优化的时候出现错误,因此我们需要禁用这部分的优化,使用"Paths and misc options
"->"Extra host compiler flags
"增加 "-fno-unroll-loops
"。如下图:
如果出现如下错误:
1 2 |
[ERROR] make[3]: *** [iconvdata/others] Error 2 [ERROR] make[2]: *** [all] Error 2 |
1 2 3 4 5 6 7 |
[ALL ] make[4]: *** No rule to make target `/Volumes/raspberry/rpi-linux/.build/armv7-rpi2-linux-gnueabihf/build/build-libc-final/iconvdata/MIK.so', needed by `others'. Stop. [ERROR] make[3]: *** [iconvdata/others] Error 2 [ERROR] make[2]: *** [all] Error 2 [ERROR] [ERROR] >> [ERROR] >> Build failed in step 'Installing C library' [ERROR] >> called in step '(top-level)' |
这个问题是由于编译的时候,同时打开的文件数量超过了256
导致的,修复方式为在shell
中增大同时打开的文件数量限制到1024
:
1 |
$ ulimit -n 1024 |
然后在同一个shell
中继续执行
1 |
$ ct-ng build |
如果出现如下错误,则直接忽略即可:
1 2 3 |
[INFO ] Installing final gcc compiler [ERROR] clang: error: unsupported option '-print-multi-os-directory' [ERROR] clang: error: no input files |
至于其他问题,貌似重试一下就可以解决了。
编译树莓派源代码
Ubuntu 16.04 (x64)树莓派B+(Raspberry Pi B+)源代码编译
参考链接
- crosstool-NG on OS X
- [DEBUG] ./.build/tools/bin/install: line 2: exec: ginstall: not found
- Building a toolchain
- fatal error: bracket nesting level exceeded maximum of 256
- [Bug binutils/19311] arm-linux-as build on Mac OS X with Xcode7 fails to
- crosstool-ng的配置参数详解
- Raspberry Pi -- Cross Compiling on Mac OSX
- Cross-compilation in OS X under Linux us crosstool-ng
- mac build woes : homebrew+iconvdata=big trouble
步骤写的非常详细,按图索骥解决了我mac 安装ct-ng的很多问题,谢谢!
没有什么能表达我内心的感激之情
赞