การสนับสนุนระบบบิลด์ VNDK

ใน Android 8.1 และสูงกว่า ระบบบิลด์มีการรองรับ VNDK ในตัว เมื่อเปิดใช้งานการรองรับ VNDK ระบบบิลด์จะตรวจสอบการขึ้นต่อกันระหว่างโมดูล สร้างตัวแปรเฉพาะของผู้จำหน่ายสำหรับโมดูลของผู้จำหน่าย และติดตั้งโมดูลเหล่านั้นลงในไดเร็กทอรีที่กำหนดโดยอัตโนมัติ

ตัวอย่างการสนับสนุนการสร้าง VNDK

ในตัวอย่างนี้ คำนิยามโมดูล Android.bp จะกำหนดไลบรารีชื่อ libexample คุณสมบัติ vendor_available บ่งชี้ว่าโมดูลเฟรมเวิร์กและโมดูลผู้ขายอาจขึ้นอยู่กับ libexample :

libexample vendor_available:true และ vndk.enabled:true

รูปที่ 1. เปิดใช้งานการสนับสนุน VNDK แล้ว

ทั้งเฟรมเวิร์กที่รันได้ /system/bin/foo และเวอร์จิ้นที่รันได้ /vendor/bin/bar ขึ้นอยู่กับ libexample และมี libexample ในคุณสมบัติ shared_libs

ถ้า libexample ถูกใช้โดยทั้งโมดูลเฟรมเวิร์กและโมดูลผู้จำหน่าย จะมีการสร้าง libexample สองเวอร์ชัน ตัวแปรหลัก (ตั้งชื่อตาม libexample ) ถูกใช้โดยโมดูลเฟรมเวิร์ก และตัวแปรผู้จำหน่าย (ตั้งชื่อตาม libexample.vendor ) ถูกใช้โดยโมดูลผู้ขาย ทั้งสองเวอร์ชันได้รับการติดตั้งไว้ในไดเร็กทอรีที่แตกต่างกัน:

  • มีการติดตั้งตัวแปรหลักใน /system/lib[64]/libexample.so
  • มีการติดตั้งชุดผู้จำหน่ายใน VNDK APEX เนื่องจาก vndk.enabled เป็น true

สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ คำจำกัดความของโมดูล

การกำหนดค่าการสนับสนุนบิลด์

หากต้องการเปิดใช้งานการสนับสนุนระบบแบบเต็มสำหรับอุปกรณ์ผลิตภัณฑ์ ให้เพิ่ม BOARD_VNDK_VERSION ใน BoardConfig.mk :

BOARD_VNDK_VERSION := current

การตั้งค่านี้มีผล ทั่วโลก : เมื่อกำหนดไว้ใน BoardConfig.mk โมดูลทั้งหมดจะถูกตรวจสอบ เนื่องจากไม่มีกลไกในการขึ้นบัญชีดำหรือขึ้นบัญชีขาวโมดูลที่ละเมิด คุณควรล้างการขึ้นต่อกันที่ไม่จำเป็นทั้งหมดก่อนที่จะเพิ่ม BOARD_VNDK_VERSION คุณสามารถทดสอบและคอมไพล์โมดูลโดยการตั้งค่า BOARD_VNDK_VERSION ในตัวแปรสภาพแวดล้อมของคุณ:

$ BOARD_VNDK_VERSION=current m module_name.vendor

เมื่อเปิดใช้งาน BOARD_VNDK_VERSION เส้นทางการค้นหาส่วนหัวส่วนกลางเริ่มต้นหลายเส้นทางจะ ถูกลบออก ซึ่งรวมถึง:

  • frameworks/av/include
  • frameworks/native/include
  • frameworks/native/opengl/include
  • hardware/libhardware/include
  • hardware/libhardware_legacy/include
  • hardware/ril/include
  • libnativehelper/include
  • libnativehelper/include_deprecated
  • system/core/include
  • system/media/audio/include

หากโมดูลขึ้นอยู่กับส่วนหัวจากไดเร็กทอรีเหล่านี้ คุณต้องระบุ (อย่างชัดเจน) การขึ้นต่อกันด้วย header_libs , static_libs และ/หรือ shared_libs

VNDK เอเพ็กซ์

ใน Android 10 และต่ำกว่า มีการติดตั้งโมดูลที่มี vndk.enabled ใน /system/lib[64]/vndk[-sp]-${VER} ใน Android 11 และสูงกว่า ไลบรารี VNDK ได้รับการจัดทำแพ็กเกจในรูปแบบ APEX และชื่อของ VNDK APEX คือ com.android.vndk.v${VER} ขึ้นอยู่กับการกำหนดค่าอุปกรณ์ VNDK APEX จะ ถูกทำให้เรียบ หรือ ไม่เรียบ และพร้อมใช้งานจากเส้นทางมาตรฐาน /apex/com.android.vndk.v${VER}

VNDK เอเพ็กซ์

รูปที่ 2. VNDK APEX

คำจำกัดความของโมดูล

หากต้องการสร้าง Android ด้วย BOARD_VNDK_VERSION คุณต้องแก้ไขคำจำกัดความของโมดูลใน Android.mk หรือ Android.bp ส่วนนี้จะอธิบายคำจำกัดความของโมดูลประเภทต่างๆ คุณสมบัติโมดูลที่เกี่ยวข้องกับ VNDK หลายประการ และการตรวจสอบการพึ่งพาที่นำไปใช้ในระบบบิลด์

โมดูลผู้ขาย

โมดูลของผู้จำหน่ายเป็นไฟล์ปฏิบัติการเฉพาะของผู้จำหน่ายหรือไลบรารีแบบแบ่งใช้ที่ต้องติดตั้งลงในพาร์ติชันของผู้จำหน่าย ในไฟล์ Android.bp โมดูลผู้ขายจะต้องตั้งค่าผู้ขายหรือคุณสมบัติที่เป็นกรรมสิทธิ์เป็น true ในไฟล์ Android.mk โมดูลผู้ขายจะต้องตั้งค่า LOCAL_VENDOR_MODULE หรือ LOCAL_PROPRIETARY_MODULE เป็น true

หากมีการกำหนด BOARD_VNDK_VERSION ระบบบิลด์จะไม่อนุญาตให้มีการขึ้นต่อกันระหว่างโมดูลผู้จำหน่ายและโมดูลเฟรมเวิร์ก และปล่อยข้อผิดพลาดหาก:

  • โมดูลที่ไม่มี vendor:true ขึ้นอยู่กับโมดูลที่มี vendor:true หรือ
  • โมดูลที่มี vendor:true ขึ้นอยู่กับโมดูลที่ไม่ใช่ llndk_library ที่ไม่มี vendor:true หรือ vendor_available:true

การตรวจสอบการพึ่งพามีผลกับ header_libs , static_libs และ shared_libs ใน Android.bp และกับ LOCAL_HEADER_LIBRARIES , LOCAL_STATIC_LIBRARIES และ LOCAL_SHARED_LIBRARIES ใน Android.mk

LL-NDK

ไลบรารีแบบแบ่งใช้ LL-NDK เป็นไลบรารีแบบแบ่งใช้ที่มี ABI ที่เสถียร ทั้งเฟรมเวิร์กและโมดูลผู้จำหน่ายใช้เหมือนกันและเป็นการใช้งานล่าสุด สำหรับแต่ละไลบรารีที่แบ่งใช้ LL-NDK cc_library จะมีคุณสมบัติ llndk พร้อมไฟล์สัญลักษณ์:

cc_library {
    name: "libvndksupport",
    llndk: {
        symbol_file: "libvndksupport.map.txt",
    },
}

ไฟล์สัญลักษณ์อธิบายสัญลักษณ์ที่โมดูลผู้ขายมองเห็นได้ ตัวอย่างเช่น:

LIBVNDKSUPPORT {
  global:
    android_load_sphal_library; # llndk
    android_unload_sphal_library; # llndk
  local:
    *;
};

ขึ้นอยู่กับไฟล์สัญลักษณ์ ระบบบิลด์จะสร้างไลบรารี่ที่ใช้ร่วมกัน stub สำหรับโมดูลผู้จำหน่าย ซึ่งจะเชื่อมโยงกับไลบรารีเหล่านี้เมื่อเปิดใช้งาน BOARD_VNDK_VERSION สัญลักษณ์จะรวมอยู่ในไลบรารี่ที่แชร์ stub เฉพาะในกรณีที่:

  • ไม่ได้กำหนดไว้ในส่วนที่ลงท้ายด้วย _PRIVATE หรือ _PLATFORM
  • ไม่มีแท็ก #platform-only และ
  • ไม่มีแท็ก #introduce* หรือแท็กตรงกับเป้าหมาย

ดองเวียดนาม

ในไฟล์ Android.bp คำจำกัดความของโมดูล cc_library , cc_library_static , cc_library_shared และ cc_library_headers รองรับคุณสมบัติที่เกี่ยวข้องกับ VNDK สามประการ: vendor_available , vndk.enabled และ vndk.support_system_process

หาก vendor_available หรือ vndk.enabled เป็น true อาจสร้างตัวแปรสองแบบ ( core และ vendor ) ตัวแปรหลักควรถือเป็นโมดูลกรอบงาน และตัวแปรผู้จำหน่ายควรถือเป็นโมดูลผู้ขาย หากโมดูลเฟรมเวิร์กบางตัวขึ้นอยู่กับโมดูลนี้ ตัวแปรหลักจะถูกสร้างขึ้น หากโมดูลผู้จัดจำหน่ายบางส่วนขึ้นอยู่กับโมดูลนี้ ตัวแปรผู้จัดจำหน่ายจะถูกสร้างขึ้น ระบบ build บังคับใช้การตรวจสอบการพึ่งพาต่อไปนี้:

  • ตัวแปรหลักจะเป็นแบบเฟรมเวิร์กเท่านั้นและไม่สามารถเข้าถึงได้สำหรับโมดูลของผู้จำหน่าย
  • ตัวแปรของผู้ขายไม่สามารถเข้าถึงโมดูลกรอบงานได้เสมอ
  • การขึ้นต่อกันทั้งหมดของตัวแปรผู้จำหน่าย ซึ่งระบุไว้ใน header_libs , static_libs และ/หรือ shared_libs ต้องเป็น llndk_library หรือโมดูลที่ vendor_available หรือ vndk.enabled
  • หาก vendor_available เป็น true ตัวแปรของผู้ขายจะสามารถเข้าถึงได้โดยโมดูลผู้ขายทั้งหมด
  • หาก vendor_available เป็น false รูปแบบผู้ขายจะสามารถเข้าถึงได้เฉพาะโมดูล VNDK หรือ VNDK-SP อื่นๆ เท่านั้น (เช่น โมดูลที่มี vendor:true ไม่สามารถเชื่อมโยงโมดูล vendor_available:false )

พาธการติดตั้งดีฟอลต์สำหรับ cc_library หรือ cc_library_shared ถูกกำหนดโดยกฎต่อไปนี้:

  • ตัวแปรหลักได้รับการติดตั้งไปที่ /system/lib[64]
  • เส้นทางการติดตั้งรุ่นผู้จำหน่ายอาจแตกต่างกันไป:
    • หาก vndk.enabled เป็น false ตัวแปรของผู้ขายจะถูกติดตั้งลงใน /vendor/lib[64]
    • หาก vndk.enabled เป็น true แสดงว่าเวอร์ชันของผู้จำหน่ายได้รับการติดตั้งใน VNDK APEX( com.android.vndk.v${VER} )

ตารางด้านล่างสรุปวิธีที่ระบบบิลด์จัดการตัวแปรของผู้จำหน่าย:

vendor_available vndk
เปิดใช้งาน
vndk
support_same_process
คำอธิบายตัวแปรของผู้ขาย
true false false ตัวแปรของผู้ขายคือ VND-ONLY เท่านั้น ไลบรารีแบบแบ่งใช้ถูกติดตั้งลงใน /vendor/lib[64]
true ไม่ถูกต้อง (ข้อผิดพลาดของบิลด์)
true false ตัวแปรของผู้ขายคือ VNDK ไลบรารีที่ใช้ร่วมกันได้รับการติดตั้งใน VNDK APEX
true ตัวแปรของผู้ขายคือ VNDK-SP ไลบรารีที่ใช้ร่วมกันได้รับการติดตั้งใน VNDK APEX

false

false

false

ไม่มีรูปแบบผู้ขาย โมดูลนี้เป็น FWK-ONLY เท่านั้น

true ไม่ถูกต้อง (ข้อผิดพลาดของบิลด์)
true false ตัวแปรของผู้ขายคือ VNDK-Private ไลบรารีที่ใช้ร่วมกันได้รับการติดตั้งใน VNDK APEX โมดูลผู้ขายจะต้องไม่ใช้สิ่งเหล่านี้โดยตรง
true ตัวแปรของผู้จำหน่ายคือ VNDK-SP-Private ไลบรารีที่ใช้ร่วมกันได้รับการติดตั้งใน VNDK APEX โมดูลผู้ขายจะต้องไม่ใช้สิ่งเหล่านี้โดยตรง

ส่วนขยาย VNDK

ส่วนขยาย VNDK คือไลบรารีที่ใช้ร่วมกันของ VNDK พร้อมด้วย API เพิ่มเติม ส่วนขยายได้รับการติดตั้งไปที่ /vendor/lib[64]/vndk[-sp] (โดยไม่มีส่วนต่อท้ายเวอร์ชัน) และแทนที่ไลบรารีที่แชร์ VNDK ดั้งเดิมขณะรันไทม์

การกำหนดส่วนขยาย VNDK

ใน Android 9 และสูงกว่า Android.bp รองรับส่วนขยาย VNDK โดยกำเนิด ในการสร้างส่วนขยาย VNDK ให้กำหนดโมดูลอื่นด้วย vendor:true และคุณสมบัติ extends :

cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
}

โมดูลที่มี vendor:true , vndk.enabled:true และ extends คุณสมบัติกำหนดส่วนขยาย VNDK:

  • คุณสมบัติ extends ต้องระบุชื่อไลบรารีที่ใช้ร่วมกันของ VNDK ฐาน (หรือชื่อไลบรารีที่ใช้ร่วมกันของ VNDK-SP)
  • ส่วนขยาย VNDK (หรือส่วนขยาย VNDK-SP) ได้รับการตั้งชื่อตามชื่อโมดูลฐานที่ใช้ขยาย ตัวอย่างเช่น ไบนารีเอาต์พุตของ libvndk_ext คือ libvndk.so แทนที่จะเป็น libvndk_ext.so
  • ส่วนขยาย VNDK ได้รับการติดตั้งลงใน /vendor/lib[64]/vndk
  • ส่วนขยาย VNDK-SP ได้รับการติดตั้งลงใน /vendor/lib[64]/vndk-sp
  • ไลบรารีแบบแบ่งใช้ฐานต้องมีทั้ง vndk.enabled:true และ vendor_available:true

ส่วนขยาย VNDK-SP ต้องขยายจากไลบรารีที่ใช้ร่วมกัน VNDK-SP ( vndk.support_system_process ต้องเท่ากัน):

cc_library {
    name: "libvndk_sp",
    vendor_available: true,
    vndk: {
        enabled: true,
        support_system_process: true,
    },
}

cc_library {
    name: "libvndk_sp_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk_sp",
        support_system_process: true,
    },
}

ส่วนขยาย VNDK (หรือส่วนขยาย VNDK-SP) อาจขึ้นอยู่กับไลบรารีที่ใช้ร่วมกันของผู้ขายรายอื่น:

cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
    shared_libs: [
        "libvendor",
    ],
}

cc_library {
    name: "libvendor",
    vendor: true,
}

การใช้ส่วนขยาย VNDK

หากโมดูลผู้จำหน่ายขึ้นอยู่กับ API เพิ่มเติมที่กำหนดโดยส่วนขยาย VNDK โมดูลจะต้องระบุชื่อของส่วนขยาย VNDK ในคุณสมบัติ shared_libs :

// A vendor shared library example
cc_library {
    name: "libvendor",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

// A vendor executable example
cc_binary {
    name: "vendor-example",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

หากโมดูลผู้จำหน่ายขึ้นอยู่กับส่วนขยาย VNDK ส่วนขยาย VNDK เหล่านั้นจะถูกติดตั้งไปที่ /vendor/lib[64]/vndk[-sp] โดยอัตโนมัติ หากโมดูลไม่ขึ้นอยู่กับส่วนขยาย VNDK อีกต่อไป ให้เพิ่มขั้นตอนใหม่ลงใน CleanSpec.mk เพื่อลบไลบรารีที่ใช้ร่วมกัน ตัวอย่างเช่น:

$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)

การรวบรวมแบบมีเงื่อนไข

ในส่วนนี้อธิบายวิธีจัดการกับ ความแตกต่างเล็กน้อย (เช่น การเพิ่มหรือลบคุณลักษณะออกจากเวอร์ชันใดเวอร์ชันหนึ่ง) ระหว่างไลบรารีที่ใช้ร่วมกันของ VNDK สามไลบรารีต่อไปนี้:

  • ตัวแปรหลัก (เช่น /system/lib[64]/libexample.so )
  • ตัวแปรผู้จำหน่าย (เช่น /apex/com.android.vndk.v${VER}/lib[64]/libexample.so )
  • ส่วนขยาย VNDK (เช่น /vendor/lib[64]/vndk[-sp]/libexample.so )

ธงคอมไพเลอร์แบบมีเงื่อนไข

ระบบสร้าง Android กำหนด __ANDROID_VNDK__ สำหรับตัวแปรของผู้ขายและส่วนขยาย VNDK ตามค่าเริ่มต้น คุณสามารถป้องกันโค้ดด้วยตัวป้องกันตัวประมวลผลล่วงหน้า C:

void all() { }

#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif

#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif

นอกจาก __ANDROID_VNDK__ แล้ว อาจระบุ cflags หรือ cppflags ที่แตกต่างกันใน Android.bp cflags หรือ cppflags ที่ระบุใน target.vendor เป็นค่าเฉพาะสำหรับตัวแปรของผู้จำหน่าย

ตัวอย่างเช่น Android.bp ต่อไปนี้กำหนด libexample และ libexample_ext :

cc_library {
    name: "libexample",
    srcs: ["src/example.c"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
    target: {
        vendor: {
            cflags: ["-DLIBEXAMPLE_ENABLE_VNDK=1"],
        },
    },
}

cc_library {
    name: "libexample_ext",
    srcs: ["src/example.c"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
    cflags: [
        "-DLIBEXAMPLE_ENABLE_VNDK=1",
        "-DLIBEXAMPLE_ENABLE_VNDK_EXT=1",
    ],
}

และนี่คือรายการโค้ดของ src/example.c :

void all() { }

#if !defined(LIBEXAMPLE_ENABLE_VNDK)
void framework_only() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK)
void vndk() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK_EXT)
void vndk_ext() { }
#endif

ตามไฟล์ทั้งสองนี้ ระบบบิลด์จะสร้างไลบรารีแบบแบ่งใช้โดยมีสัญลักษณ์ที่ส่งออกดังต่อไปนี้:

เส้นทางการติดตั้ง สัญลักษณ์ที่ส่งออก
/system/lib[64]/libexample.so all framework_only
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so all vndk
/vendor/lib[64]/vndk/libexample.so all , vndk , vndk_ext

ข้อกำหนดเกี่ยวกับสัญลักษณ์ที่ส่งออก

ตัวตรวจสอบ VNDK ABI จะเปรียบเทียบ ABI ของ ตัวแปรผู้ขาย VNDK และ ส่วนขยาย VNDK กับดัมพ์ ABI อ้างอิงภายใต้ prebuilts/abi-dumps/vndk

  • สัญลักษณ์ที่ส่งออกโดย ผู้จำหน่าย VNDK (เช่น /apex/com.android.vndk.v${VER}/lib[64]/libexample.so ) จะต้องเหมือนกันกับ (ไม่ใช่ superset ของ) สัญลักษณ์ที่กำหนดไว้ใน ABI dumps
  • สัญลักษณ์ที่ส่งออกโดย ส่วนขยาย VNDK (เช่น /vendor/lib[64]/vndk/libexample.so ) จะต้องเป็นชุดที่เหนือกว่าของสัญลักษณ์ที่กำหนดไว้ในดัมพ์ ABI

หาก ตัวแปรผู้จำหน่าย VNDK หรือ ส่วนขยาย VNDK ไม่ปฏิบัติตามข้อกำหนดข้างต้น ตัวตรวจสอบ VNDK ABI จะปล่อยข้อผิดพลาดในการสร้างและหยุดการสร้าง

ไม่รวมไฟล์ต้นฉบับหรือไลบรารีที่แบ่งใช้จากตัวแปรของผู้ขาย

หากต้องการยกเว้นไฟล์ต้นฉบับจากตัวแปรของผู้ขาย ให้เพิ่มไฟล์เหล่านั้นลงในคุณสมบัติ exclude_srcs ในทำนองเดียวกัน เพื่อให้แน่ใจว่าไลบรารีที่แบ่งใช้ไม่ได้เชื่อมโยงกับตัวแปรของผู้จำหน่าย ให้เพิ่มไลบรารีเหล่านั้นไปยังคุณสมบัติ exclude_shared_libs ตัวอย่างเช่น:

cc_library {
    name: "libexample_cond_exclude",
    srcs: ["fwk.c", "both.c"],
    shared_libs: ["libfwk_only", "libboth"],
    vendor_available: true,
    target: {
        vendor: {
            exclude_srcs: ["fwk.c"],
            exclude_shared_libs: ["libfwk_only"],
        },
    },
}

ในตัวอย่างนี้ ตัวแปรหลักของ libexample_cond_exclude มีโค้ดจาก fwk.c และ both.c และขึ้นอยู่กับไลบรารีที่แบ่งใช้ libfwk_only และ libboth ตัวแปรผู้จำหน่ายของ libexample_cond_exclude มีเฉพาะโค้ดจาก both.c เนื่องจาก fwk.c ถูกแยกออกโดยคุณสมบัติ exclude_srcs ในทำนองเดียวกัน ขึ้นอยู่กับเฉพาะไลบรารีที่แบ่งใช้ libboth เนื่องจาก libfwk_only ถูกแยกออกโดยคุณสมบัติ exclude_shared_libs

ส่งออกส่วนหัวจากส่วนขยาย VNDK

ส่วนขยาย VNDK อาจเพิ่มคลาสใหม่หรือฟังก์ชันใหม่ให้กับไลบรารีที่ใช้ร่วมกันของ VNDK ขอแนะนำให้เก็บการประกาศเหล่านั้นไว้ในส่วนหัวที่เป็นอิสระและหลีกเลี่ยงการเปลี่ยนส่วนหัวที่มีอยู่

ตัวอย่างเช่น ไฟล์ส่วนหัวใหม่ include-ext/example/ext/feature_name.h จะถูกสร้างขึ้นสำหรับส่วนขยาย VNDK libexample_ext :

  • Android.bp
  • รวม-ext/example/ext/feature_name.h
  • รวม/ตัวอย่าง/example.h
  • src/example.c
  • src/ext/feature_name.c

ใน Android.bp ต่อไปนี้ การส่งออก libexample include เฉพาะ ในขณะที่ libexample_ext ส่งออกทั้ง include และ include-ext สิ่งนี้ทำให้มั่นใจได้ว่าผู้ใช้ libexample จะไม่รวม feature_name.h ไม่ถูกต้อง:

cc_library {
    name: "libexample",
    srcs: ["src/example.c"],
    export_include_dirs: ["include"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libexample_ext",
    srcs: [
        "src/example.c",
        "src/ext/feature_name.c",
    ],
    export_include_dirs: [
        "include",
        "include-ext",
    ],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
}

หากไม่สามารถแยกส่วนขยายออกเป็นไฟล์ส่วนหัวอิสระได้ อีกทางเลือกหนึ่งคือเพิ่ม #ifdef guards อย่างไรก็ตาม ตรวจสอบให้แน่ใจว่าผู้ใช้ส่วนขยาย VNDK ทั้งหมดเพิ่มแฟล็กกำหนด คุณสามารถกำหนด cc_defaults เพื่อเพิ่มกำหนดธงให้กับ cflags และลิงก์ไลบรารีที่แบ่งใช้ด้วย shared_libs

ตัวอย่างเช่น หากต้องการเพิ่มฟังก์ชันสมาชิกใหม่ Example2::get_b() ให้กับส่วนขยาย VNDK libexample2_ext คุณต้องแก้ไขไฟล์ส่วนหัวที่มีอยู่และเพิ่ม #ifdef guard:

#ifndef LIBEXAMPLE2_EXAMPLE_H_
#define LIBEXAMPLE2_EXAMPLE_H_

class Example2 {
 public:
  Example2();

  void get_a();

#ifdef LIBEXAMPLE2_ENABLE_VNDK_EXT
  void get_b();
#endif

 private:
  void *impl_;
};

#endif  // LIBEXAMPLE2_EXAMPLE_H_

cc_defaults ชื่อ libexample2_ext_defaults ถูกกำหนดไว้สำหรับผู้ใช้ libexample2_ext :

cc_library {
    name: "libexample2",
    srcs: ["src/example2.cpp"],
    export_include_dirs: ["include"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libexample2_ext",
    srcs: ["src/example2.cpp"],
    export_include_dirs: ["include"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample2",
    },
    cflags: [
        "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1",
    ],
}

cc_defaults {
    name: "libexample2_ext_defaults",
    shared_libs: [
        "libexample2_ext",
    ],
    cflags: [
        "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1",
    ],
}

ผู้ใช้ libexample2_ext อาจรวม libexample2_ext_defaults ไว้ในคุณสมบัติ defaults :

cc_binary {
    name: "example2_user_executable",
    defaults: ["libexample2_ext_defaults"],
    vendor: true,
}

แพ็คเกจสินค้า

ในระบบบิลด์ Android ตัวแปร PRODUCT_PACKAGES จะระบุไฟล์ปฏิบัติการ ไลบรารีที่แบ่งใช้ หรือแพ็กเกจที่ควรติดตั้งลงในอุปกรณ์ การพึ่งพาสกรรมกริยาของโมดูลที่ระบุจะถูกติดตั้งโดยปริยายลงในอุปกรณ์เช่นกัน

หากเปิดใช้งาน BOARD_VNDK_VERSION โมดูลที่ vendor_available หรือ vndk.enabled จะได้รับการดูแลเป็นพิเศษ หากโมดูลเฟรมเวิร์กขึ้นอยู่กับโมดูลที่ vendor_available หรือ vndk.enabled ตัวแปรหลักจะรวมอยู่ในชุดการติดตั้งแบบสกรรมกริยา หากโมดูลผู้จำหน่ายขึ้นอยู่กับโมดูลที่ vendor_available ตัวแปรผู้จำหน่ายจะรวมอยู่ในชุดการติดตั้งแบบสกรรมกริยา อย่างไรก็ตาม มีการติดตั้งโมดูลผู้จำหน่ายที่มี vndk.enabled ไม่ว่าโมดูลผู้จำหน่ายจะใช้หรือไม่ก็ตาม

เมื่อระบบบิลด์มองไม่เห็นการขึ้นต่อกัน (เช่น ไลบรารีแบบแบ่งใช้ที่อาจเปิดด้วย dlopen() ในรันไทม์) คุณควรระบุชื่อโมดูลใน PRODUCT_PACKAGES เพื่อติดตั้งโมดูลเหล่านั้นอย่างชัดเจน

หากโมดูลมี vendor_available หรือ vndk.enabled ชื่อโมดูลจะย่อมาจากตัวแปรหลัก หากต้องการระบุตัวแปรของผู้ขายอย่างชัดเจนใน PRODUCT_PACKAGES ให้เพิ่มส่วนต่อท้าย .vendor ต่อท้ายชื่อโมดูล ตัวอย่างเช่น:

cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
}

ในตัวอย่างนี้ libexample ย่อมาจาก /system/lib[64]/libexample.so และ libexample.vendor ย่อมาจาก /vendor/lib[64]/libexample.so หากต้องการติดตั้ง /vendor/lib[64]/libexample.so ให้เพิ่ม libexample.vendor ใน PRODUCT_PACKAGES :

PRODUCT_PACKAGES += libexample.vendor