在Android Studio代碼調試一文中,簡單的介紹了代碼調試的一些技巧.現在我們來談談Android源碼編譯的一些事.(俺認為,作為android developer人人都應該有一份自己Android源碼,這樣我們就可以隨時對自己有疑惑的地方通過親手調試來加強理解).
本文適用於Ubuntu 16.04上編譯Android 6.0.*,其他情況請酌情處理,自行參考官網吧.
請首先確保自己已經安裝了Git.沒安裝的同學可以通過以下命令進行安裝:
sudo apt-get install git
git config –global user.email 「[email protected]」
git config –global user.name 「test」
② android源碼怎麼編譯生成recovery.img
recovery.img生成過程
L630-L637 依賴關系
(From: build/core/Makefile)630 $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) /631 $(INSTALLED_RAMDISK_TARGET) /632 $(INSTALLED_BOOTIMAGE_TARGET) /633 $(recovery_binary) /634 $(recovery_initrc) $(recovery_kernel) /635 $(INSTALLED_2NDBOOTLOADER_TARGET) /636 $(recovery_build_prop) $(recovery_resource_deps) /637 $(RECOVERY_INSTALL_OTA_KEYS)
INSTALLED_RECOVERYIMAGE_TARGET 為我們的編譯目標:
584 INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
它依賴很多其它目標:
1.MKBOOTFS, MINIGZIP, MKBOOTIMG,PC端工具軟體:(From build/core/config.mk)265 MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)266 MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)267 MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
2.INSTALLED_RAMDISK_TARGET,標准根文件系統 ramdisk.img:
326 BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img328 # We just build this directly to the install location.329 INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET) 3.INSTALLED_BOOTIMAGE_TARGET, 即boot.img,標准內核及標准根文件系統:362 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
4. recovery_binary, Recovery可執行程序,源碼位於:bootable/recovery
590 recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery)/recovery
5. recovery_initrc,recovery模式的init.rc, 位於 bootable/recovery/etc/init.rc
586 recovery_initrc := $(call include-path-for, recovery)/etc/init.rc
6. recovery_kernel, recovery 模式的kernel, 同標准內核
587 recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system
7.INSTALLED_2NDBOOTLOADER_TARGET,我們不用。
8. recovery_build_prop, recovery 模式的build.prop, 同標准模式。589 recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET)
9. recovery_resource_deps, recovery 模式使用的res, 位於:recovery/custom/{proct_name}/res, 以及設備自定義部分(我們沒用到)
591 recovery_resources_common := $(call include-path-for, recovery)/custom/$(TARGET_PRODUCT)/res592 recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res))593 recovery_resource_deps := $(shell find $(recovery_resources_common) 594 $(recovery_resources_private) -type f) 10. RECOVERY_INSTALL_OTA_KEYS, ota 密鑰:
618 # Generate a file containing the keys that will be read by the619 # recovery binary.620 RECOVERY_INSTALL_OTA_KEYS := /621 $(call intermediates-dir-for,PACKAGING,ota_keys)/keysL638-L655 准備內容
638 @echo ----- Making recovery image ------639 rm -rf $(TARGET_RECOVERY_OUT)640 mkdir -p $(TARGET_RECOVERY_OUT)641 mkdir -p $(TARGET_RECOVERY_ROOT_OUT)642 mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc643 mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp
准備recovery目錄:out/target/proct/{proct_name}/recovery 及其子目錄:
./root
./root/etc
./root/tmp644 echo Copying baseline ramdisk...645 cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)646 echo Modifying ramdisk contents...647 rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res
從標准根文件系統拷貝所有文件, 刪除其res 目錄。
648 cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/649 cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/ 拷貝recovery 模式的核心文件 init.rc 及 recovery 650 cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/651 $(foreach item,$(recovery_resources_private), /652 cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)653 cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys 拷貝資源文件及密鑰文件。 654 cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) /655 > $(TARGET_RECOVERY_ROOT_OUT)/default.prop 生成屬性文件 default.prop, 它包含了標准根文件系統的default.prop (out/target/proct/{proct_name}/root/default.prop)以及system分區的build.prop (out/target/proct/{proct_name}/system/build.prop) L656-L661 最終生成recovery.img
656 $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk) 壓縮recovery根文件系統 657 build/quacomm/mkimage $(PRODUCT_OUT)/ramdisk-recovery.img RECOVERY > $(PRODUCT_OUT)/ramdisk_recovery.img 加一個標識頭(RECOVERY) 658 mv $(PRODUCT_OUT)/ramdisk_recovery.img $(PRODUCT_OUT)/ramdisk-recovery.img659 $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@660 @echo ----- Made recovery image -------- $@661 $(hide) $(call assert-max-image-size,$@,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE),raw)
和內核一起,生成recovery.img附:Recovery 根文件系統目錄結構
$ tree
.
├── advanced_meta_init.rc
├── data
├── default.prop
├── dev
├── etc
├── init
├── init.factory.rc
├── init.goldfish.rc
├── init.quacomm.rc
├── init.rc
├── meta_init.rc
├── proc
├── res
│ ├── images
│ │ ├── icon_error.png
│ │ ├── icon_installing.png
│ │ ├── indeterminate1.png
│ │ ├── indeterminate2.png
│ │ ├── indeterminate3.png
│ │ ├── indeterminate4.png
│ │ ├── indeterminate5.png
│ │ ├── indeterminate6.png
│ │ ├── progress_empty.png
│ │ └── progress_fill.png
│ └── keys
├── sbin
│ ├── adbd
│ ├── advanced_meta_init
│ ├── meta_init
│ ├── meta_tst
│ └── recovery
├── sys
├── system
└── tmp
③ 如何單獨編譯Android源代碼中的模塊
Android源碼目錄下的build/envsetup.sh文件,描述編譯的命令
- m: Makes from the top of the tree.
- mm: Builds all of the moles in the current directory.
- mmm: Builds all of the moles in the supplied directories.
要想使用這些命令,首先需要在android源碼根目錄執行. build/envsetup.sh 腳本設置環境
m:編譯所有的模塊
mm:編譯當前目錄下的模塊,當前目錄下要有Android.mk文件
mmm:編譯指定路徑下的模塊,指定路徑下要有Android.mk文件
下面舉個例子說明,假設我要編譯android下的\hardware\libhardware_legacy\power模塊,當前目錄為源碼根目錄,方法如下:
1、. build/envsetup.sh
2、mmm hardware/libhardware_legacy/power/
編譯完後 運行 make snod
會重新將你改過的模塊打入到system.img中
④ android studio怎麼編譯 運行程序
Eclipse中編譯好的apk文件時在bin文件裡面的,但是在Android Studio有一個比較大的改動了,編譯好的apk在android studio裡面是直接看不到了,而且apk文件所在目錄也變了,那apk文件放在哪呢,你要在硬碟中找到對應的工程目錄:
E:\StudioDemo\MyApplication\app\build\outputs\apk
其中app是你的mole,記得一定要在對應的mole下找對應的編譯好的apk文件
⑤ Android系統如何運行動態編譯的程序
把常用的應用程序編譯到img文件中,就成了系統的一部分,用戶不必自己安裝,當然也卸載不了;
同時也可以刪減系統自帶的應用程序,精簡系統;
1.\build\target\proct 目錄下generic.mk文件:
java代碼 收藏代碼
PRODUCT_PACKAGES := \
AccountAndSyncSettings \
DeskClock \
AlarmProvider \
Bluetooth \
Calculator \
Calendar \
Camera \
testMid \
CertInstaller \
DrmProvider \
Email \
Gallery3D \
LatinIME \
Launcher2 \
Mms \
Music \
我們添加一個testMid \ 應用名稱。
2.把testMid包放入
\packages\apps 目錄下,修改android.mk文件。
Java代碼 收藏代碼
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := testMid
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
註:LOCAL_PACKAGE_NAME := testMid (包名必須和generic.mk中添加的相同)
編譯源碼,可以看到在
\out\target\proct\smdkv210\system\app
目錄下生存了testMid.apk了。這時system.img也包含了此應用。
-------------------------------------------------------------------
特殊情況:有時,應用需要包含jar包,這時的app導入源碼時會出現問題:
MODULE.TARGET.JAVA_LIBRARIES.libarity already defined by ... stop
由於 LOCAL_STATIC_JAVA_LIBRARIES := libarity 會引發錯誤信息。
目前解決方法是:
\build\core 目錄下修改base_rules.mk
注釋掉錯誤信息:
ifdef $(mole_id)
#$(error $(LOCAL_PATH): $(mole_id) already defined by $($(mole_id)))
endif
$(mole_id) := $(LOCAL_PATH)
--重新編譯,這時可以通過了。
(2)、刪除原廠(Telchips)帶源碼的應用程序,如DTV_DVBT
在/device/telechips/m801/device.mk
注釋掉相應語句:
# PRODUCT_PACKAGES += \
# SampleDVBTPlayer \
同時,在/out/target/proct/m801/system/app 找到相應的.APK包,並刪除
⑥ android studio怎麼執行編譯
安裝Android Studio的准備工作 1.下載好JDK 去官網上找一個下載下來 2.安裝JDK.並配置環境變數.安裝過程可以一直下一步,無腦操作 3.下載Android Studio的安裝包 去官網上找一個,下載下來 (jdk的環境變數一定要配置) 准備工作完成之後,就可以開始我們的安裝了 1.安裝Android studio也是無腦操作,一直點下一步。直到安裝結束 2.安裝好之後,我們要新建我們的項目。重點從這里開始 點擊 New Project會出現.我們設置好名稱,也可以無腦操作,一直點擊next,直至結束,不過這個過程需要我們耐心的等待。(時間有點漫長)。 然後我們就會進入我們的開發界面。點擊圖片中紅圈的圖標(SDK manager)會出現下圖 這個步驟是安裝Android的sdk,推薦,Android1.6~Android4.4.2全部安裝。(這個耗費時間挺長的,請在網速良好且大量閑暇時光下安裝,安裝過程中可以看部電影) 安裝完之後,就開始配置我們的avd(Android Virtual Device),也就是Android的虛擬環境。點擊,圖片中紅圈的圖標 點擊New(Test是我配置好的) 隨便設置AVD name,建議如圖設置 設置完成之後,就可以點擊下圖的三角號編譯我們的程序了。
⑦ 在android中如何編譯連接 c 的可執行文件
1. 在./development目錄下創建一目錄 如:myhello
2. 進入hello目錄,在其下編寫自己的.c文件,如: myhello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
exit(0);
//return 0;
}
3. 在hello目錄中,編寫Android.mk, 內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myhelloworld
LOCAL_SRC_FILES := myhello.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
4. 回到Android源代碼頂層目錄,進行編譯,make myhelloworld
5. 生成的可執行文件位於:out/target/proct/lotus/system/bin/ 目錄下
6. adb push 到手機 /data 目錄下,然後進入adb shell,到data目錄下,執行./myhelloworld 皆可
手動編譯連接【arm-eabi-gcc 的目錄隨andorid的版本而有變化,還有就是需要鏈接的文件如果比較多時,需要很多-l 就很麻煩了】
7、編譯成目標文件:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -I bionic/libc/arch-arm/include/ -I bionic/libc/include -I bionic/libc/kernel/common -I bionic/libc/kernel/arch-arm -g -c helloworld.c -o hello.o
8、生成可執行代碼:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc -o helloworld -Lout/target/proct/[generic]/obj/lib -Wl,-rpath-link=out/target/proct/[generic]/obj/lib -lc hello.o -entry=main
其中[ ]中部分根據實際情況修改
**************************************************
實驗:
1. 建目錄(my Android)/development/test, 在該目錄下新建 Android.mk和fb_test.c文件
2. Android.mk文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myfbtest
LOCAL_SRC_FILES := fb_test.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
3. 以下為fb_test.c
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/kd.h>
#include <stdio.h>
#define FBBIT_PER_PIXEL 32
#define FBBIT_PIXEL_IMAGE 16
#define PIXELS_WIDTH_BYTE 4
#define BYTE_PER_PIXEL 3
#define FB_GRAPHICS_PATH "/dev/graphics/fb0"
#define DEV_TTY0_PATH "/dev/tty0"
#define DISPLAY_ERROR -1
#define DISPLAY_SUCCESS 0
#define GET_BATTERYCAPACITY_ERR -1
#define MAX_STR 255
static struct {
int fd;
void *pixels;
struct fb_fix_screeninfo fixed;
struct fb_var_screeninfo var;
int align_xres;
} fb;
int getBatteryCapacity(void)
{
FILE *in;
char tmpStr[MAX_STR + 1];
char capfile[] = "/sys/class/power_supply/battery/capacity";
if (capfile == NULL)
return GET_BATTERYCAPACITY_ERR;
in = fopen(capfile, "rt");
if (in == NULL)
return GET_BATTERYCAPACITY_ERR;
if (fgets(tmpStr, MAX_STR, in) == NULL) {
printf("Failed to read battery capacity!\n");
fclose(in);
return GET_BATTERYCAPACITY_ERR;
}
printf("Battery capacity(ascii): %s\n", tmpStr);
fclose(in);
return 0;//atoi(tmpStr);
}
static int vt_set_graphicsmode(int graphics)
{
int fd, r;
fd = open(DEV_TTY0_PATH, O_RDWR | O_SYNC);
if (fd < 0)
return DISPLAY_ERROR;
r = ioctl(fd, KDSETMODE, graphics);
close(fd);
return r;
}
int display_init(void)
{
fb.fd = open(FB_GRAPHICS_PATH, O_RDWR);
if (fb.fd < 0)
return DISPLAY_ERROR;
if (ioctl(fb.fd, FBIOGET_FSCREENINFO, &fb.fixed) < 0)
return DISPLAY_ERROR;
if (ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.var) < 0)
return DISPLAY_ERROR;
fb.align_xres = fb.fixed.line_length /
(fb.var.bits_per_pixel >> BYTE_PER_PIXEL);
fb.pixels = mmap(0, fb.fixed.line_length * fb.var.yres_virtual,
PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0);
if (fb.pixels == MAP_FAILED)
return DISPLAY_ERROR;
vt_set_graphicsmode(KD_GRAPHICS);
memset(fb.pixels, 0, fb.fixed.line_length * fb.var.yres_virtual);
//display_update(fb.pixels, fb.align_xres, fb.var.yres);
fb.var.activate = FB_ACTIVATE_FORCE;
ioctl(fb.fd, FBIOPUT_VSCREENINFO, &fb.var);
printf("display_init ok\n");
return DISPLAY_SUCCESS;
}
void display_on(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_UNBLANK);
}
void display_off(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_POWERDOWN);
}
int main()
{
display_init();
display_off();//關顯示屏
getBatteryCapacity();
sleep(5);
display_on();//開顯示屏
return 0;
}
⑧ 如何編譯android kernel
1.准備工作: (ubuntu1110 32位)
ubuntu等linuxOS,下載好eclipse,安裝好JDK, 安裝好android的SDK, 在eclipse中成功打開android 手機模擬器即OK。
2.初始化編譯環境 :
關注該網頁上的「installing required packages」,其中有的軟體包因為版本問題而安裝不上,不用管它,之後遇到錯誤再單獨解決。
3.下載內核源碼:
android 2.3 內核 下載需要等待一段時間。
4.下載交叉編譯器:
該步驟有可能耗費大量時間,依據網速不同,幾個小時到幾天不等,或許可以嘗試git clone 後面的地址只下載prebuilt/linux-x86/toolchain
5.設置參數以及編譯:
$ export ARCH=arm
$ export SUBARCH=arm
$ export CROSS_COMPILE=arm-eabi-
$ cd goldfish // 進入下載的源代碼目錄
$ git checkout <commit_from_first_step> //這個步驟我沒有做,不知道幹嘛用的
$ make goldfish_defconfig
$ make
6.報錯信息:
若有報錯說找不到 (arm-eabi-gcc command not found)等等,嘗試使用http://blog.csdn.net/davidbeckham2901/article/details/7397447 中說到的解決方案即可(即採用另外一個交叉編譯器)。
7.測試:
最後,測試一下剛才編譯的內核:emulator -avd myavd -kernel ~/goldfish/arch/arm/boot/zImageemulator若系統找不到,可以去android SDK中某文件夾找到,加入系統PATH即可。 -avd後面的參數 myavd即為模擬器的名字,這個我是在eclipse中的模擬器管理中新建的一個模擬器,用那個模擬器的名字即可。 -kernel後面的參數就找到剛才編譯出的內核的路徑。
若啟動模擬器失敗,可嘗試關閉後再啟動。第一次啟動模擬器時可能需要等待比較長的時間,3分鍾到15分鍾不等。
⑨ android studio 怎麼編譯一個工程
安裝Android Studio的准備工作 1.下載好JDK 去官網上找一個下載下來 2.安裝JDK.並配置環境變數.安裝過程可以一直下一步,無腦操作 3.下載Android Studio的安裝包 去官網上找一個,下載下來 (jdk的環境變數一定要配置) 准備工作完成之後,就可以開始我們的安裝了 1.安裝Android studio也是無腦操作,一直點下一步。直到安裝結束 2.安裝好之後,我們要新建我們的項目。重點從這里開始 點擊 New Project會出現.我們設置好名稱,也可以無腦操作,一直點擊next,直至結束,不過這個過程需要我們耐心的等待。(時間有點漫長)。 然後我們就會進入我們的開發界面。點擊圖片中紅圈的圖標(SDK manager)會出現下圖 這個步驟是安裝Android的sdk,推薦,Android1.6~Android4.4.2全部安裝。(這個耗費時間挺長的,請在網速良好且大量閑暇時光下安裝,安裝過程中可以看部電影) 安裝完之後,就開始配置我們的avd(Android Virtual Device),也就是Android的虛擬環境。點擊,圖片中紅圈的圖標 點擊New(Test是我配置好的) 隨便設置AVD name,建議如圖設置 設置完成之後,就可以點擊下圖的三角號編譯我們的程序了。。。。
⑩ android 修改代碼怎樣編譯
1: ./mk n(r) kernel; ./mk bootimage;當修改kernel相關代碼時,具體如下:
alps/kernel/
alps/mediatek/platform/mt65xx/kernel/
alps/mediatek/source/kernel/
alps/mediatek/customer/mt65xx/kernel/
alps/mediatek/customer/common/kernel/
alps/mediatek/customer/$porject_name$/kernel
......
2: ./mk n pl 當修改preloader相關代碼時, 具體如下:
alps/mediatek/platform/mt65xx/preloader/
alps/mediatek/source/preloader/
alps/mediatek/customer/mt65xx/preloader/
alps/mediatek/customer/common/preloader/
alps/mediatek/customer/$porject_name$/kernle
......
3: ./mk uboot 當修改uboot相關代碼時,具體如下:
alps/mediatek/platform/mt65xx/uboot/
alps/mediatek/source/uboot/
alps/bootable/bootloader/uboot/
alps/mediatek/customer/mt65xx/uboot/
alps/mediatek/customer/common/buoot/
alps/mediatek/customer/$porject_name$/uboot/
......
4: ./mk systemimage 當修改system相關代碼時,具體如下:
alps/frameworks/
alps/packages/
alps/vendor/
alps/hardware/
alps/dalvik/
...........
5: ./mk recoverimage 當修改recover相關代碼時,具體如下:
alps/bootable/recovery/
alps/mediatek/customer/$project_name$/recovery/
......
6: ./mk factoryimage: 當修改factory相關代碼時使用此命令,具體如下:
alps/mediatek/customer/$project_name$/factory/
alps/mediatek/customer/common/factory/
alps/mediatek/source/factory/
......
7: ./mk secroimage 當修改secro相關代碼時,具體如下:
alps/mediatek/source/secro/
alps/mediatek/customer/$project_name$/secro/
.....