精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Android.mk語法簡介

我快閉嘴 ? 來源:簡書 ? 作者:愛因私談 ? 2022-09-13 15:33 ? 次閱讀

Android.mk簡介:

Android.mk文件用來告知NDK Build系統關于Source的信息。Android.mk將是GNU Makefile的一部分,且將被Build System解析一次或多次。

所以,請盡量少的在Android.mk中聲明變量,也不要假定任何東西不會在解析過程中定義。

Android.mk文件語法允許我們將Source打包成一個"modules",modules可以是:

  • 靜態庫

  • 動態庫

只有動態庫可以被install/copy到應用程序包(APK), 靜態庫則可以被鏈接入動態庫。

可以在一個Android.mk中定義一個或多個modules. 也可以將同一份source加進多個modules。

Build System幫我們處理了很多細節而不需要我們再關心。例如:你不需要在Android.mk中列出頭文件和外部依賴文件。


NDK Build System自動幫我們提供這些信息。這也意味著,當用戶升級NDK后,你將可以受益于新的toolchain/platform而不必再去修改Android.mk。

Android.mk 語法

1. 基本語法

首先看一個最簡單的Android.mk的例子:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)

講解如下:

LOCAL_PATH := $(call my-dir)

每個Android.mk文件必須以定義LOCAL_PATH為開始,它用于在開發tree中查找源文件;宏my-dir則由Build System提供,返回包含Android.mk的目錄路徑。

include $(CLEAR_VARS)

CLEAR_VARS 變量由Build System提供,并指向一個指定的GNU Makefile,由它負責清理很多LOCAL_xxx。

例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH,這個清理動作是必須的,因為所有的編譯控制文件由同一個GNU Make解析和執行,其變量是全局的,所以清理后才能避免相互影響。

LOCAL_MODULE    := hello-jni

LOCAL_MODULE模塊必須定義,以表示Android.mk中的每一個模塊。名字必須唯一且不包含空格。


Build System會自動添加適當的前綴和后綴。例如,foo,要產生動態庫,則生成libfoo.so。但請注意:如果模塊名被定為:libfoo,則生成libfoo.so,不再加前綴。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES 變量必須包含將要打包如模塊的 C/C++ 源碼。


不必列出頭文件,Build System 會自動幫我們找出依賴文件。


缺省的C++源碼的擴展名為.cpp。也可以修改,通過LOCAL_CPP_EXTENSION。

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY 是Build System提供的一個變量,指向一個GNU Makefile Script。


它負責收集自從上次調用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息,并決定編譯為什么。

  • BUILD_STATIC_LIBRARY:編譯為靜態庫

  • BUILD_SHARED_LIBRARY:編譯為動態庫

  • BUILD_EXECUTABLE:編譯為Native C可執行程序

2. NDK Build System變量

NDK Build System 保留以下變量名:

  • 以LOCAL_、PRIVATE_,NDK_、APP_ 開頭的名字

  • 小寫字母名字,如:my-dir
    如果想要定義自己在Android.mk中使用的變量名,建議添加 MY_ 前綴。

2.1 NDK提供的變量

此類GNU Make變量是NDK Build System在解析Android.mk之前就定義好了的。

2.1.1 CLEAR_VARS

指向一個編譯腳本,必須在新模塊前包含之。

include $(CLEAR_VARS)
2.1.2 BUILD_SHARED_LIBRARY

指向一個編譯腳本,它收集自從上次調用include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。


并決定如何將你列出的Source編譯成一個動態庫。注意:在包含此文件前,至少應該包含:LOCAL_MODULE and LOCAL_SRC_FILES,例如:

include $(BUILD_SHARED_LIBRARY)   
2.1.3 BUILD_STATIC_LIBRARY

與前面類似,它也指向一個編譯腳本,
收集自從上次調用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。


并決定如何將你列出的Source編譯成一個靜態庫。靜態庫不能夠加入到Project 或者APK中。但它可以用來生成動態庫。


LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES將描述之。

include $(BUILD_STATIC_LIBRARY)

2.1.4 BUILD_EXECUTABLE

與前面類似,它也指向一個編譯腳本,收集自從上次調用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。


并決定如何將你列出的Source編譯成一個可執行Native程序。

include $(BUILD_EXECUTABLE) 

2.1.5 PREBUILT_SHARED_LIBRARY

把這個共享庫聲明為 “一個” 獨立的模塊。


指向一個build 腳本,用來指定一個預先編譯好多動態庫。與BUILD_SHARED_LIBRARY and BUILD_STATIC_LIBRARY不同,
此時模塊的LOCAL_SRC_FILES應該被指定為一個預先編譯好的動態庫,而非source file.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt     # 模塊名
LOCAL_SRC_FILES := libfoo.so     # 模塊的文件路徑(相對于 LOCAL_PATH)

include $(PREBUILT_SHARED_LIBRARY) # 注意這里不是 BUILD_SHARED_LIBRARY
include $(PREBUILT_SHARED_LIBRARY) # 注意這里不是 BUILD_SHARED_LIBRARY

這個共享庫將被拷貝到 $PROJECT/obj/local 和 $PROJECT/libs/ (stripped) 主要是用在將已經編譯好的第三方庫
使用在本Android Project中。為什么不直接將其copy到libs/armabi目錄呢?因為這樣做缺陷很多。

2.1.6 PREBUILT_STATIC_LIBRARY

預先編譯的靜態庫,同上。

2.1.7 TARGET_ARCH

目標CPU架構名,如果為“arm” 則聲稱ARM兼容的指令,與CPU架構版本無關。

ifeq ($(TARGET_ARCH),arm)  
  ... 
endif

2.1.8 TARGET_PLATFORM

目標平臺的名字,對應android版本號,取值包括:android-8、android-9...android-21。

ifeq ($(TARGET_PLATFORM),android-8)  
  ... 
endif

2.1.9 TARGET_ARCH_ABI

是反應當前的cpu/abi的類型,取值包括:
32位:armeabi、armeabi-v7a、x86、mips;
64位:arm64-v8a、x86_64、mips64;

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)  
  RS_TRIPLE := armv7-none-linux-gnueabi  
endif  
ifeq ($(TARGET_ARCH_ABI),armeabi)  
  RS_TRIPLE := arm-none-linux-gnueabi  
endif  
ifeq ($(TARGET_ARCH_ABI),mips)  
  RS_TRIPLE := mipsel-unknown-linux  
endif  
ifeq ($(TARGET_ARCH_ABI),x86)  
  RS_TRIPLE := i686-unknown-linux  
endif

2.2 NDK提供的功能宏

GNU Make 提供的功能宏,只有通過類似:$(call function) 的方式來得到其值,它將返回文本化的信息。

2.2.1 my-dir

返回最近一次include的Makefile的路徑,通常返回Android.mk所在的路徑,它用來作為Android.mk的開頭來定義LOCAL_PATH。

LOCAL_PATH := $(call my-dir)

注意:返回的是最近一次include的Makefile的路徑。所以在include其它Makefile后,再調用$(call my-dir)會返回其它Android.mk所在路徑。
例如:

LOCAL_PATH := $(call my-dir) # declare one module
...
include $(LOCAL_PATH)/foo/Android.mk   
LOCAL_PATH := $(call my-dir) # declare another module

則第二次返回的LOCAL_PATH為:$PATH/foo,而非$PATH。

2.2.2 all-subdir-makefiles

返回一個列表,包含 “my-dir” 中所有子目錄中的Android.mk。
例如:

sources/foo/Android.mk
sources/foo/lib1/Android.mk
sources/foo/lib2/Android.mk

在sources/foo/Android.mk中:

include $(call all-subdir-makefiles)

那則自動include了:
sources/foo/lib1/Android.mk
sources/foo/lib2/Android.mk

2.2.3 this-makefile

當前Makefile的路徑。

2.2.4 parent-makefile

返回include tree中父Makefile路徑,也就是include當前Makefile的Makefile路徑。

2.2.5 import-module

允許尋找并import其它Modules到本Android.mk中來。它會從NDK_MODULE_PATH尋找指定的模塊名。

import-module和include區別:
功能基本一樣。

概念區別:include導入的是由我們自己寫的Makefile。而import-module導入的是外部庫、外部模塊提供的Makefile。

用法區別:include的路徑是Makefile文件的絕對路徑。
而import-module是NDK_MODULE_PATH中路徑列表的相對路徑。

$(call import-module, 模塊名/子目錄)

NDK_MODULE_PATH的配置:

NDK_MODULE_PATH 是一個環境變量,是Android.mk中設置的變量。

直接將 “NDK_MODULE_PATH=路徑1:路徑2” 加到 ndk-build命令的參數后面:

$ndk-build -C $HELLOWORLD_ROOT NDK_MODULE_PATH=路徑1:路徑2

在Android.mk中設置NDK_MODULE_PATH:

$(call import-add-path,$(LOCAL_PATH)/platform/third_party/android/prebuilt)

在系統環境里手動添加這個環境變量。

例如:

有一個Android.mk路徑如下:
F:cocos2d-xCocosDenshionandroidandroid.mk
已設置:NDK_MODULE_PATH=/cygdrive/f/cocos2d-x


那么在Android.mk引入此模塊的方法如下:

$(call import-module,CocosDenshion/android)

2.3 模塊描述變量

此類變量用來給Build System描述模塊信息。在'include $(CLEAR_VARS)' 和 'include $(BUILD_XXXXX)'之間,必須定義此類變量。

  • include $(CLEAR_VARS) 用來清空這些變量。

  • include $(BUILD_XXXXX) 收集和使用這些變量。

2.3.1 LOCAL_PATH

這個值用來給定當前目錄,必須在Android.mk的開是位置定義之。

例如:

LOCAL_PATH := $(call my-dir)  

LOCAL_PATH不會被include $(CLEAR_VARS)清理。

2.3.2 LOCAL_MODULE

定義Modules名,在include $(BUILD_XXXXX)之前,必須定義這個變量,此變量必須唯一且不能有空格。通常由此變量名決定最終生成的目標文件名。

2.3.3 LOCAL_MODULE_FILENAME

(可選)即允許用戶重新定義最終生成的目標文件名。

LOCAL_MODULE := foo-version-1   
LOCAL_MODULE_FILENAME := libfoo

2.3.4 LOCAL_SRC_FILES

為Build Modules而提供的Source文件列表,不需要列出依賴文件。
==注意:文件相對于LOCAL_PATH存放,且可以提供相對路徑。==

例如:

LOCAL_SRC_FILES := foo.c  
                   toto/bar.c

2.3.5 LOCAL_CPP_EXTENSION

(可選)指出C++擴展名。

LOCAL_CPP_EXTENSION := .cxx

從NDK R7后,可以寫多個:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

2.3.6 LOCAL_CPP_FEATURES

(可選)用來指定C++ features。

LOCAL_CPP_FEATURES := rtti  
LOCAL_CPP_FEATURES := exceptions

2.3.7 LOCAL_C_INCLUDES

一個可選的path列表,相對于NDK ROOT目錄,編譯時將會把這些目錄附上,主要為了頭文件的引用。

LOCAL_C_INCLUDES := sources/foo  
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

2.3.8 LOCAL_CFLAGS

(可選)在編譯C/C++ source 時添加如Flags,用來附加編譯選項。

注意:不要嘗試在此處修改編譯的優化選項和Debug等級,它會通過您Application.mk中的信息自動指定。

  • -Wall:是打開警告開關。

  • -O:代表默認優化,可選:-O0不優化,-O1低級優化,-O2中級優化,-O3高級優化,-Os代碼空間優化。

  • -g:是生成調試信息,生成的可執行文件具有和源代碼關聯的可調試的信息。

  • -fopenmp:OpenMp是由OpenMP Architecture Review Board牽頭提出的,并已被廣泛接受的,用于共享內存并行系統的多處理器程序設計的一套指導性的編譯處理方案(Compiler Directive)。

    OpenMP支持的編程語言包括C語言、C++和Fortran;而支持OpenMp的編譯器包括Sun Compiler,GNU Compiler和Intel Compiler等。OpenMp提供了對并行算法的高層的抽象描述,程序員通過在源代碼中加入專用的pragma來指明自己的意圖,由此編譯器可以自動將程序進行并行化,并在必要之處加入同步互斥以及通信。當選擇忽略這些pragma,或者編譯器不支持OpenMp時,程序又可退化為通常的程序(一般為串行),代碼仍然可以正常運作,只是不能利用多線程來加速程序執行。

  • -D:增加全局宏定義(==常用==)

  • -ffast-math:浮點優化選項,極大地提高浮點運算速度。

  • -mfloat-abi=softfp 浮點運算

LOCAL_CFLAGS += -DXXX # 相當于在所有源文件中增加一個宏定義'#define XXX'
2.3.10 LOCAL_CPPFLAGS

C++ Source 編譯時添加的C Flags,這些Flags將出現在LOCAL_CFLAGS flags 的后面。

2.3.11 LOCAL_STATIC_LIBRARIES

要鏈接到本模塊的靜態庫list,這僅僅對共享庫模塊才有意義。

Android.mk 1:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib_static
LOCAL_SRC_FILES := src.c
include $(BUILD_STATIC_LIBRARY)

Android.mk 2:

include $(CLEAR_VARS)
LOCAL_MODULE := mylib_shared
LOCAL_SRC_FILES := src2.c
LOCAL_STATIC_LIBRARIES := mylib_static
include $(BUILD_SHARED_LIBRARY)

要編譯Android.mk 2,必須已經先編譯mylib_static靜態庫,即Android.mk 1。

2.3.12 LOCAL_SHARED_LIBRARIES

要鏈接到本模塊的動態庫,同上。

2.3.13 LOCAL_WHOLE_STATIC_LIBRARIES

靜態庫全鏈接,不同于LOCAL_STATIC_LIBRARIES,類似于使用--whole-archive,LOCAL_WHOLE_STATIC_LIBRARIES在連接靜態連接庫的時候不會移除"daed code",何謂dead code呢,就是調用者模塊永遠都不會用到的代碼段和變量

2.3.14 LOCAL_LDLIBS

鏈接flags,鏈接的庫不產生依賴關系,一般用于不需要重新編譯的庫,可以用它來添加系統庫。

LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog …

2.3.15 LOCAL_ALLOW_UNDEFINED_SYMBOLS

默認情況下,在試圖編譯一個共享庫時,任何未定義的引用將導致一個“未定義的符號”錯誤。


然而,如果你因為某些原因,需要不啟動這項檢查,把這個變量設為'true'。注意相應的共享庫可能在運行時加載失敗。(這個一般盡量不要去設為true)

2.3.16 LOCAL_ARM_MODE

缺省模式下,ARM目標代碼被編譯為thumb模式。每個指令16位。如果指定此變量為'arm',則指令為32位。

LOCAL_ARM_MODE := arm

其實也可以指定某一個或者某幾個文件的ARM指令模式。

2.3.17 LOCAL_ARM_NEON

設置為true時,會講浮點編譯成neon指令。這會極大地加快浮點運算(前提是硬件支持)
只有targeting為'armeabi-v7a'時才可以。

2.3.18 LOCAL_DISABLE_NO_EXECUTE

Android NDK r4版本開始支持這種"NX bit"的安全功能。默認是啟用的,你也可以設置該變量的值為true來禁用它。但不推薦這么做。該功能不會修改ABI,只在ARMv6+CPU的設備內核上啟用。

2.3.19 LOCAL_EXPORT_CFLAGS

定義這個變量用來記錄C/C++編譯器標志集合,
并且會被添加到其他任何以LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES的模塊的LOCAL_CFLAGS定義中。

注意:此處NDK版本為NDK R7C。(不同NDK版本,ndk-build所產生的Makefile并不完全相同)

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Android
    +關注

    關注

    12

    文章

    3923

    瀏覽量

    127128
  • NDK
    NDK
    +關注

    關注

    0

    文章

    16

    瀏覽量

    14034
  • 語法
    +關注

    關注

    0

    文章

    44

    瀏覽量

    9784

原文標題:Android.mk文件語法詳解

文章出處:【微信號:哆啦安全,微信公眾號:哆啦安全】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Android系統移植及編譯(二)

    Android.mk每個具體的源碼目錄有一個主makefile: Android.mk。編譯不同的目標,有不同的模板,可以參考android源代碼目錄中,相關的例子。⑷編譯輸出結果(包括中間文件)放在
    發表于 08-06 15:16

    AM335X開發板Android 應用程序獲得system權限的方法

    在app工程添加Android.mk文件,其中的LOCAL_CERTIFICATE要賦值為platform,即用系統的簽名,通過這種方式只能使應用程序的權限升級到system級別。參考例程如下
    發表于 05-20 17:55

    芯靈思開發板安卓底層開發學習經驗第四期

    java層來說,Android.mk編譯生成jar包或者Android.apk這些Android.mk的編寫都是我們基于Android.mk的基本
    發表于 08-18 09:11

    芯靈思開發板安卓底層開發資料四

    我們基于Android.mk的基本語法來實現的,如果我們想在Android目錄下來編寫自己的項目,那我們就必須學會Android.mk的編寫。下面我們來分析一個最基礎的
    發表于 10-12 10:05

    Qualcomm Symphony System Manager SDK使用舉例

    the APP_PLATFORM to match your platform version.APP_PLATFORM := android-18# vim Android.mk內容如下:LOCAL_PATH
    發表于 09-21 10:33

    迅為-iMX6-Android4.4-串口屏蔽gps文檔及測試例程

    Android 系統源碼中,GPS 占用了這個串口的接收。需要屏蔽掉串口,重新編譯系統,這個串口就可以使用了底板版本:v_2.1 及以后的版本。1.1 修改 Android.mk 文件在源碼目錄使用“vi
    發表于 11-25 11:38

    Makefile腳本語法簡介

    宏定義LEDS_CTL 的使用Makefile腳本語法簡介Makefile測試
    發表于 12-22 06:39

    請問一下怎么去解決編譯錯誤_config.mk的問題

    ;frameworks/av/media/libcedarc/library/Android.mk:28: "lib_32 is: "notdef"_32"frameworks
    發表于 01-04 07:55

    編譯錯誤_config.mk: No such file or directory怎么解決?

    ;frameworks/av/media/libcedarc/library/Android.mk:28: "lib_32 is: "notdef"_32"
    發表于 01-13 07:14

    一步一步介紹在RK3288 Android系統下進行OpenCL開發

    開發了。下面給出一個打印OpenCL信息的Demo。由于libGLES_mali.so并沒有放入的android的/system/lib路徑下,所以我們要在Demo的Android.mk文件中要對libGLES_mali.so做預編譯,
    發表于 07-20 16:13

    如何去解決RK3568 Android系統二次編譯失敗的問題

    BUILD_BROKEN_DUP_RULES := true,但又會出其他問題。  [ 46% 128/277] including hardware/rockchip/libhwjpeg/Android.mk 。..  [ 48
    發表于 09-08 16:20

    RK3399編譯Android10出錯

    in BoardConfig.mkSaved manifest to out/commit_id.xml[ 95% 12265/12797] including build/make/target/board/Android.mk
    發表于 01-31 19:33

    MEDICI的語法概覽

    MEDICI 的語法概覽 語句簡介
    發表于 08-27 18:01 ?0次下載

    Android操作的系統簡介

    Android操作的系統簡介
    發表于 10-31 14:50 ?13次下載
    <b class='flag-5'>Android</b>操作的系統<b class='flag-5'>簡介</b>

    Android.mk判斷語句簡介

    Android.mkAndroid 提供的一種makefile 文件,注意用來編譯生成(exe,so,a,jar,apk)等文件。
    的頭像 發表于 04-15 09:29 ?1589次閱讀