android lichee编译脚本解析
来源:互联网 发布:淘宝店铺白色导航制作 编辑:程序博客网 时间:2024/05/21 09:58
#编译流程#lichee 目录下./build.sh -p sun7i_android -k 3.4
#build.sh 解析#!/bin/bashset -e #"Exit immediately if a simple command exits with a non-zero status." #也就是说,在"set -e"之后出现的代码,一旦出现了返回值非零,整个脚本就会立即退出buildroot/scripts/mkcommon.sh $@ #$@ 为参数 -p sun7i_android -k 3.4
#mkcommon.sh#!/bin/bash## scripts/mkcommon.sh# (c) Copyright 2013# Allwinner Technology Co., Ltd. <www.allwinnertech.com># James Deng <csjamesdeng@allwinnertech.com>## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.BR_SCRIPTS_DIR=`dirname $0` #提取出运行目录 ./buildroot/scripts/if [ "$1" = "pack" ] ; then #如果是运行打包动作 ${BR_SCRIPTS_DIR}/build_pack.sh #运行打包脚本 exit 0fi# source shflags. ${BR_SCRIPTS_DIR}/shflags/shflags #加载命令行工具. ${BR_SCRIPTS_DIR}/mkcmd.sh #加载shell编译脚本# define option, format:# 'long option' 'default value' 'help message' 'short option'#命令行工具shflags使用#三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息DEFINE_string 'platform' 'sun7i' 'platform to build, e.g. sun7i' 'p'DEFINE_string 'kernel' '3.4' 'kernel to build, e.g. 3.3' 'k'DEFINE_string 'board' '' 'board to build, e.g. evb' 'b'DEFINE_string 'module' '' 'module to build, e.g. buildroot, kernel, uboot, clean' 'm'DEFINE_boolean 'independent' false 'output build to independent directory' 'i'# parse the command-line# 解析传进来的参数FLAGS "$@" || exit $?#语法:eval cmdLine#eval会对后面的cmdLine进行两遍扫描,如果第一遍扫描后,cmdLine是个普通命令,则执行此命令;#如果cmdLine中含有变量的间接引用,则保证间接引用的语义。eval set -- "${FLAGS_ARGV}" #参数是: -p sun7i_android -k 3.4chip=${FLAGS_platform%%_*} #提取出chip sun7iplatform=${FLAGS_platform##*_} #提取出平台 androidkernel=${FLAGS_kernel} #提取出内核 3.4 board=${FLAGS_board} #提取出板子 这里空module=${FLAGS_module} #提取出模块 这里空if [ "${platform}" = "${chip}" ] ; then #如果未指定平台,默认为linux platform="linux"fiif [ -z "${module}" ] ; then #如果未指定模块,默认编译所有 module="all"fiif ! init_chips ${chip} || \ #初始化芯片参数: sun7i #查询该目录下{LICHEE_TOOLS_DIR}/pack/chips/是否有 以该芯片命名的目录 #并导出该变量 export LICHEE_CHIP=${chip} ! init_platforms ${chip} ${platform} ; then #检查是否支持该平台 #并导出 export LICHEE_PLATFORM=${platform} mk_error "invalid platform '${FLAGS_platform}'" exit 1fiif [ ${FLAGS_board} ] && \ #如果指定了板子,检查是否支持该板子 ! init_boards ${chip} ${platform} ${board} ; then mk_error "invalid board '${FLAGS_board}'" exit 1fiif [ "${kernel}" = "3.3" ] ; then #如果指定了内核3.3 ,判断该目录是否存在 # 3.4 就不检查了? LICHEE_KERN_DIR=${LICHEE_TOP_DIR}/linux-3.3 if [ ! -d ${LICHEE_KERN_DIR} ] ; then mk_error "invalid kernel '${kernel}'" exit 1 fifi# init output directoryinit_outdir #初始化输出目录,检查配置是否存在 #这里默认配置:sun7ismp_android_defconfig,配置组成在check_kern_defconf 函数中 #请自己查看 #设置了导出目录: # export LICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_PLATFORM}/common" #导出plat 目录 .../lichee/out/android/common #export LICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot" #导出 br 目录 ../lichee/out/android/common/buildrootif [ ${module} = "all" ]; then mklicheeelif [ ${module} = "boot" ] ; then mkbootelif [ ${module} = "buildroot" ] ; then mkbrelif [ ${module} = "kernel" ] ; then mkkernelelif [ ${module} = "uboot" ] ; then mkubootelif [ ${module} = "clean" ] ; then mkcleanelif [ ${module} = "mrproer" ] ; then mkmrproerelif [ ${module} = "distclean" ] ; then mkdistcleanelse mk_error "invalid module '${module}'" exit 1fiexit $?
#编译allfunction mklichee(){ mksetting #打印编译信息 mk_info "build lichee ..." #显示编译,带颜色显示 #编译交叉编译工具 ----这里就不分析了 #编译内核 #编译uboot #编译文件系统 mkbr && mkkernel && mkuboot && mkrootfs [ $? -ne 0 ] && return 1 mk_info "build lichee OK."}
编译内核所做的事情:
#,根据平台配置,编译内核 ,把编译好的内核,模块 以及.config 拷到了output 目录下
#把output 目录下的所有内容,LICHEE_PLAT_OUT
#也就是 …/lichee/out/android/common
编译uboot 所做的事情
# 根据平台选择编译脚本 —–其实这一步没起作用,最终用的build.sh
# 先make distclean ,再根据芯片 sun7i进行编译,生成u-boot.bin
#所有这里可以选择把distclean 去掉,节约编译时间
# 把u-boot.bin拷贝到了 lichee/out/android/common 目录下
编译rootfs所做的事情:
#根据linux 或者dragonboard 做相应的操作
# 而这 do nothing ,skip
//———————————-other ————————————
function mkrootfs(){ mk_info "build rootfs ..." if [ ${LICHEE_PLATFORM} = "linux" ] ; then make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} target-generic-getty-busybox [ $? -ne 0 ] && mk_error "build rootfs Failed" && return 1 make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} target-finalize [ $? -ne 0 ] && mk_error "build rootfs Failed" && return 1 make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} LICHEE_GEN_ROOTFS=y rootfs-ext4 [ $? -ne 0 ] && mk_error "build rootfs Failed" && return 1 cp ${LICHEE_BR_OUT}/images/rootfs.ext4 ${LICHEE_PLAT_OUT} elif [ ${LICHEE_PLATFORM} = "dragonboard" ] ; then echo "Regenerating dragonboard Rootfs..." (cd ${LICHEE_BR_DIR}/target/dragonboard; \ if [ ! -d "./rootfs" ]; then \ echo "extract dragonboard rootfs.tar.gz"; \ tar zxf rootfs.tar.gz; \ fi \ ) mkdir -p ${LICHEE_BR_DIR}/target/dragonboard/rootfs/lib/modules rm -rf ${LICHEE_BR_DIR}/target/dragonboard/rootfs/lib/modules/* cp -rf ${LICHEE_KERN_DIR}/output/lib/modules/* ${LICHEE_BR_DIR}/target/dragonboard/rootfs/lib/modules/ (cd ${LICHEE_BR_DIR}/target/dragonboard; ./build.sh) cp ${LICHEE_BR_DIR}/target/dragonboard/rootfs.ext4 ${LICHEE_PLAT_OUT} else mk_info "skip make rootfs for ${LICHEE_PLATFORM}" fi mk_info "build rootfs OK."}
# return true if used default configfunction check_uboot_defconf(){ local defconf local ret=1 defconf="${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}" #编译 sun7i_android #这里少了一个.sh,脚本有问题:sun7i_android.sh if [ ! -f ${LICHEE_UBOOT_DIR}/include/configs/${defconf} ] ; then ret=0 defconf="${LICHEE_CHIP}" #这里少了一个.sh 应该为:sun7i.sh fi export LICHEE_UBOOT_DEFCONF=${defconf} return ${ret}}function mkuboot(){ mk_info "build u-boot ..." local build_script if check_uboot_defconf ; then #查看配置是是否存在,指定编译脚本 build_script="build.sh" #运行此编译脚本 else build_script="build_${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}.sh" fi prepare_toolchain //运行编译脚本 (cd ${LICHEE_UBOOT_DIR} && [ -x ${build_script} ] && ./${build_script}) [ $? -ne 0 ] && mk_error "build u-boot Failed" && return 1 mk_info "build u-boot OK."}#关键的编译函数:function build_uboot(){ case "$1" in clean) make distclean CROSS_COMPILE=arm-linux-gnueabi- ;; *) make distclean CROSS_COMPILE=arm-linux-gnueabi- #清楚所有配置 make -j${jobs} ${LICHEE_CHIP} CROSS_COMPILE=arm-linux-gnueabi- #根据芯片 编译 这里是sun7i [ $? -ne 0 ] && exit 1 #拷贝u-boot.bin 到输出目录 cp -f u-boot.bin ../out/${LICHEE_PLATFORM}/common/ ;; esac}
function mksetting() #打印要编译的信息{ printf "\n" printf "mkscript current setting:\n" printf " Chip: ${LICHEE_CHIP}\n" printf " Platform: ${LICHEE_PLATFORM}\n" printf " Board: ${LICHEE_BOARD}\n" printf " Output Dir: ${LICHEE_PLAT_OUT}\n" printf "\n"}
编译内核函数
function mkkernel(){ mk_info "build kernel ..." local build_script if check_kern_defconf ; then #检查设置,编译配置文件 if [ ${LICHEE_PLATFORM} = "linux" ] ; then build_script="scripts/build_${LICHEE_CHIP}.sh" else build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}.sh" #指定编译脚本 scripts/build_sun7i_android.sh fi else build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}.sh" fi prepare_toolchain #准备交叉编译工具,就是导出环境变量 #lichee/out/android/common/buildroot/external-toolchain # mark kernel .config belong to which platform local config_mark="${LICHEE_KERN_DIR}/.config.mark" #标记编译平台 android if [ -f ${config_mark} ] ; then if ! grep -q "${LICHEE_PLATFORM}" ${config_mark} ; then mk_info "clean last time build for different platform" (cd ${LICHEE_KERN_DIR} && [ -x ${build_script} ] && ./${build_script} "clean") echo "${LICHEE_PLATFORM}" > ${config_mark} fi else echo "${LICHEE_PLATFORM}" > ${config_mark} fi #进入内核目录 ,检查编译脚本是否可执行,执行该脚本 #./scripts/build_sun7i_android.sh (cd ${LICHEE_KERN_DIR} && [ -x ${build_script} ] && ./${build_script}) [ $? -ne 0 ] && mk_error "build kernel Failed" && return 1 mk_info "build kernel OK."}
脚本#build_sun7i_android.sh 如下
#!/bin/bash## scripts/build_sun7i_android.h## (c) Copyright 2013# Allwinner Technology Co., Ltd. <www.allwinnertech.com># James Deng <csjamesdeng@allwinnertech.com>## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.set -ecpu_cores=`cat /proc/cpuinfo | grep "processor" | wc -l`if [ ${cpu_cores} -le 8 ] ; then jobs=${cpu_cores}else jobs=`expr ${cpu_cores} / 2`fi# Setup common variablesexport ARCH=armexport CROSS_COMPILE=arm-linux-gnueabi-export AS=${CROSS_COMPILE}asexport LD=${CROSS_COMPILE}ldexport CC=${CROSS_COMPILE}gccexport AR=${CROSS_COMPILE}arexport NM=${CROSS_COMPILE}nmexport STRIP=${CROSS_COMPILE}stripexport OBJCOPY=${CROSS_COMPILE}objcopyexport OBJDUMP=${CROSS_COMPILE}objdumpKERNEL_VERSION="3.4"LICHEE_KDIR=`pwd`LICHEE_MOD_DIR=${LICHEE_KDIR}/output/lib/modules/${KERNEL_VERSION}export LICHEE_KDIRbuild_standby(){ echo "build standby" # If .config is newer than include/config/auto.conf, someone tinkered # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files if [ .config -nt include/config/auto.conf -o \ ! -f include/config/auto.conf.cmd ] ; then echo "Generating autoconf.h for standby" make -f Makefile ARCH=arm CROSS_COMPILE=${CROSS_COMPILE} \ silentoldconfig fi make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} KDIR=${LICHEE_KDIR} \ -C ${LICHEE_KDIR}/arch/arm/mach-sun7i/pm/standby all}NAND_ROOT=${LICHEE_KDIR}/modules/nandbuild_nand_lib(){ echo "build nand library ${NAND_ROOT}/lib" if [ -d ${NAND_ROOT}/lib ]; then echo "build nand library now" make -C modules/nand/lib clean 2> /dev/null make -C modules/nand/lib lib install else echo "build nand with existing library" fi}HDMI_ROOT=${LICHEE_KDIR}/drivers/video/sun7i/hdmi/awbuild_hdmi_lib(){ echo "build hdcp library ${HDMI_ROOT}/hdcp" if [ -d ${HDMI_ROOT}/hdcp ]; then echo "build hdcp library now"# make -C ${HDMI_ROOT}/hdcp clean 2>/dev/null make -C ${HDMI_ROOT}/hdcp install else echo "build hdcp with existing library" fi}build_kernel(){ echo "Building kernel" if [ ! -f .config ] ; then #如果配置文件不存在,则拷贝编译脚本 printf "\n\033[0;31;1mUsing default config ...\033[0m\n\n" cp arch/arm/configs/${LICHEE_KERN_DEFCONF} .config fi build_standby #编译内核 make ARCH=arm CROSS_COMPILE=${CROSS_COMPILE} -j${jobs} uImage modules #二进制拷贝 ${OBJCOPY} -R .note.gnu.build-id -S -O binary vmlinux bImage #删除原来的输出目录 rm -rf output #创建模块输出目录 mkdir -p ${LICHEE_MOD_DIR} #拷贝内核文件 cp bImage output/ #把配置文件也拷贝到了输出目录 cp .config output/ #把所有 模块拷贝到了 output/lib/modules/3.4/ for file in $(find drivers sound crypto block fs security net -name "*.ko"); do cp $file ${LICHEE_MOD_DIR} done cp -f Module.symvers ${LICHEE_MOD_DIR} #cp drivers/net/wireless/bcm4330/firmware/bcm4330.bin ${LICHEE_MOD_DIR} #cp drivers/net/wireless/bcm4330/firmware/bcm4330.hcd ${LICHEE_MOD_DIR} #cp drivers/net/wireless/bcm4330/firmware/nvram.txt ${LICHEE_MOD_DIR}/bcm4330_nvram.txt}build_modules(){ echo "Building modules" if [ ! -f include/generated/utsrelease.h ]; then printf "Please build kernel first\n" exit 1 fi make -C modules/example LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \ install build_nand_lib make -C modules/nand LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \ install build_hdmi_lib make -C drivers/video/sun7i/hdmi/aw LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \ install ( export LANG=en_US.UTF-8 unset LANGUAGE make -C modules/mali LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \ install ) ##build ar6302 sdio wifi module #make -C modules/wifi/ar6302/AR6K_SDK_ISC.build_3.1_RC.329/host CROSS_COMPILE=${CROSS_COMPILE} \ # ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \ # all install ##build ar6003 sdio wifi module #make -C modules/wifi/ar6003/AR6kSDK.build_3.1_RC.514/host CROSS_COMPILE=${CROSS_COMPILE} \ # ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \ # all ##build usi-bmc4329 sdio wifi module #make -C modules/wifi/usi-bcm4329/v4.218.248.15/open-src/src/dhd/linux \ # CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \ # LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \ # INSTALL_DIR=${LICHEE_MOD_DIR} dhd-cdc-sdmmc-gpl ##build bcm40181 sdio wifi module 5.90.125.69.2 #make -C modules/wifi/bcm40181/5.90.125.69.2/open-src/src/dhd/linux \ # CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \ # LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \ # INSTALL_DIR=${LICHEE_MOD_DIR} OEM_ANDROID=1 dhd-cdc-sdmmc-gpl ##build bcm40183 sdio wifi module #make -C modules/wifi/bcm40183/5.90.125.95.3/open-src/src/dhd/linux \ # CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \ # LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \ # INSTALL_DIR=${LICHEE_MOD_DIR} OEM_ANDROID=1 dhd-cdc-sdmmc-gpl}gen_output(){ echo "Copy output to target ..." rm -rf ${LICHEE_PLAT_OUT}/lib cp -rf ${LICHEE_KDIR}/output/* ${LICHEE_PLAT_OUT}}clean_kernel(){ echo "Cleaning kernel" make distclean rm -rf output/*}clean_modules(){ echo "Cleaning modules" make -C modules/example LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} clean ( export LANG=en_US.UTF-8 unset LANGUAGE make -C modules/mali LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} clean ) ##build ar6302 sdio wifi module #make -C modules/wifi/ar6302/AR6K_SDK_ISC.build_3.1_RC.329/host CROSS_COMPILE=${CROSS_COMPILE} \ # ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \ # clean ##build ar6003 sdio wifi module #make -C modules/wifi/ar6003/AR6kSDK.build_3.1_RC.514/host CROSS_COMPILE=${CROSS_COMPILE} \ # ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \ # clean ##build usi-bmc4329 sdio wifi module #make -C modules/wifi/usi-bcm4329/v4.218.248.15/open-src/src/dhd/linux \ # CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \ # LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \ # INSTALL_DIR=${LICHEE_MOD_DIR} clean ##build bcm40181 sdio wifi module 5.90.125.69.2 #make -C modules/wifi/bcm40181/5.90.125.69.2/open-src/src/dhd/linux \ # CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \ # LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \ # INSTALL_DIR=${LICHEE_MOD_DIR} clean ##build bcm40183 sdio wifi module #make -C modules/wifi/bcm40183/5.90.125.95.3/open-src/src/dhd/linux \ # CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \ # LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \ # INSTALL_DIR=${LICHEE_MOD_DIR} OEM_ANDROID=1 clean}case "$1" in kernel) build_kernel ;; modules) build_modules ;; clean) clean_modules clean_kernel ;; *) build_kernel #编译内核 ,把编译好的内核,模块 拷到了output 目录下 build_modules #变所有模块 gen_output #把output 目录下的所有内核,LICHEE_PLAT_OUT #也就是 .../lichee/out/android/common ;;esac
function init_chips(){ local chip=$1 #传进来的参数:sun7i local cnt=0 local ret=1 for chipdir in ${LICHEE_TOOLS_DIR}/pack/chips/* ; do chips[$cnt]=`basename $chipdir` if [ ${chips[$cnt]} = ${chip} ] ; then #检测是否有该芯片的目录 ret=0 export LICHEE_CHIP=${chip} fi ((cnt+=1)) done return ${ret}}function init_platforms(){ local chip=$1 #传进来的芯片 sun7i local platform=$2 #传进来的平台 android local cnt=0 local ret=1 for platdir in ${LICHEE_TOOLS_DIR}/pack/chips/${chip}/configs/* ; do platforms[$cnt]=`basename $platdir` if [ ${platforms[$cnt]} = ${platform} ] ; then #检查是否支持该平台打包 ret=0 export LICHEE_PLATFORM=${platform} fi ((cnt+=1)) done return ${ret}}# output to out/<chip>/<platform>/common directory only when# both buildroot and kernel use default config file.function init_outdir(){ if check_br_defconf && check_kern_defconf ; then #check_kern_defconf 检查配置是否存在 export LICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_PLATFORM}/common" #导出plat 目录 .../lichee/out/android/common export LICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot" #导出 br 目录 ../lichee/out/android/common/buildroot else export LICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_PLATFORM}/${LICHEE_BOARD}" export LICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot" fi mkdir -p ${LICHEE_BR_OUT} #创建目录}
2 0
- android lichee编译脚本解析
- android lichee编译脚本解析
- android lichee编译脚本解析
- android lichee编译脚本解析
- android lichee编译脚本解析
- lichee下wifi编译错误
- Android 编译脚本小解析。(include-path-for 解析)
- lichee编译u-boot(Allwinner A80)
- uboot编译脚本解析
- lichee目录+android源码目录制作ROM
- Lichee(一) lichee目录结构介绍和编译命令
- Lichee(二) 在sun4i_crane平台下的编译
- Ubuntu14.04编译Allwinner lichee 两个出错解决方法
- Ubuntu14.04编译Allwinner lichee 两个出错解决方法
- Ubuntu14.04编译Allwinner lichee 两个出错解决方法
- 全志H2 lichee编译出错问题修改
- Android 编译脚本浅析
- ffmpeg android编译脚本
- [UnityShader3]遮罩效果
- linux简单的字符设备驱动程序(写的很清晰)
- 在Windows上使用putty连接一台Linux主机
- SpringSecurity核心组件
- 数据库第一次作业参考答案
- android lichee编译脚本解析
- 基于go+protobuf实现的多种持久化方案的mq框架:kiteq
- 今天遇到一个url转码的bug
- 计算 基金产生收益时间
- Android官方提供的支持不同屏幕大小的全部方法
- Java NIO系列教程(四) Scatter/Gather
- [LeetCode]Sort List
- UART App demo.c
- ArcGIS教程:评估城市环境中的蒸汽管爆炸