前段时间写了 CyanogenMod 编译 Google Galaxy Nexus (GSM) 全过程     一文,但是仅仅编译一个三星的版本有些朋友说在编译其他的版本的时候发现还是不能搞定,所以我又尝试编译了三星 Galaxy Note的手机,这个东西 CyanogenMod 官方文档已经写得十分清楚,我在编译的过程中主要遇到的问题有:


1  相关手机上的库文件与实际编译的时候需要的库文件不一致,主要表现在实际手机上的库文件没有实际编译的时候需要的库文件多。具体表现在 ./extract-files.sh 这个脚本执行后出现了

remote object '/sbin/cbd' does not exist
remote object '/system/bin/bcm4330B1_murata.hcd' does not exist

类似这样的错误。


2  在编译过程中ubuntu自带的解压缩工具在解压缩linux内核的时候缺少文件,导致编译出错,后来改用7z工具解压缩解决了该问题。


3 本身ndk的bug,在cmd中执行一下  unset NDK_ROOT 这个命令搞定。


ok 接下来继续将这次的编译过程记录如下:


一 前提条件:
1 配置好 android的编译环境
 配置方法详见  http://source.android.com/source/initializing.html 网页

2 下载源码

  curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
  需要用 CyanogenMod 提供的 repo工具

  repo init -u git://github.com/CyanogenMod/android.git -b cm-10.2  
  下载相应的分支

  repo sync
  下载

  下载过程很长,并且还有下载一半中断的情况,多下几次,确保下载完成,硬盘要准备足够大,
  我准备了100G

3 Samsung Google Galaxy Note (International) ("n7000") 手机一部

  前提条件和上一篇文章是一样的,连代码下载的分支都是一样的,所以要是已经下载过cm-10.2 分支就不用再下载了,省了好多时间。

 


二 重要网页

   主要网页
   http://wiki.cyanogenmod.org/w/N7000_Info


   编译网页
   http://wiki.cyanogenmod.org/w/Build_for_n7000



三 编译源码
1 编译前的准备工作
 cd ~/android/system/vendor/cm
 ./get-prebuilts


2 $ source build/envsetup.sh

 $ breakfast n7000

 不要想着这两个命令了,由于网络原因,breakfast这个命令基本上是行不通的。

 直接下载驱动包好了

 http://www.github.com/cyanogenmod/android_device_samsung_n7000

 下载下来,驱动包很小,解压缩以后放在

 cm-10/device/samsung/n7000 这个目录下,这个目录是没有的,需要自己新建一下

 

3 ./extract-files.sh

 首先连接好samsung note手机,然后来到 cm-10/device/samsung/n7000 这个目录下,执行上面的指令。

 这个脚本的主要作用是将手机中的驱动so库pull出来,然后新建 cm-10/vendor/samsung/n7000这个目录,然后在里面放相应的库文件。

 ok,执行,首先报错

 错误1:

 ./extract-files.sh: 104: ./extract-files.sh: ./../../../device/samsung/galaxys2-common/extract-files.sh: not found

 由于n7000的很多驱动是基于 galaxys2-common 驱动包的,所以需要预先下载 galaxys2-common 驱动包,这也是为何 n7000 驱动包那么小的缘故。


 从 https://github.com/CyanogenMod/android_device_samsung_galaxys2-common

 这里面将 galaxys2-common 驱动包下载下来,放到 cm-10/device/samsung/galaxys2-common 这个目录下,这个目录本身是没有的,需要新建。

  解决了错误1,继续执行 ./extract-files.sh 这个命令,出现了错误2

   错误2:

remote object '/sbin/cbd' does not exist
remote object '/system/bin/bcm4330B1_murata.hcd' does not exist
remote object '/system/bin/bcm4330B1_semcosh.hcd' does not exist
remote object '/system/etc/wifi/bcmdhd_apsta.bin' does not exist
remote object '/system/etc/wifi/bcmdhd_mfg.bin' does not exist
remote object '/system/etc/wifi/bcmdhd_p2p.bin' does not exist
remote object '/system/etc/wifi/bcmdhd_sta.bin' does not exist
remote object '/system/lib/libfactoryutil.so' does not exist
remote object '/system/lib/libomission_avoidance.so' does not exist
remote object '/system/lib/libsecnativefeature.so' does not exist

 关于错误2 有两种解决方法,第一种是从
https://github.com/DonkeyCoyote/proprietary_vendor_samsung
链接下面的文件包含了目前三星设备绝大部分的device驱动包。  

 下载到驱动包,然后将缺少的so adb push到手机里面,然后再./extract-files.sh出来,另外一种是 直接拷贝到相应的 /cm-10/vendor/samsung/ 目录下,第二种比较方便,但是可能需要自己新建文件夹,第一种比较自动化,也不容易错误。


我的那台机器装不上 root explorer文件管理器

remote object '/sbin/cbd' does not exist  这个暂时没有拷贝进去

当时就没有管这个错误,为后面编译的时候报错埋下伏笔。

 
4 真正编译

 赶脚配置完成了,然后开始按照官方文档进行编译了

 $ croot

 $ brunch n7000


   不幸的是,立马报错


build/core/product_config.mk:238: *** _nic.PRODUCTS.[[device/samsung/n7000/cm.mk]]: "hardware/samsung/exynos4210.mk" does not exist.  Stop.

缺少samsung硬件基础库。

https://github.com/CyanogenMod/android_hardware_samsung
下载后将里面的文件替换到 hardware/samsung/下面。


再次编译,依然报错

build/core/base_rules.mk:130: *** external/webrtc/src/system_wrappers/source: MODULE.TARGET.STATIC_LIBRARIES.libwebrtc_system_wrappers already defined by external/webrtc/src/system_wrappers/source.  Stop.

是因为安装了ndk的缘故

Apparently there is a bug in the webrtc makefiles that causes it to ignore including STL if the NDK_ROOT environmental variable is previously defined (by .bashrc, in my case). So just make sure NDK_ROOT is not defined at all when building. You can temporarily unset it with this command:

在cmd中执行一下  unset NDK_ROOT 这个命令吧


unset NDK_ROOT 问题解决以后,又报了
Can't open kernel/samsung/smdk4412/arch/arm/configs/cyanogenmod_n7000_defconfig: No such file or directory at -e line 1.
Can't open kernel/samsung/smdk4412/arch/arm/configs/cyanogenmod_n7000_defconfig: No such file or directory at -e line 1.
make: *** No rule to make target `/Disk/CyanogenMod/cm-10/out/target/product/n7000/kernel', needed by `/Disk/CyanogenMod/cm-10/out/target/product/n7000/boot.img'.  Stop.

这个错,看了一下cm的目录,显然没有kernel那个目录,下载
https://github.com/cyanogenmod/android_kernel_samsung_smdk4412
这个内核,然后在项目根目录下建立 kernel/samsung/smdk4412,将内核文件拷贝过去
内核解压缩了以后 发现也有500多M


前面没有理 remote object '/sbin/cbd' does not exist
这个错误,果然下面开始报错了
make: *** No rule to make target `vendor/samsung/galaxys2-common/proprietary/sbin/cbd', needed by `/Disk/CyanogenMod/cm-10/out/target/product/n7000/root/sbin/cbd'.  Stop.

其实脚本从手机中将那些命令和库拷贝出来,也是要放在一个目录下供编译的时候使用的,所以分析一下galaxys2-common的 extract-files.sh 这个脚本即可  

PRODUCT_COPY_FILES += \\
   \$(LOCAL_PATH)/proprietary/sbin/cbd:root/sbin/cbd


其实就是拷贝到
vendor/samsung/galaxys2-common/proprietary/sbin
这个目录下,目前打开其实是空,手机里面既然打不进去,那电脑上拷贝过去得了


再次编译,编译的时间很长,需要耐心等待一会儿


中间又报了下面的错误
Warning: AndroidManifest.xml already defines minSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.
Warning: AndroidManifest.xml already defines targetSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory `/Disk/CyanogenMod/cm-10/kernel/samsung/smdk4412'
make: *** [TARGET_KERNEL_BINARIES] Error 2
No rule to make target `net/netfilter/nfnetlink.o', needed by `net/netfilter/built-in.o'.  Stop.
这个错误我查了一下,发现竟然是解压缩kernel包的时候,漏解压缩几个文件,也许是kernel包太大或者是ubuntu自带的解压缩工具有bug吧,反正在 net/netfilter/这个目录下 压缩包里面的文件比解压缩后的文件夹中的文件多了3个,并且还不知道其他的目录会不会有这样的情况!

后来编译的时候,发现依然会报缺少其他文件的错误,真是坑爹啊
索性不用 ubuntu自带的解压缩工具了,直接下载了一个7z工具,
apt-get install p7zip-full

解压缩
7z -x android_kernel_samsung_smdk4412-cm-10.2.zip
覆盖原来的文件夹,再次继续编译


这一次终于编译成功了,整个过程还是轻松加愉快,只不过很多samsung包需要准备耽误了时间。