這個星期開始的時候就準備搗鼓一下安卓了。可惜那邊的任務沒做好。在加上linux下VPN總是連不上。週末痛定思痛,還是不能對自己能力以外的事情執念太深,所以還是放下了手頭的事情。
VPN的問題其實還是我自己的問題。我以爲linux下只要一輸入網關,外加用戶名和密碼就可以了,不去官網先看一下使用說明書。結果人家的加密方式根本不是默認的……
那本書其實也很老了,但是我看網上風評很好還是忍不住買了。比如開始提供下載repo的網址無效了,不過去博客上看了一下,果然13年的時候就換了。這個網址是谷歌提供的安裝的具體過程和方法:
http://source.android.com/source/downloading.html
linux是大小寫區分的,好久沒用都忘了……我開始以爲/bin就是~/bin的意思,後來一敲repo發現不對,原來都忘了linux root也是用戶,也是有一個單獨的區的。
curl是一個linux下的http命令行工具。這個工具很有意思,可惜我早已習慣了瀏覽器。
谷歌提供了一組SHA-1校驗碼來確保下載的文件是正確的。不過這個repo版本號怎麼看臥槽……肉眼識別了一下……
下載的過程有點慢……於是找到了一篇非常棒的文章,是引用了git的用戶手冊,不過有中英文對照這個point真是一下俘獲了我的心:
http://blog.csdn.net/zzulp/article/details/6238527#Chapter1.RepositoriesandBranches.2BeyxOAHrg..2BckhnLF6TTg5SBmUv-
不過我覺得基本的操作記住幫助語法就足夠了……其實這個git手冊有點類似與介紹軟件開發管理——這個我在linux原理一課上也聽那個老師吹過一次。不知道自己有沒有TK那般把這個手冊當小說看的毅力……
下载的过程开始没遇到什么特别的问题,除了VPN经常断线……感觉需要个脚本……然后:
http://source.android.com/source/downloading.html#using-authentication
上面的认证,是谷歌用来保证服务器稳定(总让我感觉是防御DDoS的)的策略,每一个IP都有一个quota。因为VPN肯定是一个类似于NAT的东西,我每次得到的IP地址应该是共享的。这导致我似乎被谷歌封锁了——因为HTTP响应为406——这怎么可能呢!
不过我按照谷歌这里的提供的脚本(好象是访问时附加了自己的ID和一个约定的口令?)校正了一下以后:
还是卡死在这个99%,不过这次没有错误响应报文了……醉了……这个网址点进去一看好好的,明明可以正常访问的。由于VPN是加密的,我是抓不了包了。不知道是不是不够耐心(也许是在下载,但是这一次不显示进度了?)。唉,水平次就只能用时间弥补了呗。
结果……我的无线网卡又抽风了,为了保存这个日志,我还是拔了室友的以太网线来救火的……又白等了一次同步……
这里有一篇博文挺有意思的,很多地方写的挺详细的,有参考价值。不过我要是知道有弄好的包,我才懒得去一步步捣鼓这些呢……我不认同这种自己搭环境就会显得更厉害更有实践经验的想法,除非这个环境中出现的每一个问题,都是自己掌握并解决的,搜索引擎带给我们前人丰富的经验,可不能让懒惰的头脑变得更睿智。当然,这里谷歌给的脚本是造福了我等无知弱鸡了……总之,我觉得掌握知识比邯郸学步要重要的多。
后来,我发现这个问题在谷歌的帮助issues里出现过:
我当时就被原因吓cry了……居然是TCP/IP协议栈的问题,这个根本在国内网站找不到好么~他修改了一个叫做窗口扩展(window scaling)的内核参数。
就当我满心欢喜的以为问题终于解决了……居然还是卡死……what a fucking day!
再次漫漫搜索之旅……发现stackoverflow上有人也遇到类似问题了,而且也是修改了WS参数不能解决——结果他竟然说是机器问题,直接把code删了,what a fuck!我大中华局域网重下还能玩?不过这个人提醒了我trace下载结果:
于是我就想着,反正已经完成大半,不如试试能不能编译?结果跑起来的时候说要open JDK 7……哦,那是什么鬼,感觉一看名字就知道又是开源和闭源之争了……把JDK由SUN JDK切换成OPEN JDK需要update-alternatives。这是debian提供的软件版本切换装置。
不过后来,我发现我的根目录并不够用了——这也许是我不能继续下载的原因?没办法,当初没眼界就给双系统的linux分了40GB左右,结果没想到一转眼就用完了,都不知道为什么……扩容就要unmount(不知道怎么说,叫卸载?)根目录,实在没有心思和气力去做这种危险的事情……
只能忍痛放弃了在实体机上的linux了……好不开心啊……
后来在虚拟机上就变懒了——直接找国内人的资源了。我找的是Lollipop(5.0),不过最新的好像是5.1了。也挺不错的,反正老罗的书才2.3……
好笑的是我虚拟机上分配的linux更小……不过反正有共享文件夹嘛,没事。不过共享文件夹除了需要设置VM,下载VM tools以外,还需要一个插件open-vm-dkms才能挂载这个文件夹(应该也可以不用,但是估计手工比较麻烦),这个工具Ubuntu的源好像很容易下载,debian的话我去官网上找了一下也有,不过是deb包:
https://packages.debian.org/wheezy/all/dkms/download
之后输入命令:sudo mount -t vmhgfs .host:/ /mnt/hgfs
继续按照之前的步骤,把JAVA调成OPEN JDK 7,下载编译时的一些依赖……话说这个压缩包我解压的时候用的是实体机上的windows 7,因为虚拟机分配的资源很少。我WIN7上的解压软件是好压,结果最后卡在100%不动了,而且估计时间变成了一个四十亿左右的值,这个值让我的第一反应是int32的溢出,然后用windows自带的计算器算了一下,果然很像,尤其是那个42949(后面的记不清了)。我以为haozip会就此崩溃呢,等了大约10分钟吧,忍不住用process monitor看了一下,结果居然发现好压神奇的还在读写文件(差点就放弃了)……果然片刻后好压解压终止了。百度了一下,果然windows下限制了有些命名,原因是跟设备冲突。
中间有几个文件夹无法创建,可能是windows命名空间的问题。打开错误日志看了一下,发现第一个是一个叫做AUX的文件夹。于是查了一下,这个名字是某种逻辑设备的名称,和COM这种一样,在WIN7里属于保留字。如果命名为这种保留字,那么对于这种文件夹的访问就会被定位到逻辑设备上,造成问题。我开始想的是,如果我把文件对于SYSTEM的权限去掉,是不是对于系统就不可见了呢?用一个普通的文件试了一下好像不行。在不知道哪里的论坛看到一个机(xie)智(men)的方法——在CMD里mkdir一个目录aux,这个目录在资源管理器里居然能正常打开!我们可以看到多出了一个aux的目录:
不过这个文件夹不可以被手工删除,报的错是找不到aux这个项目。可能是窗口返回值就用到aux这个字符串作为参数?不过用腾讯管家的解锁删除可以删除掉这个文件夹。
试了一下rename或者其他指令并不能得到同样的结果。所以这是这个指令的实现有问题?绕过了windows名称检查?
第二个居然又是另一个问题——windows下不支持名称相同但格式不同的文件,共享扩容路漫漫啊。这个在windows倒是很常见,以至于我都以为真的就是这样了。这个问题好像更难一些,
中间把这个文件夹的内容拷贝下来的时候好压又假死了。我用process monitor看到这个地方返回name not found:
HKLM\SOFTWARE\Microsoft\CTF\KnownClasses
国外有人在装VS的时候遇到过这个问题。不过他改的方法非常hacky,而且是对VS下的一个为SP的值做修改(难道是让OS以为自己是XP?)。也就是说这里其实是一个和具体软件有关的键值?注册表没学过……不过也可能是这里aux的原因?
不过其实也没有影响大局,最后剩下的部分就放到linux里了。开始我想用tar的-k解决,结果发现太慢(好像是相当于解压的遍历,只不过省去文件复制环节),于是还是指定了一下文件夹,果然快了一些,看来指定了以后它是先搜索字符串的(这么说来其实也是遍历?),最重要的是可以先看一下文件夹的内容,心中有数,然后-v列出的项目都包括了之后就直接终止进程。不过总算是把这些琐事结束了吧。
开始编译。开始的第一个问题就终结了我32位编译的欲望……恩……:
build/core/envsetup.mk:94: *** Unable to determine HOST_ARCH from uname -sm: Linux i686!
看英文就知道怎么回事了,这是x86和x64架构问题,这在书里提到了。不过沿着路径打开这个mk:
# HOST_ARCH
ifneq (,$(findstring x86_64,$(UNAME)))
HOST_ARCH := x86_64
HOST_2ND_ARCH := x86
HOST_IS_64_BIT := true
endif
ifeq ($(HOST_PREFER_32_BIT),true)
SDK_HOST_ARCH := x86
else
SDK_HOST_ARCH := $(HOST_ARCH)
endif
BUILD_ARCH := $(HOST_ARCH)
BUILD_2ND_ARCH := $(HOST_2ND_ARCH)
ifeq ($(HOST_ARCH),)
$(error Unable to determine HOST_ARCH from uname -sm: $(UNAME)!)
endif
我发现谷歌的代码非常清晰的表明他有两种选择。显然是自老罗之后谷歌的服务更人(ruo)性(zhi)化了。那么编译不成功肯定是因为少了步骤,比如make之前这个变量需要人为手动的去赋值。
kali的版本是32位的(file /sbin/init)。由于罗在书中所用的版本较低,所以他所说的方法和具体的文件有些出入。我就试了试先修改了这里:
# HOST_ARCH
ifneq (,$(findstring i686,$(UNAME)))
HOST_ARCH := x86_64
HOST_2ND_ARCH := x86
HOST_IS_64_BIT := true
endif
然后编译。但是这里有二进制文件执行不了,应该是个64位ELF文件。按理说,既然有2ND_ARCH这样的标号,那么谷歌应该留下了x86有关的东西啊?我本来猜是x86的执行分支,看来似乎不是?本来想放到source insight里看一下的,不过好像符号太多了(也许我该只拖入一个文件夹的)。
于是又搭起VPN去官网
http://source.android.com/source/building-running.html
详细的令人发指,不过这里主要只是指定生成的target而不是对host的要求(当然,我觉得默认选项就挺好的,只要是带有debug和ARM架构的模拟器就行了)。对HOST,谷歌只有一句话,对于2.3.x以上版本应该在64bit环境编译——what a fuck!
repo的下载需要VPN。虚拟机好像默认设备不是托管的(也就是图像化配置无效),需要
/etc/NetworkManager/NetworkManager.conf将managed=false改成true,重启一下就可以了。
在虚拟机里用repo init时python脚本报错—— OSError: [Errno 95] Operation not supported。结果放到谷歌上一看,竟然是MS-DOS文件系统不支持POSIX标准。本来想偷点懒让二者共享文件,这样修改起来也方便……没想到文件系统不兼容挺麻烦。所以要用repo最好不用共享文件夹。
不是我不想探索……水平有限就要集中精力做有用的事……于是打开了许久未用的Ubuntu 12.04。果然,同样是很小。不过VM扩容倒是也很容易,直接关机以后扩展磁盘,然后开机以后格式化这个分区然后挂载即可。
到Ubuntu下的时候我这几步我已经麻木了……深深体会到了文件复制的恶意……感觉开始直接复制压缩包到系统里然后再解压会更快一些?
有些沮丧,所以又出了一点操作上的小问题——安装了OPEN-VM-DKMS之后,需要关机以后配置共享文件夹。我不记得这个顺序了,所以当时挂载VM TOOLS的共享文件目录时出现:cannot mount filesystem:INPUT/OUTPUT ERROR。实际上关机配置好就行了。
然后是拷贝文件……结果挂载新扩展的磁盘空间的时候没有挂上(可能又是没有重启的原因,记不清了),我又没有用df命令确认一下,结果文件直接拷贝在了我系统原来的空间……还好因为中间磁盘空间不足中断了……不过那时候已经拷贝了好多G了……感觉是有点焦躁了……
在直接拷贝谷歌关于环境设置更新的命令时出了一点问题:
$ sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib mingw32 tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
凡是带有i386的均找不到软件包。我想看看为什么,于是下了个apt自动补齐的插件:(这个在debian里面好像已经自带了?)
apt-get install bash-completion
编辑~/.bashrc 文件(好玩的是人家早已经写好在里面了)
所以实际上最后我编辑的是/etc/bash.bashrc。因为这是一个全局配置文件。
最后重新登录(而不是重启,因为bash相关的脚本都是在登录时读取执行),或者用source命令。
使用apt-get的过程中,有错误,我开始以为它和apt是平行的关系,所以没管它:
dpkg: error: configuration error: /etc/dpkg/dpkg.cfg.d/multiarch:1: unknown option 'foreign-architecture'
然后感觉不对,查了下发现apt会用到这个debian里的软件管理工具。这个问题百度了一下,发现有人直接删除了这个配置文件夹。这应该是最简单粗暴的方法,当然,删除multiarch比删除这个目录更好。我只是不喜他非常好心的告诉别人,这个问题查不到的,就像我这样做吧。
debian的官网上有关于这个dpkg报错:https://wiki.debian.org/Multiarch/Issues
具体来说,是multiarch导致的。这其实是debian开发的良好特性,参看:Ubuntu软件支持MultiArch。
debian官网上说,对于incompatible versions 的release,dpkg是无效的。问题是Ubuntu 12.04应该是比较稳定的版本啊。谷歌了一下,这个问题出现的频率倒是挺高的,除了让其直接删除multiarch的方法外,大部分是建议先 dpkg --
print-foreign-architectures
因此,我发现问题好像在于dpkg软件包不全。为什么呢?我是这么推测的:正是很多新手并没有频繁的更新软件库的习惯,比如在这个目录下:
而实际上Ubuntu提供的dpkg在这个目录下应该还有大量的“插件/工具”(不是搞linux的,不知道这个专业的说法),也就是这里提供的只是一个核心,并不具有完整的dpkg的功能。
因此,即使我们看到的版本是较高的:
实际上依然不支持foreign-architecture等需要插件的选项。而很多社区的人下意识的就先认为dpkg的配置是正确的,所以对于这个问题实际上是想多了……(更新时需要先把这个multiarch去掉,删了也没事)
前几天去Ubuntu官网下了个Kylin系统(好像是麒麟的意思),反正原本的Ubuntu有很多依赖没有下载,我等的也挺烦的,干脆弄了个中国版的看起来爽多了。
然后尝试着编译源代码,其中会出现一些找不到文件之类(src)的错误,这个好像是因为没有内核的原因,并不用担心,因为他没有停止编译,也没有警告或者报错。
编译中的问题相比之下实在是微不足道,这可能也是因为我已经按照谷歌给出的依赖完整的安装了。
旧版的解决方案是:
Solution:
Modify the./framework/base/tools/localize/Android.mk file
ifeq ($(HOST_OS),linux)
#LOCAL_LDLIBS + = -lrt put the line commented out, to the following line.
LOCAL_LDLIBS += -lrt -lpthread
endif
可惜,对于5.0这已经行不通了。但是通过这部分的修改我们可以看到这个改动似乎和线程有关,莫非是需要线程同步?我在googlegroup上看到了一个人解决了这个类似的问题:
Very fortunately ! I have solved this error, just make clean and rebuild project is work well ! the reason of this error is "make" command is interrupted by other thread, so a few file compiled is not complete. In another words, we must keep it going on until it finished by itself every time, otherwise, you will meet the many others unexpected problems.
我之前虽然想到可能是同步问题而导致的,但是我只是设置了-j1这个编译选项而没有make clean。但是重新编译以后依然会出现问题。
最后编译时遇到一点小问题:
我以为是update-alternatives链接没写好。结果打开公共链接查看属性时发现是对的。于是我查了一下这个动态链接库的位置:
find /usr/lib/jvm -name libjli.so
当然,这个文件在JDK6确实是存在的。当我打开公共链接的时候,终于发现还有jar等几个可执行文件。jar也是一个编译时的选项,而这个设置的时候谷歌的官网没有提及,所以被我忽略了。不过如果是apt安装的sun jdk应该就不会有这个问题了。