Trang này mô tả cú pháp của tệp bản dựng Android.mk
mà ndk-build
sử dụng.
Tổng quan
Tệp Android.mk
nằm trong một thư mục con của thư mục jni/
trong dự án và mô tả các nguồn cũng như thư viện dùng chung cho hệ thống xây dựng.
Tệp này thật ra là một mảnh makefile GNU nhỏ mà hệ thống xây dựng phân tích cú pháp một hoặc nhiều lần. Tệp Android.mk
hữu ích cho việc xác định các chế độ cài đặt trên toàn dự án mà hệ thống xây dựng Application.mk
và các biến môi trường của bạn để ở trạng thái không xác định. Tệp này cũng có thể ghi đè các chế độ cài đặt trên toàn dự án cho các mô-đun cụ thể.
Cú pháp của Android.mk
cho phép bạn nhóm các nguồn của mình thành các mô-đun.
Mô-đun có thể là một thư viện tĩnh, thư viện dùng chung hoặc một tệp thực thi độc lập. Bạn có thể xác định một hoặc nhiều mô-đun trong mỗi tệp Android.mk
và sử dụng cùng một tệp nguồn trong nhiều mô-đun. Hệ thống xây dựng chỉ đặt các thư viện dùng chung vào gói ứng dụng của bạn. Ngoài ra, thư viện tĩnh có thể tạo ra các thư viện dùng chung.
Ngoài các thư viện đóng gói, hệ thống xây dựng còn xử lý nhiều chi tiết khác cho bạn. Ví dụ: Bạn không cần liệt kê tệp tiêu đề hoặc phần phụ thuộc rõ ràng giữa các tệp được tạo trong tệp Android.mk
. Hệ thống xây dựng NDK sẽ tự động tính toán các mối quan hệ này cho bạn. Nhờ đó, bạn có thể hưởng lợi từ khả năng hỗ trợ của chuỗi công cụ/nền tảng mới trong các bản phát hành NDK trong tương lai mà không cần sử dụng tệp Android.mk
.
Cú pháp của tệp này rất giống với cú pháp dùng trong các tệp Android.mk
được phân phối cùng với Dự án nguồn mở Android đầy đủ. Mặc dù việc triển khai hệ thống xây dựng sử dụng các loại tệp này sẽ khác biệt, nhưng điểm tương đồng là quyết định thiết kế có chủ đích hướng đến việc giúp các nhà phát triển ứng dụng dễ dàng sử dụng lại mã nguồn cho thư viện bên ngoài.
Thông tin cơ bản
Trước khi tìm hiểu chi tiết về cú pháp, bạn nên tìm hiểu những kiến thức cơ bản về nội dung có trong tệp Android.mk
. Phần này sử dụng tệp Android.mk
trong mẫu Hello-JNI theo hướng điểm cuối đó, giải thích vai trò của từng dòng trong tệp.
Tệp Android.mk
phải bắt đầu bằng cách xác định biến LOCAL_PATH
:
LOCAL_PATH := $(call my-dir)
Biến này cho biết vị trí của các tệp nguồn trong cây phát triển. Ở đây, hàm macro my-dir
do hệ thống xây dựng cung cấp sẽ trả về
đường dẫn của thư mục hiện tại (thư mục chứa chính tệp Android.mk
).
Dòng tiếp theo khai báo biến CLEAR_VARS
. Biến này có giá trị do hệ thống xây dựng cung cấp.
include $(CLEAR_VARS)
Biến CLEAR_VARS
trỏ đến một GNU Makefile đặc biệt giúp xoá nhiều biến LOCAL_XXX
cho bạn, chẳng hạn như LOCAL_MODULE
, LOCAL_SRC_FILES
và LOCAL_STATIC_LIBRARIES
. Lưu ý: Biến này không xoá LOCAL_PATH
. Biến này phải giữ nguyên giá trị vì hệ thống phân tích cú pháp tất cả các tệp kiểm soát bản dựng trong một ngữ cảnh thực thi GNU Make trong đó tất cả các biến đều là biến toàn cục. Bạn phải khai báo (lại) biến này trước khi mô tả từng mô-đun.
Tiếp theo, biến LOCAL_MODULE
lưu trữ tên của mô-đun mà bạn muốn tạo. Dùng biến này một lần cho mỗi mô-đun trong ứng dụng.
LOCAL_MODULE := hello-jni
Tên mỗi mô-đun phải là duy nhất và không chứa khoảng trắng. Hệ thống xây dựng, khi tạo tệp thư viện dùng chung cuối cùng, sẽ tự động thêm tiền tố và hậu tố thích hợp vào tên mà bạn chỉ định cho LOCAL_MODULE
. Ví dụ: Ví dụ xuất hiện ở trên sẽ dẫn đến việc tạo thư viện có tên là libhello-jni.so
.
Dòng tiếp theo liệt kê các tệp nguồn, có các dấu cách phân tách nhiều tệp:
LOCAL_SRC_FILES := hello-jni.c
Biến LOCAL_SRC_FILES
phải chứa danh sách các tệp nguồn C và/hoặc C++ để tạo thành một mô-đun.
Dòng cuối cùng giúp hệ thống liên kết mọi thứ với nhau:
include $(BUILD_SHARED_LIBRARY)
Biến BUILD_SHARED_LIBRARY
trỏ đến tập lệnh GNU Makefile thu thập tất cả thông tin mà bạn đã xác định trong các biến LOCAL_XXX
kể từ include
gần đây nhất. Tập lệnh này xác định nội dung cần xây dựng và cách xây dựng.
Bạn có thể xem nhiều ví dụ phức tạp hơn trong các thư mục mẫu, trong đó có các Android.mk
mà chúng tôi đã dẫn giải. Ngoài ra, phần Mẫu: hoạt động gốc cung cấp nội dung giải thích chi tiết về tệp Android.mk
của mẫu đó. Cuối cùng, phần Biến và macro cung cấp thêm thông tin về các biến trong phần này.
Biến và macro
Hệ thống xây dựng cung cấp nhiều biến có thể sử dụng trong tệp Android.mk
.
Nhiều biến trong số này được chỉ định sẵn giá trị. Các biến còn lại do bạn chỉ định giá trị.
Ngoài các biến này, bạn cũng có thể xác định biến tuỳ ý của riêng mình. Nếu bạn xác định biến riêng, hãy lưu ý rằng hệ thống xây dựng NDK đặt trước các tên biến sau:
- Tên bắt đầu bằng
LOCAL_
, chẳng hạn nhưLOCAL_MODULE
. - Tên bắt đầu bằng
PRIVATE_
,NDK_
hoặcAPP
. Hệ thống xây dựng sử dụng nội bộ các tên này. - Tên viết thường, chẳng hạn như
my-dir
. Hệ thống xây dựng cũng sử dụng nội bộ các tên này.
Nếu cần xác định các biến tiện lợi của riêng mình trong tệp Android.mk
, bạn nên đặt tiền tố MY_
trong tên của các biến đó.
Biến do NDK xác định
Phần này thảo luận về các biến GNU Make mà hệ thống xây dựng xác định trước khi phân tích cú pháp tệp Android.mk
của bạn. Trong một số trường hợp nhất định, NDK có thể phân tích cú pháp tệp Android.mk
của bạn nhiều lần, mỗi lần sử dụng một định nghĩa khác nhau cho một số biến trong số này.
CLEAR_VARS
Biến này trỏ đến một tập lệnh bản dựng không xác định gần như tất cả các biến LOCAL_XXX
được liệt kê trong phần "Biến do nhà phát triển xác định" bên dưới. Sử dụng biến này để bao gồm tập lệnh này trước khi mô tả một mô-đun mới. Cú pháp để sử dụng biến này như sau:
include $(CLEAR_VARS)
BUILD_EXECUTABLE
Biến này trỏ đến một tập lệnh bản dựng thu thập tất cả thông tin về mô-đun mà bạn cung cấp trong các biến LOCAL_XXX
và xác định cách tạo tệp thực thi mục tiêu từ các nguồn mà bạn đã liệt kê. Lưu ý: Việc sử dụng tập lệnh này yêu cầu rằng bạn đã chỉ định giá trị ít nhất là cho LOCAL_MODULE
và LOCAL_SRC_FILES
(để biết thêm thông tin về các biến này, hãy xem phần Biến mô tả mô-đun).
Cú pháp để sử dụng biến này như sau:
include $(BUILD_EXECUTABLE)
BUILD_SHARED_LIBRARY
Biến này trỏ đến một tập lệnh bản dựng thu thập tất cả thông tin về mô-đun mà bạn cung cấp trong các biến LOCAL_XXX
và xác định cách tạo thư viện dùng chung mục tiêu từ các nguồn mà bạn đã liệt kê. Lưu ý: Việc sử dụng tập lệnh này yêu cầu rằng bạn đã chỉ định giá trị ít nhất là cho LOCAL_MODULE
và LOCAL_SRC_FILES
(để biết thêm thông tin về các biến này, hãy xem phần Biến mô tả mô-đun).
Cú pháp để sử dụng biến này như sau:
include $(BUILD_SHARED_LIBRARY)
Biến thư viện dùng chung khiến hệ thống xây dựng tạo tệp thư viện có đuôi .so
.
BUILD_STATIC_LIBRARY
Một biến thể của BUILD_SHARED_LIBRARY
dùng để xây dựng thư viện tĩnh. Hệ thống xây dựng không sao chép các thư viện tĩnh vào dự án/gói của bạn, nhưng có thể sử dụng các thư viện đó để xây dựng thư viện dùng chung (xem LOCAL_STATIC_LIBRARIES
và LOCAL_WHOLE_STATIC_LIBRARIES
ở bên dưới). Cú pháp để sử dụng biến này như sau:
include $(BUILD_STATIC_LIBRARY)
Biến thư viện tĩnh khiến hệ thống xây dựng tạo một thư viện có đuôi .a
.
PREBUILT_SHARED_LIBRARY
Trỏ tới tập lệnh bản dựng dùng để chỉ định một thư viện dùng chung được tạo sẵn. Không giống như trong trường hợp BUILD_SHARED_LIBRARY
và BUILD_STATIC_LIBRARY
, giá trị của LOCAL_SRC_FILES
ở đây không được là tệp nguồn. Thay vào đó, giá trị này phải là một đường dẫn duy nhất đến thư viện dùng chung được tạo sẵn, chẳng hạn như foo/libfoo.so
. Cú pháp để sử dụng biến này như sau:
include $(PREBUILT_SHARED_LIBRARY)
Bạn cũng có thể tham chiếu thư viện tạo sẵn trong một mô-đun khác bằng cách sử dụng biến LOCAL_PREBUILTS
. Để biết thêm thông tin về cách sử dụng thư viện tạo sẵn, hãy xem Sử dụng thư viện tạo sẵn.
PREBUILT_STATIC_LIBRARY
Giống như PREBUILT_SHARED_LIBRARY
, nhưng dành cho thư viện tĩnh được tạo sẵn. Để biết thêm thông tin về cách sử dụng thư viện tạo sẵn, hãy xem Sử dụng thư viện tạo sẵn.
Biến thông tin mục tiêu
Hệ thống xây dựng phân tích cú pháp Android.mk
một lần cho mỗi ABI (Giao diện nhị phân ứng dụng) được chỉ định bởi biến APP_ABI
, thường được xác định trong tệp Application.mk
của bạn. Nếu APP_ABI
là all
, thì hệ thống xây dựng sẽ phân tích cú pháp Android.mk
một lần cho mỗi ABI mà NDK hỗ trợ. Phần này mô tả các biến mà hệ thống xây dựng xác định mỗi khi phân tích cú pháp Android.mk
.
TARGET_ARCH
Dòng CPU mà hệ thống xây dựng đang nhắm mục tiêu khi phân tích cú pháp tệp Android.mk
này. Biến này sẽ là một trong các loại sau: arm
, arm64
, x86
hoặc x86_64
.
TARGET_PLATFORM
Số cấp độ API Android mà hệ thống xây dựng đang nhắm mục tiêu khi phân tích cú pháp tệp Android.mk
này. Ví dụ: Ảnh hệ thống Android 5.1 tương ứng với API Android cấp 22: android-22
. Để biết danh sách đầy đủ các tên nền tảng và ảnh hệ thống Android tương ứng, hãy xem API gốc. Ví dụ sau đây cho thấy cú pháp khi sử dụng biến này:
ifeq ($(TARGET_PLATFORM),android-22)
# ... do something ...
endif
TARGET_ARCH_ABI
ABI mà hệ thống xây dựng đang nhắm mục tiêu khi phân tích cú pháp tệp Android.mk
này.
Bảng 1 cho thấy chế độ cài đặt ABI dùng cho mỗi CPU và cấu trúc được hỗ trợ.
CPU và cấu trúc | Cài đặt |
---|---|
ARMv7 | armeabi-v7a |
ARMv8 AArch64 | arm64-v8a |
i686 | x86 |
x86-64 | x86_64 |
Ví dụ sau cho thấy cách kiểm tra ARMv8 AArch64 dưới dạng tổ hợp CPU-and-ABI mục tiêu:
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
# ... do something ...
endif
Để biết thêm thông tin chi tiết về các ABI cấu trúc và các vấn đề liên quan về khả năng tương thích, hãy tham khảo phần ABI Android.
Các ABI mục tiêu mới trong tương lai sẽ có các giá trị khác nhau.
TARGET_ABI
Phép nối giữa cấp độ API Android mục tiêu và ABI. Phép này đặc biệt hữu ích khi bạn muốn kiểm thử dựa trên ảnh hệ thống mục tiêu cụ thể cho một thiết bị thực. Ví dụ: Để kiểm tra một thiết bị ARM 64 bit chạy trên API Android cấp 22:
ifeq ($(TARGET_ABI),android-22-arm64-v8a)
# ... do something ...
endif
Biến mô tả mô-đun
Các biến trong phần này mô tả mô-đun của bạn cho hệ thống xây dựng. Mỗi nội dung mô tả mô-đun phải tuân theo quy trình cơ bản sau:
- Khởi tạo hoặc không xác định các biến liên kết với mô-đun bằng cách sử dụng biến
CLEAR_VARS
. - Chỉ định giá trị cho các biến dùng để mô tả mô-đun.
- Thiết lập cho hệ thống xây dựng NDK sử dụng tập lệnh bản dựng phù hợp cho mô-đun bằng cách sử dụng biến
BUILD_XXX
.
LOCAL_PATH
Biến này được dùng để cung cấp đường dẫn của tệp hiện tại. Bạn phải xác định biến này ở đầu tệp Android.mk
. Ví dụ sau cho thấy cách thực hiện:
LOCAL_PATH := $(call my-dir)
Tập lệnh mà CLEAR_VARS
trỏ đến không xoá biến này. Do đó, bạn chỉ cần xác định một lần duy nhất, ngay cả khi tệp Android.mk
mô tả nhiều mô-đun.
LOCAL_MODULE
Biến này lưu trữ tên của mô-đun. Tên này phải là duy nhất trong số tất cả các tên mô-đun và không được có dấu cách. Bạn phải xác định mô-đun này trước khi bao gồm bất kỳ tập lệnh nào (ngoài tập lệnh cho CLEAR_VARS
). Bạn không cần thêm tiền tố lib
hoặc đuôi tệp .so
hay .a
vì hệ thống xây dựng sẽ tự động điều chỉnh. Trong toàn bộ các tệp Android.mk
và Application.mk
, hãy tham chiếu đến mô-đun của bạn theo tên chưa sửa đổi. Ví dụ: Dòng sau đây sẽ dẫn đến việc tạo ra mô-đun thư viện dùng chung có tên là libfoo.so
:
LOCAL_MODULE := "foo"
Nếu muốn mô-đun được tạo có tên khác với lib
và giá trị của LOCAL_MODULE
, thì bạn có thể sử dụng biến LOCAL_MODULE_FILENAME
để đặt tên bạn tự chọn cho mô-đun đã tạo.
LOCAL_MODULE_FILENAME
Biến tuỳ chọn này cho phép bạn ghi đè tên mà hệ thống xây dựng sử dụng theo mặc định cho các tệp mà hệ thống tạo. Ví dụ: Nếu tên của LOCAL_MODULE
là foo
, bạn có thể buộc hệ thống gọi tệp mà hệ thống tạo là libnewfoo
. Ví dụ sau đây cho thấy cách thực hiện:
LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo
Đối với một mô-đun thư viện dùng chung, ví dụ này sẽ tạo một tệp có tên là libnewfoo.so
.
LOCAL_SRC_FILES
Biến này chứa danh sách các tệp nguồn mà hệ thống xây dựng sử dụng để tạo mô-đun. Chỉ liệt kê các tệp mà hệ thống xây dựng thực sự truyền cho trình biên dịch, vì hệ thống xây dựng sẽ tự động tính toán mọi phần phụ thuộc kèm theo. Lưu ý: Bạn có thể sử dụng cả đường dẫn tệp tương đối (đến LOCAL_PATH
) và đường dẫn tệp tuyệt đối.
Bạn nên tránh sử dụng các đường dẫn tệp tuyệt đối; đường dẫn tương đối giúp tệp Android.mk
của bạn có khả năng di động linh hoạt hơn.
LOCAL_CPP_EXTENSION
Bạn có thể sử dụng biến tuỳ chọn này để chỉ báo loại đuôi tệp ngoài .cpp
cho tệp nguồn C++. Ví dụ: Dòng sau đây sẽ thay đổi đuôi tệp thành .cxx
. (Phần cài đặt phải bao gồm dấu chấm.)
LOCAL_CPP_EXTENSION := .cxx
Bạn có thể sử dụng biến này để chỉ định nhiều đuôi. Ví dụ:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES
Bạn có thể sử dụng biến tuỳ chọn này để chỉ báo rằng mã của bạn dựa trên các tính năng C++ cụ thể. Biến này kích hoạt cờ trình biên dịch và trình liên kết phù hợp trong quy trình xây dựng. Đối với các tệp nhị phân tạo sẵn, biến này cũng khai báo tính năng mà tệp nhị phân phụ thuộc, nhờ đó giúp đảm bảo hoạt động liên kết cuối cùng diễn ra chính xác. Bạn nên sử dụng biến này thay vì bật -frtti
và -fexceptions
trực tiếp trong định nghĩa LOCAL_CPPFLAGS
của bạn.
Khi bạn sử dụng biến này, hệ thống xây dựng có thể dùng các cờ thích hợp cho mỗi mô-đun. Việc sử dụng LOCAL_CPPFLAGS
sẽ khiến trình biên dịch sử dụng tất cả cờ đã chỉ định cho tất cả mô-đun, bất kể nhu cầu thực tế là gì.
Ví dụ: Để chỉ báo rằng mã của bạn sử dụng RTTI (Thông tin kiểu thời gian chạy), hãy ghi:
LOCAL_CPP_FEATURES := rtti
Để chỉ báo rằng mã của bạn sử dụng ngoại lệ của C++, hãy ghi:
LOCAL_CPP_FEATURES := exceptions
Bạn cũng có thể chỉ định nhiều giá trị cho biến này. Ví dụ:
LOCAL_CPP_FEATURES := rtti features
Thứ tự mà bạn mô tả các giá trị không quan trọng.
LOCAL_C_INCLUDES
Bạn có thể sử dụng biến tuỳ chọn này để chỉ định danh sách các đường dẫn, tương ứng với thư mục root
NDK, để thêm vào đường dẫn tìm kiếm bao hàm khi biên dịch tất cả các nguồn (C, C++ và Assembly). Ví dụ:
LOCAL_C_INCLUDES := sources/foo
Hoặc thậm chí:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo
Xác định biến này trước khi đặt bất kỳ cờ bao hàm (inclusion flag) tương ứng nào qua LOCAL_CFLAGS
hoặc LOCAL_CPPFLAGS
.
Hệ thống xây dựng cũng tự động sử dụng các đường dẫn LOCAL_C_INCLUDES
khi chạy phương thức gỡ lỗi gốc bằng ndk-gdb.
LOCAL_ASFLAGS (Hàm LOCAL_ASFLAGS)
Các cờ sẽ được truyền đến Clang khi tạo tệp .s
hoặc .S
.
LOCAL_ASMFLAGS
Cờ sẽ được truyền đến yasm khi tạo tệp .asm
.
LOCAL_CFLAGS
Những cờ sẽ được truyền đến Clang khi tạo bản dựng C, C++ và một số tệp nguồn tập hợp (.s
và .S
, nhưng không phải .asm
). Khả năng đó có thể hữu ích cho việc chỉ định thêm định nghĩa macro hoặc tuỳ chọn biên dịch. Sử dụng LOCAL_CPPFLAGS
để chỉ định cờ chỉ dành cho C++. Sử dụng LOCAL_CONLYFLAGS
để chỉ định cờ cho riêng C.
Cố gắng không thay đổi cấp độ tối ưu hoá/gỡ lỗi trong tệp Android.mk
.
Hệ thống xây dựng có thể tự động xử lý chế độ cài đặt này cho bạn bằng cách sử dụng thông tin liên quan trong tệp Application.mk
. Cách thực hiện này cho phép hệ thống xây dựng tạo các tệp dữ liệu hữu ích được dùng trong quá trình gỡ lỗi.
Bạn có thể chỉ định đường dẫn bao hàm bổ sung bằng cách ghi:
LOCAL_CFLAGS += -I<path>,
Tuy nhiên, tốt hơn là bạn nên sử dụng LOCAL_C_INCLUDES
cho mục đích này, vì việc này cũng giúp bạn có thể sử dụng các đường dẫn có sẵn để gỡ lỗi gốc bằng ndk-gdb.
LOCAL_CONLYFLAGS
Các cờ sẽ được truyền đến Clang khi biên dịch nguồn C. Không giống như LOCAL_CFLAGS
, LOCAL_CONLYFLAGS
sẽ không được truyền đến Clang khi biên dịch C++ hoặc nguồn tập hợp.
LOCAL_CPPFLAGS
Một tập hợp cờ trình biên dịch tuỳ chọn sẽ được truyền khi chỉ tạo các tệp nguồn C++. Các cờ này sẽ xuất hiện sau LOCAL_CFLAGS
trên dòng lệnh của trình biên dịch. Sử dụng LOCAL_CFLAGS
để chỉ định cờ cho cả C và C++.
LOCAL_STATIC_LIBRARIES
Biến này lưu trữ danh sách các mô-đun thư viện tĩnh mà mô-đun hiện tại phụ thuộc.
Nếu mô-đun hiện tại là một thư viện dùng chung hoặc một tệp thực thi, thì biến này sẽ buộc các thư viện này liên kết với tệp nhị phân thu được.
Nếu mô-đun hiện tại là thư viện tĩnh, thì biến này chỉ đơn giản cho biết các mô-đun khác tuỳ thuộc vào mô-đun hiện tại cũng sẽ phụ thuộc vào các thư viện được liệt kê.
LOCAL_SHARED_LIBRARIES
Biến này là danh sách các mô-đun thư viện dùng chung mà mô-đun này phụ thuộc trong thời gian chạy. Thông tin này cần thiết tại thời điểm liên kết và để nhúng thông tin tương ứng vào tệp được tạo.
LOCAL_WHOLE_STATIC_LIBRARIES
Biến này là một biến thể của LOCAL_STATIC_LIBRARIES
, đồng thời thể hiện rằng trình liên kết nên coi các mô-đun thư viện liên kết là tệp lưu trữ tổng thể. Để biết thêm thông tin về tệp lưu trữ tổng thể, hãy xem tài liệu về mã GNU cho cờ --whole-archive
.
Biến này rất hữu ích khi có các phần phụ thuộc tuần hoàn trong số nhiều thư viện tĩnh. Khi bạn sử dụng biến này để xây dựng một thư viện dùng chung, hệ thống xây dựng buộc phải thêm tất cả các tệp đối tượng từ các thư viện tĩnh vào tệp nhị phân cuối cùng. Tuy nhiên, điều này không đúng khi tạo tệp thực thi.
LOCAL_LDLIBS
Biến này chứa danh sách các cờ trình liên kết bổ sung để dùng trong việc xây dựng thư viện dùng chung hoặc tệp thực thi. Biến này cho phép bạn sử dụng tiền tố -l
để truyền tên của các thư viện hệ thống cụ thể. Ví dụ: Ví dụ sau đây yêu cầu trình liên kết tạo một mô-đun liên kết đến /system/lib/libz.so
tại thời điểm tải:
LOCAL_LDLIBS := -lz
Để biết danh sách các thư viện hệ thống hiển thị mà bạn có thể liên kết trong bản phát hành NDK này, hãy xem phần API gốc.
LOCAL_LDFLAGS
Danh sách các cờ trình liên kết khác cho hệ thống xây dựng sử dụng khi xây dựng thư viện dùng chung hoặc tệp thực thi. Ví dụ: Để sử dụng trình liên kết ld.bfd
trên ARM/X86:
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_ALLOW_UNDEFINED_SYMBOLS
Theo mặc định, khi hệ thống xây dựng gặp một tệp tham chiếu không xác định trong khi cố gắng tạo một thư viện dùng chung, hệ thống sẽ hiển thị lỗi biểu tượng không xác định. Lỗi này có thể giúp bạn tìm ra lỗi trong mã nguồn của mình.
Để tắt chế độ kiểm tra này, hãy đặt biến này thành true
. Xin lưu ý rằng chế độ cài đặt này có thể khiến thư viện dùng chung tải trong thời gian chạy.
LOCAL_ARM_MODE
Theo mặc định, hệ thống xây dựng tạo các tệp nhị phân mục tiêu ARM ở chế độ thumb, trong đó mỗi hướng dẫn rộng 16 bit và liên kết với các thư viện STL trong thư mục thumb/
. Việc xác định biến này là arm
sẽ buộc hệ thống xây dựng tạo các tệp đối tượng của mô-đun ở chế độ arm
32 bit. Ví dụ sau cho thấy cách thực hiện:
LOCAL_ARM_MODE := arm
Bạn cũng có thể hướng dẫn hệ thống xây dựng chỉ tạo các nguồn cụ thể ở chế độ arm
bằng cách thêm hậu tố .arm
vào tên tệp nguồn. Ví dụ: Ví dụ sau đây yêu cầu hệ thống xây dựng luôn biên dịch bar.c
ở chế độ ARM, nhưng tạo foo.c
theo giá trị LOCAL_ARM_MODE
.
LOCAL_SRC_FILES := foo.c bar.c.arm
LOCAL_ARM_NEON
Biến này chỉ quan trọng khi bạn đang nhắm mục tiêu đến ABI armeabi-v7a
. Biến này cho phép sử dụng hàm nội tại của trình biên dịch ARM Advanced SIMD (NEON) trong các nguồn C và C++, cũng như các hướng dẫn NEON trong tệp Assembly.
Lưu ý: Không phải tất cả các CPU dựa trên ARMv7 đều hỗ trợ đuôi tập lệnh NEON. Vì lý do này, bạn phải thực hiện việc phát hiện trong thời gian chạy để có thể sử dụng mã này một cách an toàn trong thời gian chạy. Để biết thêm thông tin, hãy xem phần Hỗ trợ Neon và các tính năng của CPU.
Ngoài ra, bạn có thể sử dụng hậu tố .neon
để chỉ định rằng hệ thống xây dựng chỉ biên dịch những tệp nguồn cụ thể có hỗ trợ NEON. Trong ví dụ sau, hệ thống xây dựng biên dịch foo.c
có hỗ trợ thump và neon, bar.c
có hỗ trợ thump và zoo.c
có hỗ trợ ARM và NEON:
LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon
Nếu bạn sử dụng cả hai hậu tố, thì .arm
phải đứng trước .neon
.
LOCAL_DISABLE_FORMAT_STRING_CHECKS
Theo mặc định, hệ thống xây dựng biên dịch mã có biện pháp bảo vệ chuỗi định dạng. Việc này sẽ buộc xảy ra lỗi trình biên dịch nếu chuỗi định dạng không phải hằng số được dùng trong hàm kiểu printf
. Biện pháp bảo vệ này được bật theo mặc định, nhưng bạn có thể tắt bằng cách đặt giá trị của biến này thành true
. Bạn không nên làm như vậy nếu không có lý do thuyết phục.
LOCAL_EXPORT_CFLAGS
Biến này ghi lại một tập hợp các cờ trình biên dịch C/C++ cần thêm vào định nghĩa LOCAL_CFLAGS
của bất kỳ mô-đun nào khác sử dụng mô-đun này thông qua các biến LOCAL_STATIC_LIBRARIES
hoặc LOCAL_SHARED_LIBRARIES
.
Ví dụ: Hãy xem xét các cặp mô-đun sau: foo
và bar
, phụ thuộc vào foo
:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
Trong trường hợp này, hệ thống xây dựng sẽ truyền các cờ -DFOO=1
và -DBAR=2
cho trình biên dịch khi tạo bar.c
. Hệ thống cũng thêm các cờ đã xuất vào LOCAL_CFLAGS
của mô-đun để bạn có thể dễ dàng ghi đè.
Ngoài ra, mối quan hệ giữa các mô-đun mang tính bắc cầu: Nếu zoo
phụ thuộc vào bar
, rồi mô-đun này phụ thuộc vào foo
, thì zoo
cũng kế thừa tất cả cờ được xuất từ foo
.
Cuối cùng, hệ thống xây dựng không sử dụng cờ được xuất khi tạo cục bộ (tức là tạo mô-đun có cờ mà hệ thống đang xuất). Do đó, trong ví dụ ở trên, hệ thống không truyền -DFOO=1
đến trình biên dịch khi tạo foo/foo.c
. Để tạo cục bộ, hãy sử dụng LOCAL_CFLAGS
.
LOCAL_EXPORT_CPPFLAGS
Biến này giống với LOCAL_EXPORT_CFLAGS
, nhưng chỉ dành cho cờ C++.
LOCAL_EXPORT_C_INCLUDES
Biến này giống với LOCAL_EXPORT_CFLAGS
, nhưng dành cho C bao gồm đường dẫn. Biến này sẽ hữu ích trong những trường hợp bar.c
cần bao gồm tiêu đề từ mô-đun foo
chẳng hạn.
LOCAL_EXPORT_LDFLAGS
Biến này giống với LOCAL_EXPORT_CFLAGS
nhưng dành cho cờ trình liên kết.
LOCAL_EXPORT_LDLIBS
Biến này giống với LOCAL_EXPORT_CFLAGS
, yêu cầu hệ thống xây dựng truyền tên thư viện hệ thống cụ thể tới trình biên dịch. Thêm -l
vào đầu tên của mỗi thư viện mà bạn chỉ định.
Lưu ý: Hệ thống xây dựng sẽ gắn cờ trình liên kết đã nhập vào giá trị của biến LOCAL_LDLIBS
trong mô-đun của bạn. Việc này được thực hiện do cách hoạt động của trình liên kết Unix.
Biến này thường hữu ích khi mô-đun foo
là một thư viện tĩnh và có mã phụ thuộc vào thư viện hệ thống. Khi đó, bạn có thể sử dụng LOCAL_EXPORT_LDLIBS
để xuất phần phụ thuộc. Ví dụ:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
Trong ví dụ này, hệ thống xây dựng đặt -llog
ở cuối lệnh trình liên kết khi tạo libbar.so
. Thao tác này sẽ cho trình liên kết biết rằng vì libbar.so
phụ thuộc vào foo
nên trình liên kết cũng phụ thuộc vào thư viện ghi nhật ký hệ thống.
LOCAL_SHORT_COMMANDS
Đặt biến này thành true
khi mô-đun của bạn có rất nhiều nguồn và/hoặc thư viện dùng chung hoặc thư viện tĩnh phụ thuộc. Cách làm này sẽ buộc hệ thống xây dựng sử dụng cú pháp @
cho các bản lưu trữ chứa tệp đối tượng trung gian hoặc liên kết thư viện.
Tính năng này có thể hữu ích trên Windows, trong đó dòng lệnh chỉ chấp nhận tối đa 8191 ký tự (con số này có thể quá nhỏ đối với các dự án phức tạp). Điều này cũng ảnh hưởng đến việc biên dịch các tệp nguồn riêng lẻ, đặt gần như tất cả cờ trình biên dịch bên trong cả các tệp danh sách.
Xin lưu ý rằng mọi giá trị không phải true
sẽ bị khôi phục về hoạt động mặc định. Bạn cũng có thể xác định APP_SHORT_COMMANDS
trong tệp Application.mk
để buộc thực hiện hoạt động này đối với mọi mô-đun trong dự án.
Bạn không nên bật tính năng này theo mặc định, vì tính năng này sẽ khiến bản dựng chậm hơn.
LOCAL_THIN_ARCHIVE
Đặt biến này thành true
khi tạo thư viện tĩnh. Cách làm này sẽ tạo ra một tệp lưu trữ mỏng, một tệp thư viện không chứa các tệp đối tượng mà chỉ chứa các đường dẫn tệp đến các đối tượng thực tế mà tệp thường chứa.
Cách này giúp giảm kích thước đầu ra của bản dựng. Điểm hạn chế là các thư viện như vậy không thể chuyển đến vị trí khác (tất cả các đường dẫn bên trong đều là tương đối).
Các giá trị hợp lệ là true
, false
hoặc để trống. Bạn có thể đặt một giá trị mặc định trong tệp Application.mk
thông qua biến APP_THIN_ARCHIVE
.
LOCAL_FILTER_ASM
Hãy xác định biến này là một lệnh shell mà hệ thống xây dựng sẽ sử dụng để lọc các tệp tập hợp được trích xuất hoặc tạo từ các tệp mà bạn chỉ định cho LOCAL_SRC_FILES
. Việc xác định biến này sẽ dẫn đến:
- Hệ thống xây dựng tạo một tệp tập hợp tạm thời từ bất kỳ tệp nguồn C hoặc C++ nào, thay vì biên dịch các tệp đó thành tệp đối tượng.
- Hệ thống xây dựng thực thi lệnh shell trong
LOCAL_FILTER_ASM
trên bất kỳ tệp tập hợp tạm thời nào và trên bất kỳ tệp tập hợp nào được liệt kê trongLOCAL_SRC_FILES
, do đó sẽ tạo một tệp tập hợp tạm thời khác. - Hệ thống xây dựng biên dịch các tệp tập hợp đã lọc này thành một tệp đối tượng.
Ví dụ:
LOCAL_SRC_FILES := foo.c bar.S
LOCAL_FILTER_ASM :=
foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o
bar.S --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o
"1" tương ứng với trình biên dịch, "2" tương ứng với bộ lọc và "3" tương ứng với trình tập hợp. Bộ lọc phải là một lệnh shell độc lập, lấy tên của tệp đầu vào làm đối số đầu tiên và tên của tệp đầu ra làm đối số thứ hai. Ví dụ:
myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S
Các macro hàm do NDK cung cấp
Phần này giải thích về các macro hàm GNU Make mà NDK cung cấp. Sử dụng $(call <function>)
để đánh giá các macro này; macro trả về thông tin văn bản.
my-dir
Macro này trả về đường dẫn của tệp makefile được bao gồm cuối cùng, thường là thư mục của Android.mk
hiện tại. my-dir
rất hữu ích khi xác định LOCAL_PATH
ở đầu tệp Android.mk
. Ví dụ:
LOCAL_PATH := $(call my-dir)
Do cách thức hoạt động của GNU Make, kết quả trả về thực sự của macro này là đường dẫn của tệp makefile cuối cùng mà hệ thống xây dựng đưa vào khi phân tích cú pháp các tập lệnh bản dựng. Vì lý do này, bạn không nên gọi my-dir
sau khi đã đưa một tệp khác vào.
Hãy xem ví dụ sau đây:
LOCAL_PATH := $(call my-dir)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(call my-dir)
# ... declare another module
Vấn đề ở đây là lệnh gọi thứ hai đến my-dir
xác định LOCAL_PATH
là $PATH/foo
thay vì $PATH
, vì đó là nơi mà lệnh include gần đây nhất trỏ đến.
Bạn có thể tránh vấn đề này bằng cách đưa lệnh include bổ sung vào sau mọi nội dung khác trong tệp Android.mk
. Ví dụ:
LOCAL_PATH := $(call my-dir)
# ... declare one module
LOCAL_PATH := $(call my-dir)
# ... declare another module
# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk
Nếu không thể định cấu trúc tệp theo cách này, hãy lưu giá trị của lệnh gọi my-dir
đầu tiên vào một biến khác. Ví dụ:
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(MY_LOCAL_PATH)
# ... declare another module
all-subdir-makefiles
Trả về danh sách các tệp Android.mk
nằm trong tất cả các thư mục con của đường dẫn my-dir
hiện tại.
Bạn có thể sử dụng hàm này để cung cấp cấu trúc phân cấp thư mục nguồn được lồng ghép sâu cho hệ thống xây dựng. Theo mặc định, NDK chỉ tìm các tệp trong thư mục chứa tệp Android.mk
.
this-makefile
Trả về đường dẫn của tệp makefile hiện tại (hệ thống xây dựng gọi hàm từ đó).
parent-makefile
Trả về đường dẫn của tệp makefile mẹ trong cây bao hàm (inclusion) (đường dẫn của tệp makefile có chứa tệp hiện tại).
grand-parent-makefile
Trả về đường dẫn của tệp makefile cấp ông bà trong cây bao hàm (đường dẫn của tệp makefile có chứa tệp hiện tại).
import-module
Một hàm cho phép bạn tìm và bao gồm tệp Android.mk
của mô-đun theo tên của mô-đun. Sau đây là ví dụ điển hình:
$(call import-module,<name>)
Trong ví dụ này, hệ thống xây dựng tìm kiếm mô-đun được gắn thẻ <name>
trong danh sách thư mục mà biến môi trường NDK_MODULE_PATH
tham chiếu và tự động bao gồm tệp Android.mk
cho bạn.