安装ubuntu18.04
-
win10环境
- 处理器:Intel® Core(M) i7-8700 CPU (§) 3.20GHz 3.19 GHz
- 已装RAM:16.0 GB(15.8GB 可用)
- 版本号:1809
- 系统版本:17763.805
- 硬盘可用空间:465GB
进入应用商店点击搜索并输入ubuntu回车,如下:
选择ubuntu 18.04 LTS进入详情页面,点击Get获取应用,稍等片刻之后安装完成,如下:
点击launch启动应用,第一次启动需设置用户名和密码,登录后将不是root用户,但可以增加root用户:
sudo -s
sudo passwd root
根据提示输入密码即可。
配置软件源
使用阿里云软件源即可
cp /etc/apt/sources.list /etc/apt/sources.list.ubuntun
rm /etc/apt/sources.list
vi /etc/apt/sources.list
将阿里云软件源地址填入,再保存退出:
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
# libncurses5-dev lib32ncurses5-dev用到
deb http://ftp.cuhk.edu.hk/pub/Linux/ubuntu xenial main universe
deb-src http://ftp.cuhk.edu.hk/pub/Linux/ubuntu xenial main universe
更新源
sudo apt update
安装编译环境
安装open jdk
sudo apt-get install openjdk-8-jdk
提示:安装 openjdk-8-jdk,会更改 JDK 的默认链接,这时可用:
sudo update-alternatives --config java
sudo update-alternatives --config javac
查看jdk版本
root@xxx:/mnt/e/source# java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
root@xxx:/mnt/f/source#
安装编译工具包 for Ubuntu 18.04
sudo apt-get install gcc python bc git-core gnupg flex bison gperf libsdl1.2-dev \
libesd0-dev squashfs-tools build-essential zip curl \
libncurses5-dev zlib1g-dev pngcrush schedtool libxml2 libxml2-utils \
xsltproc lzop libc6-dev schedtool g++-multilib lib32z1-dev lib32ncurses5-dev \
lib32readline6-dev gcc-multilib libswitch-perl libssl1.0.0 libssl-dev
这里参考Ubuntu 14.04的工具包并做了一些修正:
新增了bc
,gcc
,python
lib32readline-gplv2-dev
修改为lib32readline6-dev
libwxgtk2.8-dev
安装出错,提示未定位包,需要单独安装,并且在18.04版本中更新到了3.0
sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install libwxgtk3.0-dev
使bash支持32位程序运行
安装qemu并设置binfmt
sudo apt update
sudo apt install qemu-user-static
设置binfmt
sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'
启动服务
sudo service binfmt-support start
注意:binfmt服务在每次启动bash控制台时都需要启动
否在在运行32位程序时会报如下错误:
-bash: ./hello: cannot execute binary file: Exec format error
启动服务后可以写个helloworld编译成32位用来测试
root@xxx:/mnt/e/source/sample# cat hello.c
#include <stdio.h>
int main(){
printf("Hello world!\n");
return 0;
}
root@xxx:/mnt/e/source/sample# gcc -o hello hello.c -m32
root@xxx:/mnt/e/source/sample# file hello
hello: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, BuildID[sha1]=c8fa4a5c2e5b622f15e3c37d87fd37c3ef42ca5c, not stripped
root@xxx:/mnt/e/source/sample# ./hello
-bash: ./hello: cannot execute binary file: Exec format error
root@xxx:/mnt/e/source/sample# service binfmt-support start
* Enabling additional executable binary formats binfmt-support [ OK ]
root@xxx:/mnt/e/source/sample# ./hello
Hello world!
root@xxx:/mnt/e/source/sample#
下载Android源码
先创建一个用于存放源码的文件夹,比如E:\source
打开命令行或powershell输入 :
PS C:\Windows\system32> fsutil.exe file setCaseSensitiveInfo E:\source enable
已启用目录 E:\source 的区分大小写属性。
PS C:\Windows\system32>
linux使用的是大小写不敏感文件系统
此后E:\source
文件夹下创建的目录都会继承大小写不敏感这个属性
否则编译Android系统时会出现如下问题:
Case-insensitive filesystems not supported
然后将源码下载至此目录
解压编译过程参考FireFly的官方文档。因为在win10-bash上编译会出很多问题,所以才有下面内容。
解压后同步下最新代码
git reset --hard
git remote add gitlab https://gitlab.com/TeeFirefly/firenow-oreo-rk3399.git
git pull gitlab firefly-rk3399:firefly-rk3399
编译kernel
./FFTools/make.sh -k -j12
编译uboot
./FFTools/make.sh -u -j12
编译Android
注意:必须使用管理员权限打开ubuntu控制台
否则可能会报出Permission denied
的错误,即使你是root
个人推测win10下权限级别如下
win10管理员 > ubuntu root > ubuntu 其他用户
./FFTools/make.sh -a -j12
报错:ftruncate(fd_out, GetSize()): Invalid argument
[ 45% 37395/82723] Generating TOC: out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc
FAILED: out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc
/bin/bash -c "(ASAN_OPTIONS=detect_leaks=0 prebuilts/build-tools/linux-x86/bin/ijar out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc.tmp ) && (if cmp -s out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc.tmp out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc ; then rm out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc.tmp ; else mv out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc.tmp out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc ; fi )"
ftruncate(fd_out, GetSize()): Invalid argument
/bin/bash: line 1: 7485 Aborted (core dumped) ( ASAN_OPTIONS=detect_leaks=0 prebuilts/build-tools/linux-x86/bin/ijar out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar.toc.tmp )
[ 45% 37418/82723] target Java: core-all (out/target/common/obj/JAVA_LIBRARIES/core-all_intermediates/classes)
ninja: build stopped: subcommand failed.
12:18:11 ninja failed with: exit status 1
意思是说程序prebuilts/build-tools/linux-x86/bin/ijar
在将classes.jar
转化为classes.jar.toc.tmp
时出了问题,对应源码位置是build\make\tools\ijar
,目录下存在以下这些文件:
- 解决方法1
修改zip.cc
文件998行
void *zipdata_out = mmap(NULL, mmap_length, PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, fd_out, 0);
- 解决方法2
去掉zip.cc
文件的936行:
int OutputZipFile::Finish() {
if (fd_out > 0) {
WriteCentralDirectory();
//if (ftruncate(fd_out, GetSize()) < 0) {
// return error("ftruncate(fd_out, GetSize()): %s", strerror(errno));
//}
if (close(fd_out) < 0) {
return error("close(fd_out): %s", strerror(errno));
}
fd_out = -1;
}
return 0;
}
注:也可以参考对比ijar
的仓库代码
保存并使用g++编译,生成新的ijar
:
g++ -o ijar classfile.cc zip.cc ijar.cc -lz
测试下看是否报错:
从out目录拷贝刚才出错的classes.jar
root@xxx:/mnt/e/source/Android8.1_RK/build/make/tools/ijar# cp ../../../../out/target/common/obj/JAVA_LIBRARIES/sdk_v9_intermediates/classes.jar classes.jar
root@xxx:/mnt/e/source/Android8.1_RK/build/make/tools/ijar# ls
Android.bp LICENSE README.txt classes.jar classfile.cc common.h ijar ijar.cc zip.cc zip.h zip_main.cc
root@xxx:/mnt/e/source/Android8.1_RK/build/make/tools/ijar# ./ijar classes.jar classes.jar.toc.tmp
root@xxx:/mnt/e/source/Android8.1_RK/build/make/tools/ijar# ls
Android.bp README.txt classes.jar.toc.tmp common.h ijar.cc zip.h
LICENSE classes.jar classfile.cc ijar zip.cc zip_main.cc
root@xxx:/mnt/e/source/Android8.1_RK/build/make/tools/ijar#
可以看出没有报错而且文件生成成功!
备份原来的ijar
并替换:
cp ../../../../prebuilts/build-tools/linux-x86/bin/ijar ../../../../prebuilts/build-tools/linux-x86/bin/ijar.backup
cp ijar ../../../../prebuilts/build-tools/linux-x86/bin/ijar
继续编译:
./FFTools/make.sh -a -j12
报错:dex2oat did not finish after 2850 seconds
dex2oatd F 10-30 18:28:31 27007 27014 art/dex2oat/dex2oat.cc:523] dex2oat did not finish after 2850 seconds
Zygote loaded classes=4924 post zygote classes=1307
Intern table: 43071 strong; 0 weak
JNI: CheckJNI is off; globals=46 (plus 18 weak)
Libraries: (0)
Heap: 98% free, 1011KB/64MB; dex2oatd F 10-30 18:29:21 27007 27014 thread_list.cc:760] Timed out waiting for threads to suspend, waited for 50.000s
Runtime aborting...
- 解决方法1
针对出错的项目关闭odex生成,找到编译不过去的app或jar包的mk文件,加上LOCAL_DEX_PREOPT := false
缺点:只能一个一个去找,去添加,较麻烦
- 解决方法2
如果是boot.jar出现这个问题
在build\make\core\dex_preopt_libart_boot.mk
文件中追加-j1
,使用单线程编译odex
如果是某个app出现这个问题@rm -f $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))/*.oat $(DEX2OAT) -j1 --runtime-arg -Xms$(DEX2OAT_IMAGE_XMS) \ --runtime-arg -Xmx$(DEX2OAT_IMAGE_XMX) \
在build\make\core\dex_preopt_libart.mk
文件中追加-j1
,使用单线程编译odex
也可使用变量判断当前$(hide) mkdir -p $(dir $(2)) $(hide) ANDROID_LOG_TAGS="*:e" $(DEX2OAT) -j1 \ --runtime-arg -Xms$(DEX2OAT_XMS) --runtime-arg -Xmx$(DEX2OAT_XMX) \ --class-loader-context=$(DEX2OAT_CLASS_LOADER_CONTEXT) \
HOST_CROSS_OS
变量是否为windows
,如果是的话使用单线程编译
因为这编译这类文件的数量不多,因此不用担心影响总体编译效率
报错:futex cmp requeue failed for ...
打印了一堆native堆栈和线程信息
解决方法同上
编译成功!
in=/mnt/e/source/Android8.1_RK/out/target/product/rk3399_firefly_mid/oem.img out=/mnt/e/source/Android8.1_RK/out/target/product/rk3399_firefly_mid/oem.img.out align=1024
Total of 131072 4096-byte output blocks in 14 input chunks.
Generating optimized sparse image done,total_chunk=10.
create uboot.img...done.
create trust.img...done.
create loader...done.
create resource.img...done.
create kernel.img...done.
create parameter...done.
Firefly-RK3399 make images finish!
附
成功记录
以下为已测试编译通过的windows环境(不定期更新)
CPU | 核心/线程 | RAM | Window版本 | Ubuntu 版本 | 完全编译用时 |
---|---|---|---|---|---|
i7-8700 | 6C12T | 16GB DDR4 | 1809 17763.805 | 18.04 | 约2:30:00 |
i7-8700 | 6C12T | 16GB DDR4 | 1903 18362.418 | 18.04 | 约2:30:00 |
i5-7500 | 4C4T | 16GB DDR4 | 1903 18362.387 | 18.04 | 约2:55:00 |
另外建议磁盘可用空间在200GB以上
bash和cmd之间的切换
在ubuntu命令行输入cmd.exe
切换到cmd模式,再输入exit
退出cmd回到ubuntu命令行
同理也可以再cmd窗口下输入bash
进入到ubuntu命令行
root@xxx:/mnt/e/source/Android8.1_RK# cmd.exe
Microsoft Windows [版本 10.0.18362.418]
(c) 2019 Microsoft Corporation。保留所有权利。
E:\source\Android8.1_RK>dir device
驱动器 E 中的卷没有标签。
卷的序列号是 0E51-1454
E:\source\Android8.1_RK\device 的目录
2019/10/29 10:27 <DIR> .
2019/10/29 10:27 <DIR> ..
2019/10/29 10:27 <DIR> rockchip
2019/10/29 10:27 <DIR> sample
0 个文件 0 字节
4 个目录 330,965,643,264 可用字节
E:\source\Android8.1_RK>exit
root@xxx:/mnt/e/source/Android8.1_RK#
想必你也发现什么了吧,what ?竟然可以运行windows命令!!!
其实还可以运行其他的,比如:
root@xxx:~# fsutil.exe file setCaseSensitiveInfo E:\source enable
已启用目录 E:\source 的区分大小写属性。
root@xxx:~#
root@DESKTOP-2HP654K:~# ipconfig.exe
Windows IP 配置
以太网适配器 以太网 2:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
无线局域网适配器 本地连接* 9:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
不得不说windows的强大!
注意:
- 运行window命令要加后缀.exe
- 使用部分命令时当前命令行窗口要以管理员权限运行
更多强大的功能希望大家共同探索!
总结
使用window编译Android源码的好处
- 学习源码门槛大大降低,大量windows工具帮你更快阅读源码,并同时拥有find命令
- 文件系统共享,不用像虚拟机一样一个文件拷来拷去
- 效率高于虚拟机
- 使得window软件和linux程序同时运行,避免双系统切换的情况
- shell脚本里可以编写并执行windows和linux的混合命令
当然也不可能完全与纯ubuntu系统媲美,希望微软大大继续改善!
参考文章
编译 Android8.1 固件
Linux 64位安装32位运行库(解决rk3399 make kernel.img error)
解决ubuntu安装东西时出现"E: Sub-process /usr/bin/dpkg returned an error code (1) "的错误
Bash On Windows(WSL)无法运行32Bit程序,报错 Exec format error解决办法
报错:Aborted (core dumped) (classes.jar.toc.tmp )
报错:dex2oatd F dex2oat did not finish after 2850 seconds