Dexpreopt และ <uses-library> checks

Android 12 มีการเปลี่ยนแปลงระบบสำหรับการรวบรวม AOT ของไฟล์ DEX (dexpreopt) สำหรับโมดูล Java ที่มีการพึ่งพา <uses-library> ในบางกรณีการเปลี่ยนแปลงระบบบิลด์เหล่านี้อาจทำให้บิลด์เสียหายได้ ใช้หน้านี้เพื่อเตรียมการแตกหัก และปฏิบัติตามสูตรในหน้านี้เพื่อแก้ไขและบรรเทา

Dexpreopt เป็นกระบวนการรวบรวมไลบรารี Java และแอพล่วงหน้า Dexpreopt เกิดขึ้นบนโฮสต์ ณ เวลาบิลด์ (ซึ่งต่างจาก dexopt ซึ่งเกิดขึ้นบนอุปกรณ์) โครงสร้างของการพึ่งพาไลบรารีที่ใช้ร่วมกันที่ใช้โดยโมดูล Java (ไลบรารีหรือแอป) เรียกว่า บริบทตัวโหลดคลาส (CLC) เพื่อรับประกันความถูกต้องของ dexpreopt CLC ของ build-time และ run-time จะต้องตรงกัน Build-time CLC คือสิ่งที่คอมไพเลอร์ dex2oat ใช้ในเวลา dexpreopt (มันถูกบันทึกไว้ในไฟล์ ODEX) และ CLC แบบรันไทม์คือบริบทที่โหลดโค้ดที่คอมไพล์ล่วงหน้าบนอุปกรณ์

CLC ของ build-time และ run-time เหล่านี้ต้องตรงกันด้วยเหตุผลของทั้งความถูกต้องและประสิทธิภาพ เพื่อความถูกต้อง จำเป็นต้องจัดการกับคลาสที่ซ้ำกัน หากการขึ้นต่อกันของไลบรารีที่แบ่งใช้ ณ รันไทม์แตกต่างจากที่ใช้สำหรับการคอมไพล์ คลาสบางคลาสอาจได้รับการแก้ไขแตกต่างกัน ทำให้เกิดบั๊กรันไทม์ที่ละเอียดอ่อน ประสิทธิภาพยังได้รับผลกระทบจากการตรวจสอบรันไทม์สำหรับคลาสที่ซ้ำกัน

กรณีการใช้งานที่ได้รับผลกระทบ

การบู๊ตครั้งแรกเป็นกรณีการใช้งานหลักที่ได้รับผลกระทบจากการเปลี่ยนแปลงเหล่านี้: หาก ART ตรวจพบว่า CLC ของ build-time และ run-time ไม่ตรงกัน มันจะปฏิเสธ dexpreopt artifact และรัน dexopt แทน สำหรับการบูทครั้งต่อๆ ไป วิธีนี้ใช้ได้ดีเพราะสามารถแยกแอปออกจากพื้นหลังและจัดเก็บไว้ในดิสก์ได้

พื้นที่ที่ได้รับผลกระทบของ Android

สิ่งนี้มีผลกับแอพและไลบรารี Java ทั้งหมดที่มีการพึ่งพารันไทม์บนไลบรารี Java อื่น Android มีแอปเป็นพันๆ แอป และมีหลายร้อยแอปที่ใช้ไลบรารีที่แชร์ พันธมิตรได้รับผลกระทบเช่นกัน เนื่องจากมีห้องสมุดและแอพเป็นของตัวเอง

ทำลายการเปลี่ยนแปลง

ระบบบิลด์จำเป็นต้องทราบการพึ่งพา <uses-library> ก่อนที่จะสร้างกฎการสร้าง dexpreopt อย่างไรก็ตาม ไม่สามารถเข้าถึงไฟล์ Manifest โดยตรงและอ่านแท็ก <uses-library> ในไฟล์ได้ เนื่องจากระบบบิลด์ไม่ได้รับอนุญาตให้อ่านไฟล์ที่กำหนดเองเมื่อสร้างกฎของบิวด์ (ด้วยเหตุผลด้านประสิทธิภาพ) นอกจากนี้ ไฟล์ Manifest อาจบรรจุอยู่ภายใน APK หรือที่สร้างไว้ล่วงหน้า ดังนั้น ข้อมูล <uses-library> จะต้องมีอยู่ในไฟล์บิลด์ ( Android.bp หรือ Android.mk )

ก่อนหน้านี้ ART ใช้วิธีแก้ปัญหาที่ละเว้นการขึ้นต่อกันของไลบรารีที่ใช้ร่วมกัน (เรียกว่า &-classpath ) การดำเนินการนี้ไม่ปลอดภัยและทำให้เกิดข้อบกพร่องเล็กๆ น้อยๆ ดังนั้นวิธีแก้ปัญหาจึงถูกลบใน Android 12

ด้วยเหตุนี้ โมดูล Java ที่ไม่ได้ให้ข้อมูล <uses-library> ที่ถูกต้องในไฟล์บิลด์อาจทำให้เกิด การแตก ของบิลด์ (เกิดจาก CLC ของ build-time ไม่ตรงกัน) หรือ การถดถอยของเวลาบูตครั้งแรก (เกิดจาก CLC เวลาบูต ไม่ตรงกันตามด้วย dexopt)

เส้นทางการย้ายถิ่น

ทำตามขั้นตอนเหล่านี้เพื่อแก้ไขบิลด์ที่เสียหาย:

  1. ปิดใช้งานการตรวจสอบเวลาสร้างสำหรับผลิตภัณฑ์เฉพาะทั่วโลกโดยการตั้งค่า

    PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true

    ใน makefile ของผลิตภัณฑ์ วิธีนี้จะแก้ไขข้อผิดพลาดของบิลด์ (ยกเว้นกรณีพิเศษ ซึ่งแสดงอยู่ในส่วน การ แก้ไขการแตกหัก ) อย่างไรก็ตาม นี่เป็นวิธีแก้ปัญหาชั่วคราว และอาจทำให้ CLC เวลาบูตไม่ตรงกันตามด้วย dexopt

  2. แก้ไขโมดูลที่ล้มเหลวก่อนที่คุณจะปิดใช้งานการตรวจสอบเวลาบิลด์ทั่วโลกโดยเพิ่มข้อมูล <uses-library> ที่จำเป็นลงในไฟล์บิลด์ (ดูรายละเอียดใน การแก้ไขการแตกหัก ) สำหรับโมดูลส่วนใหญ่ ต้องเพิ่มสองสามบรรทัดใน Android.bp หรือใน Android.mk

  3. ปิดใช้การตรวจสอบเวลาบิวด์และ dexpreopt สำหรับกรณีที่มีปัญหาตามแต่ละโมดูล ปิดใช้งาน dexpreopt เพื่อไม่ให้คุณเสียเวลาในการสร้างและการจัดเก็บบนสิ่งประดิษฐ์ที่ถูกปฏิเสธตอนบูต

  4. เปิดใช้งานการตรวจสอบเวลาสร้างใหม่ทั่วโลกโดยยกเลิกการตั้งค่า PRODUCT_BROKEN_VERIFY_USES_LIBRARIES ที่กำหนดไว้ในขั้นตอนที่ 1 บิลด์ไม่ควรล้มเหลวหลังจากการเปลี่ยนแปลงนี้ (เนื่องจากขั้นตอนที่ 2 และ 3)

  5. แก้ไขโมดูลที่คุณปิดใช้งานในขั้นตอนที่ 3 ทีละรายการ จากนั้นเปิดใช้งาน dexpreopt และการตรวจสอบ <uses-library> อีกครั้ง ไฟล์บักหากจำเป็น

การตรวจสอบเวลาบิวด์ <uses-library> บังคับใช้ใน Android 12

แก้ไขการแตกหัก

ส่วนต่อไปนี้จะบอกวิธีแก้ไขการแตกหักบางประเภท

ข้อผิดพลาดในการสร้าง: CLC ไม่ตรงกัน

ระบบบิลด์จะตรวจสอบความสอดคล้องระหว่างเวลาของบิลด์ระหว่างข้อมูลในไฟล์ Android.bp หรือ Android.mk และรายการ ระบบบิลด์ไม่สามารถอ่านรายการได้ แต่สามารถสร้างกฎการสร้างเพื่ออ่านรายการ (แยกไฟล์ออกจาก APK หากจำเป็น) และเปรียบเทียบแท็ก <uses-library> ในไฟล์ Manifest กับข้อมูล <uses-library> ใน ไฟล์บิลด์ หากการตรวจสอบล้มเหลว ข้อผิดพลาดจะมีลักษณะดังนี้:

error: mismatch in the <uses-library> tags between the build system and the manifest:
    - required libraries in build system: []
                     vs. in the manifest: [org.apache.http.legacy]
    - optional libraries in build system: []
                     vs. in the manifest: [com.x.y.z]
    - tags in the manifest (.../X_intermediates/manifest/AndroidManifest.xml):
        <uses-library android:name="com.x.y.z"/>
        <uses-library android:name="org.apache.http.legacy"/>

note: the following options are available:
    - to temporarily disable the check on command line, rebuild with RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)
    - to temporarily disable the check for the whole product, set PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles
    - to fix the check, make build system properties coherent with the manifest
    - see build/make/Changes.md for details

ตามที่ข้อความแสดงข้อผิดพลาดแนะนำ มีวิธีแก้ไขหลายอย่าง ขึ้นอยู่กับความเร่งด่วน:

  • สำหรับ โปรแกรมแก้ไขทั้งผลิตภัณฑ์ชั่วคราว ให้ตั้งค่า PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true ใน makefile ของผลิตภัณฑ์ ยังคงดำเนินการตรวจสอบความสอดคล้องกันของเวลาบิวด์ แต่การตรวจสอบล้มเหลวไม่ได้หมายความว่าบิลด์ล้มเหลว ความล้มเหลวในการตรวจสอบทำให้ระบบบิลด์ดาวน์เกรดตัวกรองคอมไพเลอร์ dex2oat เพื่อ verify ใน dexpreopt ซึ่งปิดใช้งานการรวบรวม AOT ทั้งหมดสำหรับโมดูลนี้
  • สำหรับการ แก้ไขบรรทัดคำสั่งส่วนกลางอย่างรวดเร็ว ให้ ใช้ตัวแปรสภาพแวดล้อม RELAX_USES_LIBRARY_CHECK=true มีผลเช่นเดียวกับ PRODUCT_BROKEN_VERIFY_USES_LIBRARIES แต่มีไว้สำหรับใช้ในบรรทัดคำสั่ง ตัวแปรสภาพแวดล้อมแทนที่ตัวแปรผลิตภัณฑ์
  • สำหรับวิธีแก้ปัญหาใน การแก้ไข ข้อผิดพลาด ให้ระบบบิลด์รับรู้แท็ก <uses-library> ในไฟล์ Manifest การตรวจสอบข้อความแสดงข้อผิดพลาดแสดงว่าไลบรารีใดทำให้เกิดปัญหา (เช่นเดียวกับการตรวจสอบ AndroidManifest.xml หรือรายการภายใน APK ที่สามารถตรวจสอบได้ด้วย ` aapt dump badging $APK | grep uses-library `)

สำหรับโมดูล Android.bp :

  1. ค้นหาไลบรารีที่ขาดหายไปในคุณสมบัติ libs ของโมดูล หากมี โดยปกติแล้ว Soong จะเพิ่มไลบรารีดังกล่าวโดยอัตโนมัติ ยกเว้นในกรณีพิเศษเหล่านี้:

    • ไลบรารีไม่ใช่ไลบรารี SDK (ถูกกำหนดเป็น java_library แทนที่จะเป็น java_sdk_library )
    • ไลบรารีมีชื่อไลบรารีที่แตกต่างจากชื่อโมดูล (ในระบบบิลด์)

    หากต้องการแก้ไขปัญหานี้ชั่วคราว ให้เพิ่ม provides_uses_lib: "<library-name>" ในคำจำกัดความไลบรารี Android.bp สำหรับวิธีแก้ปัญหาในระยะยาว ให้แก้ไขปัญหาพื้นฐาน: แปลงไลบรารีเป็นไลบรารี SDK หรือเปลี่ยนชื่อโมดูล

  2. หากขั้นตอนก่อนหน้านี้ไม่ได้ระบุวิธีแก้ไข ให้เพิ่ม uses_libs: ["<library-module-name>"] สำหรับไลบรารีที่ต้องการ หรือ optional_uses_libs: ["<library-module-name>"] สำหรับไลบรารีเสริมสำหรับ Android.bp คำจำกัดความ Android.bp ของโมดูล คุณสมบัติเหล่านี้ยอมรับรายชื่อโมดูล ลำดับสัมพัทธ์ของไลบรารีในรายการต้องเหมือนกับลำดับในรายการ

สำหรับโมดูล Android.mk :

  1. ตรวจสอบว่าไลบรารีมีชื่อไลบรารีที่แตกต่างจากชื่อโมดูล (ในระบบบิลด์) หรือไม่ (ในรายการ) หากเป็นเช่นนั้น ให้แก้ไขปัญหานี้ชั่วคราวโดยเพิ่ม LOCAL_PROVIDES_USES_LIBRARY := <library-name> ในไฟล์ Android.mk ของไลบรารี หรือเพิ่ม provides_uses_lib: "<library-name>" ในไฟล์ Android.bp ของไลบรารี (ทั้งสองกรณี เป็นไปได้เนื่องจากโมดูล Android.mk อาจขึ้นอยู่กับไลบรารี Android.bp ) สำหรับวิธีแก้ปัญหาในระยะยาว ให้แก้ไขปัญหาพื้นฐาน: เปลี่ยนชื่อโมดูลไลบรารี

  2. เพิ่ม LOCAL_USES_LIBRARIES := <library-module-name> สำหรับไลบรารีที่ต้องการ เพิ่ม LOCAL_OPTIONAL_USES_LIBRARIES := <library-module-name> สำหรับไลบรารีที่เป็นทางเลือกให้กับคำจำกัดความ Android.mk ของโมดูล คุณสมบัติเหล่านี้ยอมรับรายชื่อโมดูล ลำดับสัมพัทธ์ของไลบรารีในรายการต้องเหมือนกับในรายการ

ข้อผิดพลาดในการสร้าง: เส้นทางไลบรารีที่ไม่รู้จัก

หากระบบบิลด์ไม่พบพาธไปยัง <uses-library> DEX jar (ไม่ว่าจะเป็นพาธเวลาบิลด์บนโฮสต์หรือพาธการติดตั้งบนอุปกรณ์) บิลด์มักจะล้มเหลว ความล้มเหลวในการค้นหาเส้นทางสามารถบ่งชี้ว่าไลบรารีได้รับการกำหนดค่าในลักษณะที่ไม่คาดคิด แก้ไขบิลด์ชั่วคราวโดยปิดใช้งาน dexpreopt สำหรับโมดูลที่มีปัญหา

Android.bp (คุณสมบัติของโมดูล):

enforce_uses_libs: false,
dex_preopt: {
    enabled: false,
},

Android.mk (ตัวแปรโมดูล):

LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT := false

แจ้งจุดบกพร่องเพื่อตรวจสอบสถานการณ์ที่ไม่รองรับ

ข้อผิดพลาดในการสร้าง: ขาดการพึ่งพาไลบรารี

ความพยายามที่จะเพิ่ม <uses-library> X จากรายการของโมดูล Y ไปยังไฟล์บิลด์สำหรับ Y อาจส่งผลให้เกิดข้อผิดพลาดในการสร้างเนื่องจากการขึ้นต่อกันที่หายไป X

นี่เป็นข้อความแสดงข้อผิดพลาดตัวอย่างสำหรับโมดูล Android.bp:

"Y" depends on undefined module "X"

นี่เป็นข้อความแสดงข้อผิดพลาดตัวอย่างสำหรับโมดูล Android.mk:

'.../JAVA_LIBRARIES/com.android.X_intermediates/dexpreopt.config', needed by '.../APPS/Y_intermediates/enforce_uses_libraries.status', missing and no known rule to make it

แหล่งที่มาทั่วไปของข้อผิดพลาดดังกล่าวคือเมื่อตั้งชื่อไลบรารีแตกต่างจากโมดูลที่เกี่ยวข้องที่มีชื่ออยู่ในระบบบิลด์ ตัวอย่างเช่น หากรายการ <uses-library> รายการเป็น com.android.X แต่ชื่อของโมดูลไลบรารีเป็นเพียง X จะทำให้เกิดข้อผิดพลาด ในการแก้ไขกรณีนี้ ให้แจ้งระบบบิลด์ว่าโมดูลที่ชื่อ X มี <uses-library> ชื่อ com.android.X

นี่คือตัวอย่างสำหรับไลบรารี Android.bp (คุณสมบัติของโมดูล):

provides_uses_lib: “com.android.X”,

นี่คือตัวอย่างสำหรับไลบรารี Android.mk (ตัวแปรโมดูล):

LOCAL_PROVIDES_USES_LIBRARY := com.android.X

CLC เวลาบูตไม่ตรงกัน

ในการบู๊ตครั้งแรก ให้ค้นหา logcat เพื่อหาข้อความที่เกี่ยวข้องกับ CLC mismatch ดังที่แสดงด้านล่าง:

$ adb wait-for-device && adb logcat \
  | grep -E 'ClassLoaderContext [a-z ]+ mismatch' -A1

ผลลัพธ์สามารถมีข้อความของแบบฟอร์มที่แสดงที่นี่:

[...] W system_server: ClassLoaderContext shared library size mismatch Expected=..., found=... (PCL[]... | PCL[]...)
[...] I PackageDexOptimizer: Running dexopt (dexoptNeeded=1) on: ...

หากคุณได้รับคำเตือน CLC ไม่ตรงกัน ให้มองหาคำสั่ง dexopt สำหรับโมดูลที่ผิดพลาด ในการแก้ไข ตรวจสอบให้แน่ใจว่าผ่านการตรวจสอบเวลาสร้างสำหรับโมดูล หากไม่ได้ผล อาจเป็นกรณีพิเศษที่ระบบบิลด์ไม่รองรับ (เช่น แอปที่โหลด APK อื่น ไม่ใช่ไลบรารี่) ระบบบิลด์ไม่รองรับทุกกรณี เนื่องจาก ณ เวลาบิลด์ เป็นไปไม่ได้ที่จะทราบแน่ชัดว่าแอปโหลดอะไรขณะรันไทม์

บริบทตัวโหลดคลาส

CLC เป็นโครงสร้างแบบต้นไม้ที่อธิบายลำดับชั้นของตัวโหลดคลาส ระบบบิลด์ใช้ CLC ในความหมายที่แคบ (ครอบคลุมเฉพาะไลบรารี ไม่ใช่ APK หรือตัวโหลดคลาสแบบกำหนดเอง): เป็นแผนผังของไลบรารีที่แสดงถึงการปิดแบบสกรรมกริยาของการพึ่งพา <uses-library> ทั้งหมดของไลบรารีหรือแอป องค์ประกอบระดับบนสุดของ CLC คือการอ้างอิงโดยตรง <uses-library> ที่ระบุในรายการ (เส้นทางของคลาส) แต่ละโหนดของแผนผัง CLC คือโหนด <uses-library> ที่อาจมีโหนดย่อย <uses-library> ของตัวเอง

เนื่องจากการพึ่งพา <uses-library> เป็นกราฟ acyclic ที่มีทิศทางโดยตรง และไม่จำเป็นต้องเป็นแผนผัง CLC สามารถมีแผนผังย่อยได้หลายรายการสำหรับไลบรารีเดียวกัน กล่าวอีกนัยหนึ่ง CLC คือกราฟการพึ่งพา "กางออก" ไปยังต้นไม้ การทำซ้ำอยู่ในระดับตรรกะเท่านั้น ตัวโหลดคลาสพื้นฐานที่แท้จริงจะไม่ซ้ำกัน (ที่รันไทม์มีอินสแตนซ์ตัวโหลดคลาสเดียวสำหรับแต่ละไลบรารี)

CLC กำหนดลำดับการค้นหาของไลบรารีเมื่อแก้ไขคลาส Java ที่ใช้โดยไลบรารีหรือแอป ลำดับการค้นหามีความสำคัญเนื่องจากไลบรารีสามารถมีคลาสที่ซ้ำกันได้ และคลาสจะถูกแก้ไขให้ตรงกับตัวแรก

บนอุปกรณ์ (รันไทม์) CLC

PackageManager (ใน frameworks/base ) สร้าง CLC เพื่อโหลดโมดูล Java บนอุปกรณ์ มันเพิ่มไลบรารีที่แสดงอยู่ในแท็ก <uses-library> ในรายการของโมดูลเป็นองค์ประกอบ CLC ระดับบนสุด

สำหรับไลบรารีที่ใช้แต่ละรายการ PackageManager จะรับการพึ่งพา <uses-library> ทั้งหมด (ระบุเป็นแท็กในรายการของไลบรารีนั้น) และเพิ่ม CLC ที่ซ้อนกันสำหรับการพึ่งพาแต่ละรายการ กระบวนการนี้ดำเนินต่อไปแบบวนซ้ำจนกว่าโหนดปลายสุดของแผนผัง CLC ที่สร้างขึ้นเป็นไลบรารีที่ไม่มีการอ้างอิง <uses-library>

PackageManager รับรู้เฉพาะไลบรารีที่แบ่งใช้ คำจำกัดความของการแชร์ในการใช้งานนี้แตกต่างจากความหมายปกติ (เช่นเดียวกับแบบแชร์และแบบคงที่) ใน Android ไลบรารีที่ใช้ร่วมกันของ Java คือรายการในการกำหนดค่า XML ที่ติดตั้งบนอุปกรณ์ ( /system/etc/permissions/platform.xml ) แต่ละรายการประกอบด้วยชื่อของไลบรารีที่แบ่งใช้ พาธไปยังไฟล์ jar DEX และรายการการพึ่งพา (ไลบรารีที่แบ่งใช้อื่นที่ไลบรารีนี้ใช้ขณะรันไทม์ และระบุในแท็ก <uses-library> ในรายการ)

กล่าวอีกนัยหนึ่ง มีแหล่งข้อมูลสองแหล่งที่อนุญาตให้ PackageManager สร้าง CLC ขณะรันไทม์: แท็ก <uses-library> ในรายการ และการอ้างอิงไลบรารีที่ใช้ร่วมกันในการกำหนดค่า XML

บนโฮสต์ (เวลาบิลด์) CLC

CLC ไม่ได้จำเป็นเฉพาะเมื่อโหลดไลบรารี่หรือแอพเท่านั้น แต่ยังจำเป็นเมื่อทำการคอมไพล์ด้วย การคอมไพล์อาจเกิดขึ้นได้ทั้งบนอุปกรณ์ (dexopt) หรือระหว่างบิลด์ (dexpreopt) เนื่องจาก dexopt เกิดขึ้นบนอุปกรณ์ จึงมีข้อมูลเหมือนกับ PackageManager (มานิเฟสต์และการพึ่งพาไลบรารีที่ใช้ร่วมกัน) อย่างไรก็ตาม Dexpreopt เกิดขึ้นบนโฮสต์และในสภาพแวดล้อมที่แตกต่างกันโดยสิ้นเชิง และต้องได้รับข้อมูลเดียวกันจากระบบบิลด์

ดังนั้น CLC ของ build-time ที่ใช้โดย dexpreopt และ CLC แบบรันไทม์ที่ใช้โดย PackageManager เป็นสิ่งเดียวกัน แต่คำนวณในสองวิธีที่แตกต่างกัน

CLC ของเวลาบิลด์และรันไทม์ ต้อง ตรงกัน ไม่เช่นนั้นโค้ดที่คอมไพล์ AOT ที่สร้างโดย dexpreopt จะถูกปฏิเสธ ในการตรวจสอบความเท่าเทียมกันของ CLC ของ build-time และ run-time คอมไพเลอร์ dex2oat จะบันทึก CLC ของ build-time ในไฟล์ *.odex (ในฟิลด์ classpath ของส่วนหัวของไฟล์ OAT) หากต้องการค้นหา CLC ที่เก็บไว้ ให้ใช้คำสั่งนี้:

oatdump --oat-file=<FILE> | grep '^classpath = '

มีรายงานความไม่ตรงกันของ CLC ของเวลาบิลด์และรันไทม์ใน logcat ระหว่างการบู๊ต ค้นหาด้วยคำสั่งนี้:

logcat | grep -E 'ClassLoaderContext [az ]+ mismatch'

ความไม่ตรงกันเป็นผลเสียต่อประสิทธิภาพ เนื่องจากบังคับให้ไลบรารีหรือแอปต้องแยกการทำงานออก หรือเรียกใช้โดยไม่มีการเพิ่มประสิทธิภาพ (เช่น อาจต้องดึงโค้ดของแอปในหน่วยความจำจาก APK ซึ่งเป็นการดำเนินการที่มีราคาแพงมาก)

ไลบรารีที่ใช้ร่วมกันสามารถเลือกได้หรือจำเป็น จากจุดยืนของ dexpreopt ไลบรารีที่จำเป็นต้องมีอยู่ในเวลาสร้าง ไลบรารีที่เป็นทางเลือกสามารถมีอยู่หรือไม่มีอยู่ในขณะที่สร้าง: หากมี จะถูกเพิ่มไปยัง CLC ส่งต่อไปยัง dex2oat และบันทึกไว้ในไฟล์ *.odex หากไม่มีไลบรารีทางเลือก จะถูกข้ามและจะไม่ถูกเพิ่มใน CLC หากมีความไม่ตรงกันระหว่างสถานะเวลาบิลด์และรันไทม์ (ไลบรารีทางเลือกมีอยู่ในกรณีหนึ่ง แต่ไม่มีอีกกรณีหนึ่ง) CLC ของ build-time และ run-time จะไม่ตรงกันและโค้ดที่คอมไพล์แล้วจะถูกปฏิเสธ

รายละเอียดระบบบิลด์ขั้นสูง (manifest fixer)

บางครั้งแท็ก <uses-library> หายไปจากรายการแหล่งที่มาของไลบรารีหรือแอป สิ่งนี้สามารถเกิดขึ้นได้ ตัวอย่างเช่น หากการพึ่งพาสกรรมกริยาของไลบรารีหรือแอปเริ่มใช้แท็ก <uses-library> อื่น และรายการไลบรารีหรือแอปไม่ได้รับการอัปเดตเพื่อรวมไว้

Soong สามารถคำนวณแท็ก <uses-library> บางส่วนที่ขาดหายไปสำหรับไลบรารีหรือแอปที่กำหนดโดยอัตโนมัติ เนื่องจากไลบรารี SDK ในการปิดการพึ่งพาสกรรมกริยาของไลบรารีหรือแอป จำเป็นต้องปิดเนื่องจากไลบรารี (หรือแอป) อาจขึ้นอยู่กับไลบรารีสแตติกที่ขึ้นอยู่กับไลบรารี SDK และอาจขึ้นอยู่กับการถ่ายทอดผ่านไลบรารีอื่นอีกครั้ง

ไม่สามารถคำนวณแท็ก <uses-library> ทั้งหมดด้วยวิธีนี้ แต่เมื่อเป็นไปได้ ขอแนะนำให้ Soong เพิ่มรายการรายการโดยอัตโนมัติ มีโอกาสเกิดข้อผิดพลาดน้อยลงและทำให้การบำรุงรักษาง่ายขึ้น ตัวอย่างเช่น เมื่อแอปจำนวนมากใช้ไลบรารีแบบคงที่ที่เพิ่มการพึ่งพา <uses-library> ใหม่ แอปทั้งหมดจะต้องได้รับการอัปเดต ซึ่งยากต่อการดูแล