Enabling the VNDK

The VNDK requires several changes to a codebase to separate concerns between vendor and system. Use the following guide to enable VNDK in a vendor/OEM codebase.

Build system libraries

The build system contains several types of objects including libraries (shared, static, or header) and binaries.

Build system libraries
Figure 1. Build system libraries
  • core libraries are used by the system image, on the system image. These libraries can't be used by vendor, vendor_available, vndk, or vndk-sp libraries.
    cc_library {
        name: "libThatIsCore",
        ...
    }
    
  • vendor-only (or proprietary) libraries are used by the vendor image, on the vendor image.
    cc_library {
        name: "libThatIsVendorOnly",
        proprietary: true,
        # or: vendor: true, # (for things in AOSP)
        ...
    }
    
  • vendor_available libraries are used by the vendor image, on the vendor image (may contain duplicates of core).
    cc_library {
        name: "libThatIsVendorAvailable",
        vendor_available: true,
        ...
    }
    
  • vndk libraries are used by the vendor image, on the system image.
    cc_library {
        name: "libThatIsVndk",
        vendor_available: true,
        vndk: {
            enabled: true,
        }
        ...
    }
    
  • vndk-sp libraries are used by the vendor image, and also by the system image indirectly.
    cc_library {
        name: "libThatIsVndkSp",
        vendor_available: true,
        vndk: {
            enabled: true,
            support_system_process: true,
        }
        ...
    }
    
  • llndk libraries are used by both the system and vendor images.
    cc_library {
        name: "libThatIsLlndk",
        llndk: {
            symbol_file: "libthatisllndk.map.txt"
        }
        ...
    }
    

When a lib is marked as vendor_available:true, it's built twice:

  • Once for platform (and thus installed to /system/lib)
  • Once for vendor (and thus installed to /vendor/lib or VNDK APEX)

The vendor versions of libs are built with -D__ANDROID_VNDK__. Private system components that may change significantly in future versions of Android are disabled with this flag. In addition, different libraries export a different set of headers (such as liblog). Options specific to a vendor variant of a target can be specified in an Android.bp file in:

target: { vendor: { … } }

Enabling VNDK for a codebase

To enable the VNDK for a codebase:

  1. Determine eligibility by calculating the required sizes of vendor.img and system.img partitions.
  2. Enable BOARD_VNDK_VERSION=current. You can add to BoardConfig.mk or build components with it directly (for example, m -j BOARD_VNDK_VERSION=current MY-LIB).

After enabling BOARD_VNDK_VERSION=current, the build system enforces the following dependency and header requirements.

Managing dependencies

A vendor object that depends on a core component that doesn't exist in vndk or as a vendor object must be resolved using one of the following options:

  • The dependency can be removed.
  • If the core component is owned by vendor, it can be marked as vendor_available or vendor.
  • A change making the core object part of the vndk may be upstreamed to Google.

In addition, if a core component has dependencies on a vendor component, the vendor component must be made into a core component or the dependency must be removed in another way (for example, by removing the dependency or by moving the dependency into a vendor component).

Managing headers

Global header dependencies must be removed to enable the build system to know whether to build the headers with or without -D__ANDROID_VNDK__. For example, libutils headers such as utils/StrongPointer.h can still be accessed using the header library libutils_headers.

Some headers (such as unistd.h) can no longer be included transitively but can be included locally.

Finally, the public part of private/android_filesystem_config.h has been moved to cutils/android_filesystem_config.h. To manage these headers, do one of the following:

  • Remove the dependency to private/android_filesystem_config.h by replacing all AID_* macros with getgrnam/ getpwnam calls if possible. For example:
    • (uid_t)AID_WIFI becomes getpwnam("wifi")->pw_uid.
    • (gid_t)AID_SDCARD_R becomes getgrnam("sdcard_r")->gr_gid.
    For details, refer to private/android_filesystem_config.h.
  • For hard-coded AIS, include cutils/android_filesystem_config.h.