Android.mk

Trang này mô tả cú pháp của tệp bản dựng Android.mkndk-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_FILESLOCAL_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ặc APP. 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_MODULELOCAL_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_MODULELOCAL_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_LIBRARIESLOCAL_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_LIBRARYBUILD_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_ABIall, 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ợ.

Bảng 1. Các chế độ cài đặt ABI cho những cấu trúc và CPU khác nhau.

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:

  1. 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.
  2. Chỉ định giá trị cho các biến dùng để mô tả mô-đun.
  3. 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.mkApplication.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_MODULEfoo, 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-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.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ợ Neoncá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: foobar, 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-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:

  1. 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.
  2. 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ê trong LOCAL_SRC_FILES, do đó sẽ tạo một tệp tập hợp tạm thời khác.
  3. 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$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.