NDK build编译的解析

从ndk-build命令开始解析:

1,ndk-build.sh:编译总脚本
    a,获取make工具,找到makefile文件;
    b,执行make -f  makefile(or othername:build-local.mk);
2,build-local.mk:启动的makefile
    a,检查NDK_ROOT的合法性;
    b,初始化环境init.mk;
    c,NDK_PROJECT_PATH:设法找到NDK工程所在的目录;找到NDK_APPLICATION_MK即Application.mk文件,以及输出目录:NDK_APP_OUT := $(NDK_PROJECT_PATH)/obj
    d,Fake an application named 'local',虚拟app,并添加之include $(BUILD_SYSTEM)/add-application.mk;
      Application.mk文件就是在这一步解析的,通过解析获取变量:APP_DEBUG,APP_MODULES,APP_PROJECT_PATH,APP_PLATFORM,APP_ABI,APP_BUILD_SCRIPT,APP_OPTIM
      APP_CFLAGS,APP_STL,NDK_ALL_APPS,此处解析的是:/home/tony/workstation/android-ndk-r6b/build/core/default-application.mk这个文件;
    e,开始编译 :include $(BUILD_SYSTEM)/build-all.mk
3,init.mk:编译环境初始化
    a,检查makefile版本(3.8.1以上);
    b,再次检查NDK_ROOT的合法性;
    c,检查NDKLOG;
    d,设置主机的系统:HOST_OS和主机架构:HOST_ARCH,进而的到一个主机标签:HOST_TAG;如:HOST_OS = linux-HOST_ARCH =x86 --> HOST_TAG = linux-x86;
    e,检查使用的awk工具和AWK脚本路径;
    f,设置所有的编译脚本路径:BUILD_SYSTEM := $(NDK_ROOT)/build/core,以及公共定义$(BUILD_SYSTEM)/definitions.mk
    g,添加交叉编译工具:$(BUILD_SYSTEM)/add-toolchain.mk,在目录$(wildcard $(NDK_ROOT)/toolchains/*/config.mk)下,有所有交叉编译工具的定义,每个工具通过
      config.mk和setup.mk两个文件来定义;可以得到:
      NDK_ALL_TOOLCHAINS:    arm-linux-androideabi-4.4.3  x86-4.4.3
       NDK_ALL_ABIS:    armeabi armeabi-v7a  x86
    h,在NDK_PLATFORMS_ROOT下得到所有支持的platform($(NDK_PLATFORMS_ROOT)),
      如:android-3 android-4 android-5 android-8 android-9,对于每种平台执行:include $(BUILD_SYSTEM)/add-platform.mk
      添加之,并指定:SYSROOT所在,如$(NDK_PLATFORMS_ROOT)/$(_platform)/arch-$(_abi)) = /home/tony/workstation/android-ndk-r6b/platforms/android-9/arch-arm
      然后找到各个level值以及最大值
4,build-all.mk,编译开始:
    a,初始化各个脚本变量,这些都是Android文件中常用的:
        CLEAR_VARS                := $(BUILD_SYSTEM)/clear-vars.mk
        BUILD_HOST_EXECUTABLE     := $(BUILD_SYSTEM)/build-host-executable.mk
        BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-host-static-library.mk
        BUILD_STATIC_LIBRARY      := $(BUILD_SYSTEM)/build-static-library.mk
        BUILD_SHARED_LIBRARY      := $(BUILD_SYSTEM)/build-shared-library.mk
        BUILD_EXECUTABLE          := $(BUILD_SYSTEM)/build-executable.mk
        PREBUILT_SHARED_LIBRARY   := $(BUILD_SYSTEM)/prebuilt-shared-library.mk
        PREBUILT_STATIC_LIBRARY   := $(BUILD_SYSTEM)/prebuilt-static-library.mk
        编译过程中会用的一些变量,伪目标,先把他们初始化了
        ANDROID_MK_INCLUDED := \
        $(CLEAR_VARS) \
        $(BUILD_HOST_EXECUTABLE) \
        $(BUILD_HOST_STATIC_LIBRARY) \
        $(BUILD_STATIC_LIBRARY) \
        $(BUILD_SHARED_LIBRARY) \
        $(BUILD_EXECUTABLE) \
        $(PREBUILT_SHARED_LIBRARY) \

        # this is the list of directories containing dependency information
        # generated during the build. It will be updated by build scripts
        # when module definitions are parsed.
        #
        ALL_DEPENDENCY_DIRS :=

        # this is the list of all generated files that we would need to clean
        ALL_HOST_EXECUTABLES      :=
        ALL_HOST_STATIC_LIBRARIES :=
        ALL_STATIC_LIBRARIES      :=
        ALL_SHARED_LIBRARIES      :=
        ALL_EXECUTABLES           :=

        WANTED_INSTALLED_MODULES  :=
        等等。。。
    b,编译开始:
        $(foreach _app,$(NDK_APPS),\
          $(eval include $(BUILD_SYSTEM)/setup-app.mk)\
        )
        对每一个app循环,如Fake出来的app:local
5,setup-app.mk:
    a,对与每个app,确定TARGET_PLATFORM和TARGET_ARCH_ABI,检查他们的合法性;
    b,对于每个TARGET_ARCH_ABI,进行include $(BUILD_SYSTEM)/setup-abi.mk操作;
6,setup-abi.mk:
    a,确定:TARGET_ARCH
    b,确定:TARGET_OUT,TARGET_OBJS,TARGET_GDB_SETUP;
    c,保存:TARGET_PLATFORM -->TARGET_PLATFORM_SAVED
    d,include $(BUILD_SYSTEM)/setup-toolchain.mk,建立交叉编译;
//------------------------------------------------------以上涉及的关键控制(如app,abi)都在application.mk里面定义--------------------------------
7,setup-toolchain.mk:
    a,获取TARGET_TOOLCHAIN,编译工具
    b,获取TARGET_ABI,目标的指令集
    c,SYSROOT,用于指定编译时所依赖的库和头文件。
    d,统计$(__ndk_modules)模块,并计算每个模块的依赖
    e,对于每个模块执行:build-binary.mk
8,build-binary.mk:
    a,统计出每个模块里面的变量定义:include $(BUILD_SYSTEM)/import-locals.mk
      计算出,LOCAL_CPP_EXTENSION,LOCAL_CFLAGS,LOCAL_OBJECTS,LOCAL_ARM_MODE,LOCAL_ARM_NEON,LOCAL_SRC_FILES,LOCAL_DEPENDENCY_DIRS
      LOCAL_STATIC_LIBRARIES,LOCAL_SHARED_LIBRARIES ,LOCAL_WHOLE_STATIC_LIBRARIES, LOCAL_LDLIBS,分问库和源文件两类
    b,根据是静态库,动态库或者可执行文件三种类型来进行5种情况的编译,
        I,$(cmd-build-shared-library):If this is a shared library module
        II,$(cmd-build-executable):If this is an executable module
        III,$(cmd-build-static-library):If this is a static library module
        IV,Prebuilt:If this is a prebuilt module
        V,cmd-strip:If this is an installable module
        其中,I,II,III,三种情况使用的编译命令参数可在 $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.4.3/setup.mk中找到定义,
        系统中也有默认的(default-build-commands)

//------------------------------------------------------以上关键控制(如:LOCAL_XXX)都在Android.mk里面定义--------------------------------------

Note:
    如果你的工程没有Application.mk文件,则系统会用默认的,$(NDK_ROOT)/build/core/default-application.mk

    以上就是android-ndk编译文件make走过的全过程

猜你喜欢

转载自hulefei29.iteye.com/blog/1962286