• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            唐吉訶德

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              5 Posts :: 75 Stories :: 3 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(2)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            Android.mk文件語法規范

            根據eoeandroid上的的連載,進行一些更新、修改和加亮。

            今天翻譯ANDROID-MK.TXT文件(英文原文件在/development/Ndk/Docs/android-mk.txt

            Android.mk文件語法規范

             

            Introduction:

            Android.mk編譯文件是用來向Android NDK描述你的C,C++源代碼文件的, 這篇文檔描述了它的語法。在閱讀下面的內容之前,假定你已經閱讀了docs/OVERVIEW.TXT文件,了解了它們的腳色和用途。

             

            概述:

            一個Android.mk file用來向編譯系統描述你的源代碼。具體來說:-該文件是GNU Makefile的一小部分,會被編譯系統解析一次或更多次的build系統。因此,您應盡量減少您聲明的變量,不要認為某些變量在解析過程中不會被定義。-這個文件的語法允許把你的源代碼組織成模塊,一個模塊屬下列類型之一:

            靜態庫

            共享庫

            只有共享庫將被安裝/復制到您的應用軟件包。雖然靜態庫能被用于生成共享庫。

            你可以在每一個Android.mk file中定義一個或多個模塊,你也可以在幾個模塊中使用同一個源代碼文件。

            /*****************************************************************************/

            -編譯系統為你處理許多細節問題。例如,你不需要在你的Android.mk中列出頭文件和依賴文件。NDK編譯系統將會為你自動處理這些問題。這也意味著,在升級NDK后,你應該得到新的toolchain/platform支持,而且不需要改變你的Android.mk文件。

            注意,這個語法同公開發布的Android平臺的開源代碼很接近,然而編譯系統實現他們的方式卻是不同的,這是故意這樣設計的,可以讓程序開發人員重用外部庫的源代碼更容易。

             

            簡單的例子:

            ---------------

            在描述語法細節之前,咱們來看一個簡單的"hello world"的例子,比如,下面的文件:

            sources/helloworld/helloworld.c

            sources/helloworld/Android.mk

            'helloworld.c'是一個JNI共享庫,實現返回"hello world"字符串的原生方法。

            相應的Android.mk文件會象下面這樣:

            ---------- cut here ------------------

            LOCAL_PATH := $(call my-dir)

            include $(CLEAR_VARS)

            LOCAL_MODULE:= helloworld

            LOCAL_SRC_FILES := helloworld.c

            include $(BUILD_SHARED_LIBRARY)

            ---------- cut here ------------------

            好,我們來解釋一下這幾行代碼:

            LOCAL_PATH := $(call my-dir)

            一個Android.mk file首先必須定義好LOCAL_PATH變量。它用于在開發樹中查找源文件。在這個例子中,宏函數’my-dir, 由編譯系統提供,用于返回當前路徑(即包含Android.mk file文件的目錄)。

            include $( CLEAR_VARS)

            CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE為你清除許多LOCAL_XXX變量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),

            LOCAL_PATH 。這是必要的,因為所有的編譯控制文件都在同一個GNU MAKE執行環境中,所有的變量都是全局的。

            LOCAL_MODULE := helloworld

            LOCAL_MODULE變量必須定義,以標識你在Android.mk文件中描述的每個模塊。名稱必須是唯一的,而且不包含任何空格。注意編譯系統會自動產生合適的前綴和后綴,換句話說,一個被命名為'foo'的共享庫模塊,將會生成'libfoo.so'文件。

            重要注意事項

            如果你把庫命名為‘libhelloworld’,編譯系統將不會添加任何的lib前綴,也會生成libhelloworld.so,這是為了支持來源于Android平臺的源代碼的Android.mk文件,如果你確實需要這么做的話。

            LOCAL_SRC_FILES := helloworld.c

            LOCAL_SRC_FILES變量必須包含將要編譯打包進模塊中的CC++源代碼文件。注意,你不用在這里列出頭文件和包含文件,因為編譯系統將會自動為你找出依賴型的文件;僅僅列出直接傳遞給編譯器的源代碼文件就好。【注意,默認的C++源碼文件的擴展名是’.cpp. 指定一個不同的擴展名也是可能的,只要定義LOCAL_DEFAULT_CPP_EXTENSION變量,不要忘記開始的小圓點(也就是定義為‘.cxx,而不是‘cxx’)(當然這一步我們一般不會去改它)】

            include $(BUILD_SHARED_LIBRARY)

            BUILD_SHARED_LIBRARY是編譯系統提供的變量,指向一個GNU Makefile腳本(應該就是在build/core目錄下的shared_library.mk),負責收集自從上次調用'include $(CLEAR_VARS)'以來,定義在LOCAL_XXX變量中的所有信息,并且決定編譯什么,如何正確地去做。并根據其規則生成靜態庫。同理對于靜態庫。

             

             

             

            /****************************************************************************/

            sources/samples目錄下有更復雜一點的例子,寫有注釋的Android.mk文件,你可以看看。

            參考:

            這是一份你應該在Android.mk中依賴或定義的變量列表,您可以定義其他變量為自己使用,

            但是NDK編譯系統保留下列變量名:

            -LOCAL_開頭的名字(例如 LOCAL_MODULE

            -PRIVATE_, NDK_ or APP_開頭的名字(內部使用)

            -小寫名字(內部使用,例如’my-dir’)

            如果您為了方便在Android.mk中定義自己的變量,我們建議使用MY_前綴,一個小例子:

            ---------- cut here ------------------

            MY_SOURCES := foo.c

            ifneq ($(MY_CONFIG_BAR),)

            MY_SOURCES += bar.c

            endif

            LOCAL_SRC_FILES += $(MY_SOURCES)

            ---------- cut here ------------------

            - - - - - - - - - - -

            這些GNU Make 變量在你的Android.mk文件解析之前,就由編譯系統定義好了。

            注意在某些情況下,NDK可能分析Android.mk幾次,每一次某些變量的定義會有不同。

            CLEAR_VARS

            指向一個編譯腳本,幾乎所有未定義的LOCAL_XXX變量都在"Module-description"節中列出。

            你必須在開始一個新模塊之前包含這個腳本。include $(CLEAR_VARS)

             

            BUILD_SHARED_LIBRARY

            指向編譯腳本,收集所有的你在LOCAL_XXX變量中提供的信息,并且決定如何把你列出的源代碼文件編譯成一個共享庫。注意,你必須至少在包含這個文件之前定義LOCAL_MODULELOCAL_SRC_FILES,使用例子:

            include $(BUILD_SHARED_LIBRARY)

            注意這將生成一個名為lib$(LOCAL_MODULE).so的文件。

             

            BUILD_STATIC_LIBRARY

            一個BUILD_SHARED_LIBRARY變量用于編譯一個靜態庫。靜態庫不會復制到你的project/packages中,誕生能夠用于編譯共享庫,(看下面描述的LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES

            使用例子:

            include $(BUILD_STATIC_LIBRARY)

            注意,這將會生成一個名為lib$(LOCAL_MODULE).a的文件。

             

            TARGET_ARCH

            目標CPU平臺的名字,如同在android開放源碼中指定的那樣。如果是’arm’,表示要生成ARM兼容的指令,與CPU架構的修訂版無關。

             

            TARGET_PLATFORM

            Android.mk解析的時候,目標Android平臺的名字.詳情可參考/development/ndk/docs/stable-apis.txt.

                android-3      -> Official Android 1.5 system images

                android-4      -> Official Android 1.6 system images

                android-5      -> Official Android 2.0 system images

             

            TARGET_ARCH_ABI

            暫時只支持兩個valuearmeabiarmeabi-v7a。在現在的版本中一般把這兩個值簡單的定義為arm,通過android 平臺內部對它重定義來獲得更好的匹配。

            其他的ABI將在以后的NDK版本中介紹,它們會有不同的名字。注意所有基于ARM的ABI都會把'TARGET_ARCH'定義成‘arm’,但是會有不同的‘TARGET_ARCH_ABI

             

            TARGET_ABI

              目標平臺和ABI的組合,它事實上被定義成$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI) 在你想要在真實的設備中針對一個特別的目標系統進行測試時,會有用。在默認的情況下,它會是'android-3-arm'

             

             

            /*****************************************************************************/

            下面是GNU Make ‘功能’宏,必須通過使用'$(call <function>)'來求值,他們返回文本化的信息。

            my-dir

            返回當前Android.mk所在的目錄路徑,相對于NDK編譯系統的頂層。這是有用的,在Android.mk文件的開頭如此定義:

            LOCAL_PATH := $(call my-dir)

             

            all-subdir-makefiles

               返回一個位于當前'my-dir'路徑的子目錄列表。例如,看下面的目錄層次:

            sources/foo/Android.mk

            sources/foo/lib1/Android.mk

            sources/foo/lib2/Android.mk

            如果sources/foo/Android.mk包含一行

            include $(call all-subdir-makefiles)

            那么它就會自動包含sources/foo/lib1/Android.mk sources/foo/lib2/Android.mk

            這項功能用于向編譯系統提供深層次嵌套的代碼目錄層次。注意,在默認情況下,NDK將會只搜索在sources/*/Android.mk中的文件。

             

            this-makefile

            返回當前Makefile的路徑(即這個函數調用的地方)

             

            parent-makefile

              返回調用樹中父Makefile路徑。即包含當前MakefileMakefile路徑。

             

            grand-parent-makefile

            猜猜看...

             

             

            /*****************************************************************************/

            模塊描述變量:

            下面的變量用于向編譯系統描述你的模塊。你應該定義在'include $(CLEAR_VARS)''include $(BUILD_XXXXX)'之間定義。正如前面描寫的那樣,$(CLEAR_VARS是一個腳本,清除所有這些變量,除非在描述中顯式注明。

             

            LOCAL_PATH

              這個變量用于給出當前文件的路徑。你必須在Android.mk的開頭定義,可以這樣使用:

             

            LOCAL_PATH := $(call my-dir)

            這個變量不會被$(CLEAR_VARS)清除,因此每個Android.mk只需要定義一次(即使你在一個文件中定義了幾個模塊的情況下)。

             

            LOCAL_MODULE

            這是你模塊的名字,它必須是唯一的,而且不能包含空格。你必須在包含任一的$(BUILD_XXXX)腳本之前定義它。模塊的名字決定了生成文件的名字,例如,如果一個一個共享庫模塊的名字是<foo>,那么生成文件的名字就是lib<foo>.so。但是,在你的NDK生成文件中(或者Android.mk或者Application.mk),你應該只涉及(引用)有正常名字的其他模塊。

             

            LOCAL_SRC_FILES

            這是要編譯的源代碼文件列表。只要列出要傳遞給編譯器的文件,因為編譯系統自動為你計算依賴。

            注意源代碼文件名稱都是相對于LOCAL_PATH的,你可以使用路徑部分,例如:

            LOCAL_SRC_FILES := foo.c \

            toto/bar.c

            注意:在生成文件中都要使用UNIX風格的斜杠(/).windows風格的反斜杠不會被正確的處理。

             

            LOCAL_CPP_EXTENSION

            這是一個可選變量,用來指定C++代碼文件的擴展名,默認是'.cpp',但是你可以改變它,比如:

            LOCAL_CPP_EXTENSION := .cxx

             

            LOCAL_C_INCLUDES

                   路徑的可選配置,是從根目錄開始的,

                all sources (C, C++ and Assembly). For example:

                    LOCAL_C_INCLUDES := sources/foo

                Or even:

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

                   需要在任何包含LOCAL_CFLAGS / LOCAL_CPPFLAGS標志之前。

             

            LOCAL_CFLAGS

            可選的編譯器選項,在編譯C代碼文件的時候使用。

            這可能是有用的,指定一個附加的包含路徑(相對于NDK的頂層目錄),宏定義,或者編譯選項。

             重要信息:不要在Android.mk中改變optimization/debugging級別,只要在Application.mk中指定合適的信息,就會自動地為你處理這個問題,在調試期間,會讓NDK自動生成有用的數據文件。

             

            LOCAL_CXXFLAGS

            Same as LOCAL_CFLAGS for C++ source files

             

            LOCAL_CPPFLAGS

            LOCAL_CFLAGS相同,但是對C 和 C++ source files都適用。

             

            LOCAL_STATIC_LIBRARIES

            應該鏈接到這個模塊的靜態庫列表(使用BUILD_STATIC_LIBRARY生成),這僅僅對共享庫模塊才有意義。

             

            LOCAL_SHARED_LIBRARIES

            這個模塊在運行時要依賴的共享庫模塊列表,在鏈接時需要,在生成文件時嵌入的相應的信息。注意:這不會附加列出的模塊到編譯圖,也就是,你仍然需要在Application.mk中把它們添加到程序要求的模塊中。

             

            LOCAL_LDLIBS

            編譯你的模塊要使用的附加的鏈接器選項。這對于使用”-l”前綴傳遞指定庫的名字是有用的。例如,下面將告訴鏈接器生成的模塊要在加載時刻鏈接到/system/lib/libz.so

            LOCAL_LDLIBS := -lz

            docs/STABLE-APIS.TXT獲取你使用NDK發行版能鏈接到的開放的系統庫列表。

             

            LOCAL_ALLOW_UNDEFINED_SYMBOLS

              默認情況下,在試圖編譯一個共享庫時,任何未定義的引用將導致一個“未定義的符號”錯誤。這對于在你的源代碼文件中捕捉錯誤會有很大的幫助。

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

             

            LOCAL_ARM_MODE

                   默認情況下,arm目標二進制會以thumb的形式生成(16位),你可以通過設置這個變量為arm如果你希望你的module是以32位指令的形式。

                'arm' (32-bit instructions) mode. E.g.:

                  LOCAL_ARM_MODE := arm

            注意你同樣可以在編譯的時候告訴系統編譯特定的類型比如

                   LOCAL_SRC_FILES := foo.c bar.c.arm

            這樣就告訴系統總是將bar.carm的模式編譯,

             

             

            Android.mk使用模板

            在一個Android.mk中可以生成多個可執行程序、動態庫和靜態庫。

            1,編譯應用程序的模板:

                 #Test Exe

                 LOCAL_PATH := $(call my-dir)

                 #include $(CLEAR_VARS)

                 LOCAL_SRC_FILES:= main.c

                 LOCAL_MODULE:= test_exe

                 #LOCAL_C_INCLUDES :=

                 #LOCAL_STATIC_LIBRARIES :=

                 #LOCAL_SHARED_LIBRARIES :=

                 include $(BUILD_EXECUTABLE)

            (菜鳥級別解釋::=是賦值的意思,$是引用某變量的值)LOCAL_SRC_FILES中加入源文件路徑,LOCAL_C_INCLUDES 中加入所需要包含的頭文件路徑,LOCAL_STATIC_LIBRARIES加入所需要鏈接的靜態庫(*.a)的名稱,LOCAL_SHARED_LIBRARIES中加入所需要鏈接的動態庫(*.so)的名稱,LOCAL_MODULE表示模塊最終的名稱,BUILD_EXECUTABLE表示以一個可執行程序的方式進行編譯。

            2,編譯靜態庫的模板:

                 #Test Static Lib

                 LOCAL_PATH := $(call my-dir)

                 include $(CLEAR_VARS)

                 LOCAL_SRC_FILES:= \

                           helloworld.c

                 LOCAL_MODULE:= libtest_static

                 #LOCAL_C_INCLUDES :=

                 #LOCAL_STATIC_LIBRARIES :=

                 #LOCAL_SHARED_LIBRARIES :=

                 include $(BUILD_STATIC_LIBRARY)

            一般的和上面相似,BUILD_STATIC_LIBRARY表示編譯一個靜態庫。

            3,編譯動態庫的模板:

                 #Test Shared Lib

                 LOCAL_PATH := $(call my-dir)

                 include $(CLEAR_VARS)

                 LOCAL_SRC_FILES:= \

                           helloworld.c

                 LOCAL_MODULE:= libtest_shared

                 TARGET_PRELINK_MODULES := false

                 #LOCAL_C_INCLUDES :=

                 #LOCAL_STATIC_LIBRARIES :=

                 #LOCAL_SHARED_LIBRARIES :=

                  include $(BUILD_SHARED_LIBRARY)

            一般的和上面相似,BUILD_SHARED_LIBRARY表示編譯一個共享庫。

             

            以上三者的生成結果分別在如下,generic依具體target會變:

            out/target/product/generic/obj/EXECUTABLE

            out/target/product/generic/obj/STATIC_LIBRARY

            out/target/product/generic/obj/SHARED_LIBRARY

                  每個模塊的目標文件夾分別為:

            可執行程序:XXX_intermediates

            靜態庫:      XXX_static_intermediates

            動態庫:      XXX_shared_intermediates

                  另外,在Android.mk文件中,還可以指定最后的目標安裝路徑,用LOCAL_MODULE_PATHLOCAL_UNSTRIPPED_PATH來指定。不同的文件系統路徑用以下的宏進行選擇:

            TARGET_ROOT_OUT:表示根文件系統。

            TARGET_OUT:表示system文件系統。

            TARGET_OUT_DATA:表示data文件系統。

            用法如:

             LOCAL_MODULE_PATH:=$(TARGET_ROOT_OUT)

             

            posted on 2011-05-26 11:47 心羽 閱讀(496) 評論(0)  編輯 收藏 引用 所屬分類: android
            亚洲国产精久久久久久久| 久久午夜无码鲁丝片秋霞| 国产精品久久网| 国内精品久久久久久久亚洲 | 伊人久久大香线蕉综合网站| 久久精品中文字幕第23页| 思思久久好好热精品国产| 午夜精品久久久久久99热| 日本精品久久久中文字幕| 亚洲国产精品狼友中文久久久| 漂亮人妻被黑人久久精品| 国产精品久久久久久久| 少妇无套内谢久久久久| 久久久久久a亚洲欧洲aⅴ| 色综合久久夜色精品国产| 久久精品国产精品国产精品污| 日韩美女18网站久久精品| 久久99久久99小草精品免视看| 日韩人妻无码一区二区三区久久99| 久久国产乱子伦免费精品| 亚洲а∨天堂久久精品| 国产无套内射久久久国产| 国产精品久久久久影院嫩草 | 国产亚洲欧美精品久久久| 无夜精品久久久久久| 精品国产青草久久久久福利| 97久久精品午夜一区二区| 国产激情久久久久久熟女老人| 美女久久久久久| 亚洲国产精品嫩草影院久久| 四虎国产精品免费久久5151| 亚洲精品无码久久久久久| 国产69精品久久久久APP下载| 国产精品欧美亚洲韩国日本久久| 77777亚洲午夜久久多喷| 久久亚洲私人国产精品vA| 人妻无码中文久久久久专区 | 2022年国产精品久久久久| 九九精品99久久久香蕉| 精品无码久久久久久尤物| 久久亚洲私人国产精品|