国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python—android編譯中build_image.py分析

2019-11-08 00:17:52
字體:
來源:轉載
供稿:網友

最近在學習python,基礎知識學習了一遍。我的學習習慣是:了解了基礎語法后,去閱讀開源代碼(掌握優秀程序員的一些寫代碼習慣和手法),最后結合項目實踐,實踐的過程對某些細節進行深化。 想起android編譯系統中有一些python腳本,下面對build_image.py進行簡單分析。

編譯系統中調用build_image.py

生成系統鏡像的target在build/core/Makefile中,

#----------build/core/Makefile-------------# $(1): output filedefine build-systemimage-target @echo "Target system fs image: $(1)" @mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt $(call generate-userimage-PRop-dictionary, $(systemimage_intermediates)/system_image_info.txt, skip_fsck=true) $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH / ./build/tools/releasetools/build_image.py / $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1)endef

其中,可以看出來主要是借助了build_image.py去生成鏡像,/build/tools/releasetools/build_image.py $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) , 有三個參數,一個是作為輸入的文件目錄,system_image_info.txt,和最終生成的鏡像名,例如system.img。

build_image.py分析

由于上面makefile中是在shell中直接調用build_image.py(不是import 模塊),所以__name____main__,會直接調用main函數,

#參數格式必須為3個# $(TARGET_OUT) system_image_info.txt output_filedef main(argv): if len(argv) != 3: print __doc__ sys.exit(1) in_dir = argv[0] glob_dict_file = argv[1] out_file = argv[2] #將system_image_info.txt中的內容保存到字典中,例如{'fs_type':'ext4',.....} glob_dict = LoadGlobalDict(glob_dict_file) #basename獲取文件名(不包括路徑),這里為system.img image_filename = os.path.basename(out_file) mount_point = "" if image_filename == "system.img": mount_point = "system" elif image_filename == "userdata.img": mount_point = "data" elif image_filename == "cache.img": mount_point = "cache" elif image_filename == "vendor.img": mount_point = "vendor" else: print >> sys.stderr, "error: unknown image file name ", image_filename exit(1) #print >> #the first expression after the >> must evaluate to a “file-like” object, #輸入為system_image_info.txt內容字典和system image_properties = ImagePropFromGlobalDict(glob_dict, mount_point) if not BuildImage(in_dir, image_properties, out_file): print >> sys.stderr, "error: failed to build %s from %s" % (out_file, in_dir) exit(1)#當被直接python build_image.py執行時 __name__為__main__#當被其他import時,__name__是模塊的名字,build_image#argv[0]是腳本名if __name__ == '__main__': main(sys.argv[1:])

其中,system_image_info.txt一個例子如下所示,一些參數及其值,

fs_type=ext4system_size=1288491008userdata_size=5835325440cache_fs_type=ext4cache_size=268435456extfs_sparse_flag=-sselinux_fc=out/target/product/msm8916_64/root/file_contextsverity=trueverity_key=build/target/product/security/verityverity_signer_cmd=out/host/linux-x86/bin/verity_signersystem_verity_block_device=/dev/block/bootdevice/by-name/systemskip_fsck=true

LoadGlobalDict函數如下,將system_image_info.txt中的內容保存到字典中,例如{‘fs_type’:’ext4’,…..}

def LoadGlobalDict(filename): """Load "name=value" pairs from filename""" d = {} f = open(filename) #對文件對象的迭代 #文件中#不處理,是注釋 #strip去除字符串兩頭,不包括內部的空格 #split將字符串分割成序列 str.split(sep=None, maxsplit=-1) #If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). #>>>'1,2,3'.split(',', maxsplit=1) #['1', '2,3'] #所以用=分割,只有=前面和后面2個元素 for line in f: line = line.strip() if not line or line.startswith("#"): continue k, v = line.split("=", 1) d[k] = v f.close() return d

ImagePropFromGlobalDict函數,從全局字典(system_image_info.txt中有些東西不是都有用)取出需要的東西,返回一個新字典。

def ImagePropFromGlobalDict(glob_dict, mount_point): """Build an image property dictionary from the global dictionary. Args: glob_dict: the global dictionary from the build system. mount_point: such as "system", "data" etc. """ d = {} def copy_prop(src_p, dest_p): if src_p in glob_dict: d[dest_p] = str(glob_dict[src_p]) #extfs_sparse_flag=-s #skip_fsck=true #selinux_fc=out/target/product/msm8916_64/root/file_contexts #將common_props屬性中的值保存到新建的字典d中, common_props = ( "extfs_sparse_flag", "mkyaffs2_extra_flags", "selinux_fc", "skip_fsck", ) for p in common_props: copy_prop(p, p) #添加'mount_point':'system' d["mount_point"] = mount_point if mount_point == "system": #'fs_type':'ext4' #'partition_size':'1288491008' copy_prop("fs_type", "fs_type") copy_prop("system_size", "partition_size") elif mount_point == "data": copy_prop("fs_type", "fs_type") copy_prop("userdata_size", "partition_size") elif mount_point == "cache": copy_prop("cache_fs_type", "fs_type") copy_prop("cache_size", "partition_size") elif mount_point == "vendor": copy_prop("vendor_fs_type", "fs_type") copy_prop("vendor_size", "partition_size") return d

最后調用BuildImage函數,其實就是組了一個命令,然后執行該命令(mkuserimg.sh -s in_dir out_file ext4 system 1288491008 out/target/product/msm8916_64/root/file_contexts)。

def BuildImage(in_dir, prop_dict, out_file): """Build an image to out_file from in_dir with property prop_dict. Args: in_dir: path of input directory. prop_dict: property dictionary. out_file: path of the output image file. Returns: True iff the image is built successfully. """ build_command = [] #字典的get方法,如果鍵不存在,沒有任何異常,而得到None fs_type = prop_dict.get("fs_type", "") run_fsck = False #文件系統以ext開頭 #這里是ext4,走這里,其實就是組一個要執行的命令 mkuserimg.sh -s in_dir out_file ext4 system 1288491008 out/target/product/msm8916_64/root/file_contexts if fs_type.startswith("ext"): build_command = ["mkuserimg.sh"] if "extfs_sparse_flag" in prop_dict: build_command.append(prop_dict["extfs_sparse_flag"]) run_fsck = True build_command.extend([in_dir, out_file, fs_type, prop_dict["mount_point"]]) if "partition_size" in prop_dict: build_command.append(prop_dict["partition_size"]) if "selinux_fc" in prop_dict: build_command.append(prop_dict["selinux_fc"]) else: build_command = ["mkyaffs2image", "-f"] #split用于將字符串分割成list,沒有參數表示用空格分割 if prop_dict.get("mkyaffs2_extra_flags", None): build_command.extend(prop_dict["mkyaffs2_extra_flags"].split()) build_command.append(in_dir) build_command.append(out_file) if "selinux_fc" in prop_dict: build_command.append(prop_dict["selinux_fc"]) build_command.append(prop_dict["mount_point"]) #執行該命令mkuserimg.sh -s in_dir out_file ext4 system exit_code = RunCommand(build_command) if exit_code != 0: return False# >>> os.path.dirname('c://Python//a.txt') 返回目錄# 'c://Python'# >>> os.path.basename('c://Python//a.txt') 返回文件名# 'a.txt'# os.path.join連接目錄與文件名或目錄 #skip_fsck=true,不走這里 if run_fsck and prop_dict.get("skip_fsck") != "true": # Inflate the sparse image unsparse_image = os.path.join( os.path.dirname(out_file), "unsparse_" + os.path.basename(out_file)) inflate_command = ["simg2img", out_file, unsparse_image] exit_code = RunCommand(inflate_command) #This function is semantically identical to unlink(). #remove和unlink一樣 if exit_code != 0: os.remove(unsparse_image) return False # Run e2fsck on the inflated image file e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image] exit_code = RunCommand(e2fsck_command) os.remove(unsparse_image) return exit_code == 0

其中,RunCommand其實就類似于c語言中的system(),執行一段命令,獲取返回值,用popen實現的。

def RunCommand(cmd): """ Echo and run the given command Args: cmd: the command represented as a list of strings. Returns: The exit code. """ print "Running: ", " ".join(cmd) #創建子進程 p = subprocess.Popen(cmd) #等待子進程執行完 p.communicate() return p.returncode

最終其實是調用了mkuserimg.sh腳本,腳本核心是調用make_ext4fs 應用程序

#system/extras/ext4_utils/mkuserimg.shfunction usage() {cat<<EOTUsage:mkuserimg.sh [-s] SRC_DIR OUTPUT_FILE EXT_VARIANT MOUNT_POINT SIZE [FILE_CONTEXTS]EOT}echo "in mkuserimg.sh PATH=$PATH"ENABLE_SPARSE_IMAGE=if [ "$1" = "-s" ]; then ENABLE_SPARSE_IMAGE="-s" shiftfiif [ $# -ne 5 -a $# -ne 6 ]; then usage exit 1fiSRC_DIR=$1if [ ! -d $SRC_DIR ]; then echo "Can not find directory $SRC_DIR!" exit 2fiOUTPUT_FILE=$2EXT_VARIANT=$3MOUNT_POINT=$4SIZE=$5FC=$6case $EXT_VARIANT in ext4) ;; *) echo "Only ext4 is supported!"; exit 3 ;;esacif [ -z $MOUNT_POINT ]; then echo "Mount point is required" exit 2fiif [ -z $SIZE ]; then echo "Need size of filesystem" exit 2fiif [ -n "$FC" ]; then FCOPT="-S $FC"fi#核心是make_ext4fs 應用程序MAKE_EXT4FS_CMD="make_ext4fs $ENABLE_SPARSE_IMAGE $FCOPT -l $SIZE -a $MOUNT_POINT $OUTPUT_FILE $SRC_DIR"echo $MAKE_EXT4FS_CMD$MAKE_EXT4FS_CMDif [ $? -ne 0 ]; then exit 4fi

而make_ext4fs 應用程序具體在system/extras/ext4_utils中生成,makefile如下,其中makefile中有兩個make_ext4fs的module,一個是host(BUILD_HOST_EXECUTABLE),一個是target的(BUILD_EXECUTABLE),這個命令是在編譯機調用,也就是host上而不是target上。

include $(CLEAR_VARS)LOCAL_SRC_FILES := make_ext4fs_main.cLOCAL_MODULE := make_ext4fsLOCAL_STATIC_LIBRARIES += / libext4_utils_host / libsparse_host / libzifeq ($(HOST_OS),windows) LOCAL_LDLIBS += -lws2_32else LOCAL_STATIC_LIBRARIES += libselinux LOCAL_CFLAGS := -DHOSTendifinclude $(BUILD_HOST_EXECUTABLE)
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金阳县| 榆树市| 巴楚县| 花莲市| SHOW| 宿迁市| 随州市| 故城县| 浪卡子县| 磐石市| 丹棱县| 河北省| 阿克陶县| 永新县| 高清| 绥阳县| 彭阳县| 静海县| 武定县| 云梦县| 许昌县| 五大连池市| 图木舒克市| 阿克陶县| 墨竹工卡县| 双峰县| 高陵县| 江安县| 子长县| 寿阳县| 南京市| 靖安县| 额敏县| 霸州市| 洞口县| 茂名市| 安达市| 吴忠市| 罗山县| 河北省| 怀远县|