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

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

ตัวอย่างการสนับสนุนบิลด์ของ VNDK

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

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

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

ทั้ง /system/bin/foo และผู้ให้บริการเฟรมเวิร์กที่เรียกใช้ได้ /vendor/bin/bar ที่ดำเนินการได้ขึ้นอยู่กับ libexample และ มี libexample ในพร็อพเพอร์ตี้ shared_libs

หากใช้ libexample โดยทั้งโมดูลเฟรมเวิร์กและผู้ให้บริการ มีการสร้างโมดูล 2 ตัวแปรของ 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 เลือกโมดูลทั้งหมดแล้ว เนื่องจากไม่มีกลไก ขึ้นบัญชีดำหรืออนุญาตพิเศษโมดูลที่ไม่เหมาะสม คุณควรล้างทั้งหมด ทรัพยากร Dependency ที่ไม่จำเป็นก่อนเพิ่ม 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

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

เวียดนาม

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

เวียดนาม

รูปที่ 2 VNDK APEX

การกำหนดโมดูล

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

โมดูลของผู้ให้บริการ

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

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

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

การตรวจสอบทรัพยากร Dependency มีผลกับ header_libs static_libs และ shared_libs นิ้ว Android.bp และถึง LOCAL_HEADER_LIBRARIES LOCAL_STATIC_LIBRARIES และ LOCAL_SHARED_LIBRARIES ใน Android.mk

LL-NDK

ไลบรารีที่ใช้ร่วมกัน LL-NDK คือไลบรารีที่ใช้ร่วมกันซึ่งมี ABI ที่เสถียร ทั้ง 2 เฟรมเวิร์ก และโมดูลของผู้ให้บริการเดียวกันและมีการใช้งานล่าสุด สำหรับแต่ละรายการ ไลบรารีที่ใช้ร่วมกัน 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:
    *;
};

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

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

ดองเวียดนาม

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

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

  • ตัวแปรหลักจะใช้ได้เพียงเฟรมเวิร์กเท่านั้นและผู้ให้บริการไม่สามารถเข้าถึงได้ โมดูล
  • โมดูลเฟรมเวิร์กจะเข้าถึงตัวแปรของผู้ให้บริการไม่ได้เสมอไป
  • ทรัพยากร Dependency ทั้งหมดของตัวแปรผู้ให้บริการ ตามที่ระบุไว้ใน 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 เท่านั้น ไลบรารีที่แชร์ ได้แก่ ติดตั้งใน /vendor/lib[64] แล้ว
true ไม่ถูกต้อง (ข้อผิดพลาดของรุ่น)
true false รายละเอียดปลีกย่อยของผู้ให้บริการคือ VNDK ติดตั้งไลบรารีที่แชร์แล้ว เป็น VNDK APEX
true รายละเอียดปลีกย่อยของผู้ให้บริการคือ VNDK-SP ไลบรารีที่แชร์ ได้แก่ ที่ติดตั้งไปยัง VNDK APEX

false

false

false

ไม่มีผลิตภัณฑ์ย่อยของผู้ให้บริการ โมดูลนี้สำหรับ FWK เท่านั้น

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)

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

หัวข้อนี้จะอธิบายวิธีจัดการกับความแตกต่างเล็กน้อย (เช่น เพิ่มหรือนำฟีเจอร์ออกจากตัวแปรใดตัวแปรหนึ่ง) ระหว่างตัวเลือกต่อไปนี้ ไลบรารีที่ใช้ร่วมกัน 3 รายการของ 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) ต้องเหมือนกัน กับ (ไม่ใช่ซูเปอร์เซ็ตของ) สัญลักษณ์ที่กำหนดไว้ในดัมพ์ ABI
  • สัญลักษณ์ที่ส่งออกโดยส่วนขยาย 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
  • include-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 วิธีนี้ช่วยให้มั่นใจว่า ผู้ใช้ของ จะไม่รวม feature_name.h อย่างไม่ถูกต้อง libexample:

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 แต่อย่าลืมดูให้แน่ใจว่า ผู้ใช้ส่วนขยาย VNDK จะเพิ่มค่าสถานะกำหนด คุณอาจระบุ cc_defaults เพื่อเพิ่มการกำหนดแฟล็กใน cflags และลิงก์ คลังภาพที่แชร์กับ shared_libs

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

#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 ระบุไฟล์ปฏิบัติการ ไลบรารีที่ใช้ร่วมกัน หรือแพ็กเกจที่ควร ติดตั้งไว้ในอุปกรณ์ ทรัพยากร Dependency แบบทรานซิทีฟของข้อมูลที่ระบุ โดยโมดูลจะติดตั้งในอุปกรณ์โดยปริยายเช่นกัน

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

เมื่อระบบมองไม่เห็นทรัพยากร Dependency ในระบบบิลด์ (เช่น ไลบรารีที่แชร์) ที่อาจเปิดด้วย 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