Zalo Inbox

Hướng Dẫn Chi Tiết về Android.bp và Soong Build System trong AOSP (1)


  • author-image

    devlinux

  • blog-tag aosp, aaos
  • blog-comment 0 Bình luận
  • blog-comment 39 Views
  • created-date 17 Feb, 2025
blog-image


Bài viết này cung cấp kiến thức chuyên sâu về Android.bpSoong Build System trong Android Open Source Project (AOSP), bao gồm:

  • Giới thiệu Android.bp và hệ thống build Soong.
  • Phân tích cấu trúc và cách làm việc của Android.bp.
  • Thực hành tạo module mới với Android.bp.
  • Hướng dẫn build và debug trong AOSP.

1. Giới thiệu Android.bp và Soong

1.1. Hệ thống Build trong AOSP: Makefile vs. Soong

Trong các phiên bản AOSP cũ, Android.mk (dựa trên GNU Make) là công cụ build chính. Tuy nhiên, với sự phát triển của dự án, các hạn chế của Makefile dần lộ rõ:

  • Quản lý khó khăn: Các Makefile lớn dễ bị lỗi và khó bảo trì.
  • Hiệu suất thấp: Makefile xử lý lặp không hiệu quả với các dự án lớn.
  • Tệp cấu hình: Android.mk

Để khắc phục, Google đã giới thiệu Soong, một hệ thống build hiện đại, dựa trên Blueprint, giúp:

  • Dễ dàng mở rộng và bảo trì.
  • Cải thiện hiệu suất bằng việc sử dụng ninja.
  • Tệp cấu hình: Android.bp được giới thiệu từ Android 7.0.

1.2. Android.bp là gì?

Android.bp là tệp cấu hình module trong Soong, tương tự như Android.mk nhưng có cú pháp rõ ràng hơn, dạng JSON-like. Các tệp này định nghĩa các bước cần thiết để biên dịch, liên kết, và đóng gói module trong AOSP.

1.3. So sánh Android.bp và Android.mk

Đặc điểm Android.mk Android.bp
Cú pháp GNU Make JSON-like (Blueprint DSL)
Tính dễ đọc Khó với dự án lớn Dễ đọc và dễ hiểu
Công cụ build make ninja và soong_build
Khả năng mở rộng Giới hạn Dễ mở rộng

1.4. Ví dụ: Phân tích tệp Android.bp

cc_library_shared {
    name: "example_lib",
    srcs: ["example.cpp"],
    shared_libs: ["libc", "libm"],
    include_dirs: ["include"],
}

Giải thích:

  • cc_library_shared: Định nghĩa một thư viện chia sẻ (shared library).
  • name: Tên của module (example_lib).
  • srcs: Danh sách file nguồn để build.
  • shared_libs: Thư viện cần liên kết.
  • include_dirs: Các thư mục chứa file header.

2. Cấu trúc tệp Android.bp

2.1. Tổng quan

Tệp Android.bp được chia thành các module, mỗi module đại diện cho một thành phần trong dự án như thư viện, chương trình thực thi, hoặc tài nguyên.

2.1.1. Các loại module phổ biến

  • cc_binary: Xây dựng chương trình thực thi từ mã C/C++.
  • cc_library_shared: Tạo thư viện chia sẻ (shared library).
  • java_library: Tạo thư viện Java.
  • prebuilt_binary: Sử dụng các file nhị phân có sẵn.

2.1.2. Các thông tin cơ bản trong một module

Trường Mô tả
name Tên module, được sử dụng khi build hoặc liên kết.
srcs Danh sách file nguồn.
deps Các module phụ thuộc.
include_dirs Các thư mục chứa file header cần thiết.

**2.2. Nâng cao **

2.2.1. Default

Cho phép định nghĩa các giá trị chung cho nhiều module.

cc_defaults {
    name: "example_defaults",
    include_dirs: ["common/include"],
}

cc_binary {
    name: "example_binary",
    defaults: ["example_defaults"],
    srcs: ["main.cpp"],
}

2.2.2. Prebuilt

Sử dụng file nhị phân có sẵn thay vì biên dịch.

prebuilt_binary {
    name: "prebuilt_tool",
    srcs: ["tool_binary"],
}

2.2.3 Blueprint Variables

Biến để tái sử dụng cấu hình.

cc_binary {
    name: "example_binary",
    srcs: ["main.cpp"],
    cflags: ["-DDEBUG"],
}

3. Các bước tạo module mới

3.1. Tạo thư mục dự án

Để bắt đầu, cần chuẩn bị môi trường và tạo thư mục chứa mã nguồn cho module mới. Di chuyển đến thư mục mã nguồn của Android và hiện các bước sau:

mkdir -p external/helloworld
cd external/helloworld

3.2. Viết mã nguồn

Viết mã nguồn bằng C++ hoặc Java cho module của bạn. Dưới đây là một ví dụ đơn giản với C++:

hello_world.cpp

#include <iostream>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

3.3. Tạo tệp Android.bp

Tạo một tệp Android.bp trong thư mục dự án. Đây là cấu hình build cho module.

Android.bp

cc_binary {
    name: "hello_world",
    srcs: ["hello_world.cpp"],
}

Tệp trên định nghĩa một binary module hello_world, sử dụng mã nguồn từ hello_world.cpp.

3.4. Build và Debug

3.4.1. Thiết lập môi trường build

Trước khi build module, cần thiết lập môi trường build của AOSP.

source build/envsetup.sh
lunch aosp_rpi4_car-ap3a-userdebug

3.4.2. Build module

Thực hiện build module hello_world bằng lệnh.

m hello_world

3.4.3. Kiểm tra kết quả

Sau khi build thành công, module sẽ được đặt tại vị trí:

out/target/product/<target>/system/bin/hello_world

3.4.4. Debug lỗi Android.bp

3.4.4.1. Thiếu file mã nguồn

Log lỗi:

error: cannot find source file: hello_world.cpp
  • Nguyên nhân: Đường dẫn trong trường srcs không đúng hoặc file mã nguồn không tồn tại.
  • Giải pháp: Kiểm tra và sửa lại đường dẫn trong tệp Android.bp

Android.bp

cc_binary {
    name: "hello_world",
    srcs: ["correct_path/hello_world.cpp"]
}

3.4.4.2. Thiếu thư viện phụ thuộc

Log lỗi:

error: undefined reference to `some_function`
  • Nguyên nhân: Module thiếu thư viện phụ thuộc.
  • Giải pháp: Thêm thư viện vào trường shared_libs hoặc static_libs.

Android.bp

cc_binary {
    name: "hello_world",
    srcs: ["hello_world.cpp"],
    shared_libs: ["libdependency"],
}

3.4.4.3. Lỗi cú pháp

Log lỗi:

error: Android.bp: invalid field name
  • Nguyên nhân: Sử dụng tên trường không hợp lệ hoặc thiếu dấu ngoặc.
  • Giải pháp: Đảm bảo cấu trúc tệp Android.bp tuân theo cú pháp chuẩn của Blueprint.
author_photo
devlinux

0 Bình luận