AOSP Foundations
3 min read

Soong Build Deep Dive

Explore advanced Soong features, including static dependencies, reusable defaults modules, and visibility rules.

While Android.bp syntax is strictly declarative and designed to be simple, the immense scale of the AOSP source tree requires advanced mechanisms to prevent code duplication, enforce security, and manage massive, multi-tiered dependency chains.

Dependency Management

In Soong, you do not manually tell the compiler which .so file to link against using command-line flags. Instead, you declare dependencies by referencing the name of other modules. Soong automatically figures out the correct compiler and linker flags for you.

  • shared_libs: The module requires a dynamically linked .so library.
  • static_libs: The module requires a statically linked .a library, and the compiled binary code will be embedded directly into the output.
  • header_libs: The module only needs the C++ header .h files from another module to compile, but no actual compiled library code.
cc_binary {
    name: "my_camera_daemon",
    srcs: ["daemon.cpp"],
    shared_libs: ["libcamera_metadata"],
    static_libs: ["libmath_custom"],
}

Reusable Build Rules (defaults)

Often, you have dozens of modules that share the exact same compiler flags, include directories, or dependencies. To avoid repeating yourself in every single module definition, Blueprint provides defaults modules.

// 1. Define the reusable rules
cc_defaults {
    name: "my_company_standard_flags",
    cflags: [
        "-Wall",
        "-Werror",
        "-O3",
    ],
    shared_libs: ["liblog"],
}

// 2. Apply the defaults to a real module
cc_binary {
    name: "app_one",
    defaults: ["my_company_standard_flags"],
    srcs: ["app1.cpp"],
}

Any property defined in the defaults module is automatically inherited by the module that includes it.

Visibility and Security

By default, any module in the AOSP tree can link against any other module. For massive codebases, this is an architectural nightmare.

You might write a highly sensitive cryptographic library and only want a specific authentication daemon to use it. You can restrict access using the visibility property.

cc_library {
    name: "libsecret_crypto",
    srcs: ["crypto.cpp"],
    visibility: [
        "//system/security/auth_daemon",
    ],
}

If an app in packages/apps/Settings tries to add libsecret_crypto to its shared_libs, the Soong parser will throw a fatal error before compilation even begins.

Soong vs. Makefile Conversion

Because AOSP still contains legacy Android.mk files, it is crucial to understand how the two systems interact.

  • Soong to Make: An Android.bp module can easily depend on an Android.mk module. Soong and Kati work together to resolve the dependency automatically in the Ninja graph.
  • Make to Soong: An Android.mk module can also safely depend on an Android.bp module.
# You can use a helpful AOSP script to attempt to auto-convert an Android.mk file to Android.bp
androidmk Android.mk > Android.bp