深入理解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走過的全過程


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com