ไฟล์ Android.bp ได้รับการออกแบบมาให้ใช้งานง่าย โดยไม่มีคำสั่งแบบมีเงื่อนไขหรือคำสั่งควบคุมโฟลว์ และตรรกะการบิลด์ที่ซับซ้อนทั้งหมดจะได้รับการจัดการโดยตรรกะการบิลด์ที่เขียนด้วยภาษา Go
โมดูล
โมดูลในไฟล์ Android.bp จะเริ่มต้นด้วยประเภทโมดูล ตามด้วยชุด
พร็อพเพอร์ตี้ใน name: "value", ดังนี้
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
ทุกโมดูลต้องมีพร็อพเพอร์ตี้ name และค่าต้องไม่ซ้ำกันในไฟล์ Android.bp ทั้งหมด ยกเว้นค่าพร็อพเพอร์ตี้ name ในเนมสเปซและโมดูลที่สร้างไว้ล่วงหน้า ซึ่งอาจซ้ำกันได้
พร็อพเพอร์ตี้ srcs จะระบุไฟล์แหล่งที่มาที่ใช้สร้างโมดูลเป็นรายการสตริง คุณอ้างอิงเอาต์พุตของโมดูลอื่นๆ ที่สร้าง
ไฟล์แหล่งที่มา เช่น genrule หรือ filegroup ได้โดยใช้ไวยากรณ์การอ้างอิงโมดูล
":<module-name>"
ดูรายการประเภทโมดูลที่ถูกต้องและพร็อพเพอร์ตี้ของโมดูลได้ในข้อมูลอ้างอิงโมดูล Soong ที่สร้างขึ้นโดยการเรียกใช้ m soong_docs เอาต์พุตจะอยู่ใน out/soong/docs/soong_build.html
ประเภท
ตัวแปรและพร็อพเพอร์ตี้เป็นแบบกำหนดประเภทอย่างเข้มงวด โดยตัวแปรจะกำหนดประเภทแบบไดนามิกตามการกำหนดค่าครั้งแรก และพร็อพเพอร์ตี้จะกำหนดประเภทแบบคงที่ตามประเภทโมดูล ประเภทที่รองรับมีดังนี้
- บูลีน (
trueหรือfalse) - จำนวนเต็ม (
int) - สตริง (
"string") - รายการสตริง (
["string1", "string2"]) - แมป (
{key1: "value1", key2: ["value2"]})
แมปอาจมีค่าเป็นประเภทใดก็ได้ รวมถึงแมปที่ซ้อนกัน รายการและแมปอาจมีคอมมาต่อท้ายหลังจากค่าสุดท้าย
Globs
พร็อพเพอร์ตี้ที่ใช้รายการไฟล์ เช่น srcs สามารถใช้รูปแบบ Glob ได้ด้วย รูปแบบ Glob สามารถมีสัญลักษณ์แทน * ปกติของ UNIX เช่น
*.java นอกจากนี้ รูปแบบ Glob ยังมีสัญลักษณ์แทน ** เดียวเป็นองค์ประกอบเส้นทาง ซึ่งจะตรงกับองค์ประกอบเส้นทางตั้งแต่ 0 รายการขึ้นไป เช่น java/**/*.java จะตรงกับทั้งรูปแบบ java/Main.java และ java/com/android/Main.java
ตัวแปร
ไฟล์ Android.bp อาจมีการกำหนดค่าตัวแปรระดับบนสุดดังนี้
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
ตัวแปรจะมีขอบเขตเป็นส่วนที่เหลือของไฟล์ที่ประกาศไว้ รวมถึงไฟล์ Blueprint ย่อย ตัวแปรจะเปลี่ยนแปลงไม่ได้ ยกเว้นกรณีที่สามารถเพิ่มตัวแปรได้ด้วยการกำหนดค่า += แต่จะทำได้ก็ต่อเมื่อยังไม่มีการอ้างอิงตัวแปร
ความคิดเห็น
ไฟล์ Android.bp สามารถมีความคิดเห็นหลายบรรทัดในรูปแบบ C /* */ และความคิดเห็นบรรทัดเดียวในรูปแบบ C++ //
โอเปอเรเตอร์
คุณสามารถเพิ่มสตริง รายการสตริง และแมปได้โดยใช้โอเปอเรเตอร์ +
และสามารถรวมจำนวนเต็มได้โดยใช้โอเปอเรเตอร์ + การเพิ่มแมปจะสร้างการรวมคีย์ในแมปทั้ง 2 รายการ และเพิ่มค่าของคีย์ที่มีอยู่ในแมปทั้ง 2 รายการ
โมดูลค่าเริ่มต้น
นักพัฒนาแอปสามารถใช้โมดูลค่าเริ่มต้น เพื่อทำซ้ำพร็อพเพอร์ตี้เดียวกันในหลายโมดูลได้ เช่น
cc_defaults {
name: "gzip_defaults",
shared_libs: ["libz"],
stl: "none",
}
cc_binary {
name: "gzip",
defaults: ["gzip_defaults"],
srcs: ["src/test/minigzip.c"],
}
โมดูลที่สร้างไว้ล่วงหน้า
โมดูลที่สร้างไว้ล่วงหน้าบางประเภทอนุญาตให้โมดูลมีชื่อเดียวกับโมดูลที่อิงตามแหล่งที่มา เช่น อาจมี cc_prebuilt_binary ชื่อ foo เมื่อมี cc_binary ที่มีชื่อเดียวกันอยู่แล้ว ซึ่งช่วยให้นักพัฒนาแอปมีความยืดหยุ่นในการเลือกเวอร์ชันที่จะรวมไว้ในผลิตภัณฑ์ขั้นสุดท้าย หากการกำหนดค่าบิลด์มีทั้ง 2 เวอร์ชัน ค่าแฟล็ก prefer ในคำจำกัดความของโมดูลที่สร้างไว้ล่วงหน้าจะเป็นตัวกำหนดเวอร์ชันที่มีลำดับความสำคัญ
โปรดทราบว่าโมดูลที่สร้างไว้ล่วงหน้าบางโมดูลมีชื่อที่ไม่ขึ้นต้นด้วย prebuilt เช่น android_app_import
โมดูลเนมสเปซ
จนกว่า Android จะเปลี่ยนจาก Make เป็น Soong อย่างสมบูรณ์ การกำหนดค่าผลิตภัณฑ์ Make ต้องระบุค่า PRODUCT_SOONG_NAMESPACES ค่าดังกล่าวควรเป็นรายการเนมสเปซที่คั่นด้วยช่องว่าง ซึ่ง Soong จะส่งออกไปยัง Make เพื่อให้คำสั่ง m สร้าง หลังจากที่ Android เปลี่ยนเป็น Soong อย่างสมบูรณ์แล้ว รายละเอียดของการเปิดใช้เนมสเปซอาจมีการเปลี่ยนแปลง
Soong ช่วยให้โมดูลในไดเรกทอรีต่างๆ ระบุชื่อเดียวกันได้ ตราบใดที่โมดูลแต่ละโมดูลประกาศไว้ในเนมสเปซแยกกัน นักพัฒนาแอปสามารถประกาศเนมสเปซได้ดังนี้
soong_namespace {
imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}
โปรดทราบว่าเนมสเปซไม่มีพร็อพเพอร์ตี้ name ระบบจะกำหนดเส้นทางเป็นชื่อโดยอัตโนมัติ
ระบบจะกำหนดเนมสเปซให้กับโมดูล Soong แต่ละโมดูลตามตำแหน่งในโครงสร้าง
โมดูล Soong แต่ละโมดูลจะถือว่าอยู่ในเนมสเปซที่กำหนดโดย soong_namespace ที่พบในไฟล์ Android.bp ในไดเรกทอรีปัจจุบันหรือไดเรกทอรีระดับบนสุดที่ใกล้ที่สุด หากไม่พบโมดูล soong_namespace ดังกล่าว โมดูลจะถือว่าอยู่ในเนมสเปซรูทโดยนัย
ตัวอย่างเช่น Soong พยายามแก้ปัญหาทรัพยากร Dependency D ที่ประกาศโดยโมดูล M ในเนมสเปซ N ซึ่งนำเข้าเนมสเปซ I1, I2, I3…
- จากนั้นหาก D เป็นชื่อที่สมบูรณ์ในตัวเองในรูปแบบ
//namespace:moduleระบบจะค้นหาเฉพาะเนมสเปซที่ระบุสำหรับชื่อโมดูลที่ระบุ - ไม่เช่นนั้น Soong จะค้นหาโมดูลชื่อ D ที่ประกาศไว้ในเนมสเปซ N ก่อน
- หากโมดูลดังกล่าวไม่มีอยู่ Soong จะค้นหาโมดูลชื่อ D ในเนมสเปซ I1, I2, I3…
- Soong จะค้นหาในเนมสเปซรูท
คำสั่งแบบมีเงื่อนไข
Soong ไม่รองรับคำสั่งแบบมีเงื่อนไขในไฟล์ Android.bp แต่จะจัดการความซับซ้อนในกฎการบิลด์ที่ต้องใช้คำสั่งแบบมีเงื่อนไขใน Go ซึ่งสามารถใช้ฟีเจอร์ภาษาขั้นสูงและติดตามการขึ้นต่อกันโดยนัยที่เกิดจากคำสั่งแบบมีเงื่อนไขได้ คำสั่งแบบมีเงื่อนไขส่วนใหญ่จะแปลงเป็นพร็อพเพอร์ตี้แมป โดยระบบจะเลือกค่าใดค่าหนึ่งในแมปและเพิ่มค่าดังกล่าวลงในพร็อพเพอร์ตี้ระดับบนสุด
ตัวอย่างเช่น หากต้องการรองรับไฟล์เฉพาะสถาปัตยกรรม ให้ทำดังนี้
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
ตัวจัดรูปแบบ
Soong มีตัวจัดรูปแบบมาตรฐานสำหรับไฟล์ Blueprint ซึ่งคล้ายกับ
gofmt หากต้องการจัดรูปแบบไฟล์ Android.bp ทั้งหมดในไดเรกทอรีปัจจุบันแบบเรียกซ้ำ ให้เรียกใช้คำสั่งต่อไปนี้
bpfmt -w .
รูปแบบมาตรฐานประกอบด้วยการเยื้อง 4 ช่องว่าง บรรทัดใหม่หลังองค์ประกอบทุกรายการในรายการที่มีหลายองค์ประกอบ และคอมมาต่อท้ายในรายการและแมป