Android mk

หน้านี้อธิบายไวยากรณ์ของไฟล์บิลด์ Android.mk ที่ใช้โดย ndk-build

ภาพรวม

ไฟล์ Android.mk อยู่ในไดเรกทอรีย่อย jni/ ของโปรเจ็กต์ และอธิบายแหล่งที่มาและไลบรารีที่แชร์ไปยังระบบบิลด์ นี่เป็นส่วนย่อยของไฟล์ GNU ขนาดเล็กที่ระบบบิลด์จะแยกวิเคราะห์เพียงครั้งเดียวหรือ และอีกมากมาย ไฟล์ Android.mk มีประโยชน์สำหรับการกำหนดการตั้งค่าของทั้งโปรเจ็กต์ที่ Application.mk ระบบบิลด์ และตัวแปรสภาพแวดล้อมจะปล่อยไว้ ไม่ได้กำหนด นอกจากนี้ยังลบล้างการตั้งค่าของทั้งโปรเจ็กต์สำหรับโมดูลที่เจาะจงได้ด้วย

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

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

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

ข้อมูลเบื้องต้น

ก่อนศึกษารายละเอียดไวยากรณ์ ควรเริ่มต้นด้วยการทำความเข้าใจ ข้อมูลพื้นฐานในไฟล์ Android.mk ส่วนนี้ใช้เมธอด Android.mk ในตัวอย่าง Hello-JNI ในด้านนั้น โดยอธิบายบทบาท แต่ละบรรทัดในไฟล์จะเล่น

ไฟล์ Android.mk ต้องเริ่มต้นด้วยการกำหนดตัวแปร LOCAL_PATH ดังนี้

LOCAL_PATH := $(call my-dir)

ตัวแปรนี้ระบุตำแหน่งของไฟล์ต้นฉบับในการพัฒนา ต้นไม้ ในที่นี้ ฟังก์ชันมาโคร my-dir ซึ่งมาจากระบบบิลด์ จะส่งคืน เส้นทางของไดเรกทอรีปัจจุบัน (ไดเรกทอรีที่มี Android.mk โดยตรง)

บรรทัดถัดไปจะประกาศตัวแปร CLEAR_VARS ซึ่งเป็นค่าของระบบบิลด์ ที่มีให้

include $(CLEAR_VARS)

ตัวแปร CLEAR_VARS ชี้ไปที่ GNU Makefile พิเศษที่ช่วยล้างหลายๆ ตัวแปร LOCAL_XXX รายการให้คุณ เช่น LOCAL_MODULE, LOCAL_SRC_FILES และ LOCAL_STATIC_LIBRARIES โปรดทราบว่าไม่ล้างข้อมูล LOCAL_PATH ช่วงเวลานี้ จะต้องเก็บค่าตัวแปรไว้เนื่องจากระบบแยกวิเคราะห์ไฟล์ควบคุมบิลด์ทั้งหมด ใน GNU สร้างบริบทการดำเนินการที่ตัวแปรทั้งหมดอยู่ส่วนกลาง คุณต้อง ประกาศตัวแปรนี้ (อีกครั้ง) ก่อนอธิบายแต่ละโมดูล

จากนั้นตัวแปร LOCAL_MODULE จะจัดเก็บชื่อโมดูลที่คุณต้องการ งานสร้าง ใช้ตัวแปรนี้ 1 ครั้งต่อโมดูลในแอปพลิเคชัน

LOCAL_MODULE := hello-jni

ชื่อโมดูลแต่ละชื่อต้องไม่ซ้ำกันและไม่มีการเว้นวรรค ระบบบิลด์ เมื่อสร้างไฟล์ไลบรารีที่ใช้ร่วมกันขั้นสุดท้าย ก็จะเพิ่มคอลัมน์ คำนำหน้าและคำต่อท้ายชื่อที่คุณกำหนดให้กับ LOCAL_MODULE ตัวอย่างเช่น ตัวอย่างที่ปรากฏด้านบนส่งผลให้เกิดการสร้างห้องสมุดชื่อ libhello-jni.so

บรรทัดถัดไปจะแจกแจงไฟล์ต้นฉบับ โดยมีการเว้นวรรคคั่นไฟล์หลายรายการ ไฟล์:

LOCAL_SRC_FILES := hello-jni.c

ตัวแปร LOCAL_SRC_FILES ต้องมีรายการไฟล์ต้นฉบับ C และ/หรือ C++ ในการสร้างเป็นโมดูล

บรรทัดสุดท้ายจะช่วยให้ระบบเชื่อมโยงทุกอย่างเข้าด้วยกัน

include $(BUILD_SHARED_LIBRARY)

ตัวแปร BUILD_SHARED_LIBRARY ชี้ไปยังสคริปต์ GNU Makefile ที่ รวบรวมข้อมูลทั้งหมดที่คุณระบุไว้ในตัวแปร LOCAL_XXX ตั้งแต่ include ล่าสุด สคริปต์นี้จะกำหนดสิ่งที่ควรสร้างและวิธีสร้าง

มีตัวอย่างที่ซับซ้อนมากขึ้นในไดเรกทอรีตัวอย่าง โดยมีความคิดเห็น Android.mk ไฟล์ที่คุณสามารถดู นอกจากนี้ ตัวอย่าง: Native-activity จะให้คำอธิบายโดยละเอียดเกี่ยวกับไฟล์ Android.mk ของตัวอย่างดังกล่าว สุดท้าย ตัวแปรและมาโครให้ข้อมูลเพิ่มเติมเกี่ยวกับตัวแปรจาก

ตัวแปรและมาโคร

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

นอกจากตัวแปรเหล่านี้แล้ว คุณยังกำหนดตัวแปรของคุณเองได้ด้วย หากเป็นเช่นนั้น โปรด โปรดทราบว่าระบบบิลด์ NDK จะสงวนชื่อตัวแปรต่อไปนี้:

  • ชื่อที่ขึ้นต้นด้วย LOCAL_ เช่น LOCAL_MODULE
  • ชื่อที่ขึ้นต้นด้วย PRIVATE_, NDK_ หรือ APP ระบบบิลด์ใช้ เหล่านี้เป็นการภายใน
  • ชื่อตัวพิมพ์เล็ก เช่น my-dir ระบบบิลด์จะใช้สิ่งเหล่านี้ภายใน

ถ้าคุณต้องกำหนดตัวแปรอำนวยความสะดวกของคุณเองในไฟล์ Android.mk ขอแนะนำให้ใส่ MY_ ไว้หน้าชื่อ

ตัวแปรรวมที่กำหนดโดย NDK

ส่วนนี้จะกล่าวถึงตัวแปร GNU Make ที่ระบบกำหนด ก่อนแยกวิเคราะห์ไฟล์ Android.mk ในบางกรณี NDK อาจแยกวิเคราะห์ไฟล์ Android.mk หลายครั้งโดยใช้คำจำกัดความอื่น สำหรับตัวแปรบางตัวทุกครั้ง

ล้างตัวแปร

ตัวแปรนี้ชี้ไปยังสคริปต์บิลด์ที่ยังไม่ได้กำหนด LOCAL_XXX เกือบทั้งหมด ตัวแปรที่แสดงใน "ตัวแปรที่นักพัฒนาแอปกำหนด" ด้านล่าง ใช้ร่างคำตอบนี้ ที่จะรวมสคริปต์นี้ก่อนที่จะอธิบายโมดูลใหม่ ไวยากรณ์ของ โดยใช้สิ่งนี้

include $(CLEAR_VARS)

สร้างผลลัพธ์สำเร็จ

ตัวแปรนี้ชี้ไปยังสคริปต์บิลด์ที่รวบรวมข้อมูลทั้งหมดเกี่ยวกับ โมดูลที่คุณระบุไว้ในตัวแปร LOCAL_XXX รวมทั้งกำหนดวิธีการ สร้างปฏิบัติการเป้าหมายจากแหล่งที่มาที่คุณระบุ โปรดทราบว่าการใช้สิ่งนี้ คุณต้องกำหนดค่าให้กับ LOCAL_MODULE และ LOCAL_SRC_FILES เป็นอย่างน้อย (ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวแปรเหล่านี้ได้ที่ ตัวแปรคำอธิบายโมดูล)

ไวยากรณ์สำหรับการใช้ตัวแปรนี้คือ

include $(BUILD_EXECUTABLE)

คลังที่ใช้ร่วมกัน

ตัวแปรนี้ชี้ไปยังสคริปต์บิลด์ที่รวบรวมข้อมูลทั้งหมดเกี่ยวกับ โมดูลที่คุณระบุไว้ในตัวแปร LOCAL_XXX รวมทั้งกำหนดวิธีการ สร้างไลบรารีที่ใช้ร่วมกันเป้าหมายจากแหล่งที่มาที่คุณแสดงรายการไว้ โปรดทราบว่าการใช้สิ่งนี้ คุณต้องกำหนดค่าให้กับ LOCAL_MODULE และ LOCAL_SRC_FILES เป็นอย่างน้อย (ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวแปรเหล่านี้ได้ที่ ตัวแปรคำอธิบายโมดูล)

ไวยากรณ์สำหรับการใช้ตัวแปรนี้คือ

include $(BUILD_SHARED_LIBRARY)

ตัวแปรไลบรารีที่ใช้ร่วมกันจะทำให้ระบบบิลด์สร้างไฟล์ไลบรารี ด้วยส่วนขยาย .so

คลังสถิติสถิติ

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

include $(BUILD_STATIC_LIBRARY)

ตัวแปรไลบรารีแบบคงที่จะทำให้ระบบสร้างไลบรารีที่มี ส่วนขยาย .a

คลังที่สร้างไว้ล่วงหน้า

ชี้ไปที่สคริปต์บิลด์ที่ใช้ระบุไลบรารีที่ใช้ร่วมกันที่สร้างไว้ล่วงหน้า เลิกชอบ ในกรณีของ BUILD_SHARED_LIBRARY และ BUILD_STATIC_LIBRARY นี่คือค่าของ LOCAL_SRC_FILES ไม่สามารถเป็นไฟล์ต้นฉบับ แต่จะต้องเป็นเส้นทางเดียวเพื่อ ไลบรารีที่ใช้ร่วมกันที่สร้างไว้ล่วงหน้า เช่น foo/libfoo.so ไวยากรณ์ในการใช้ ตัวแปรคือ

include $(PREBUILT_SHARED_LIBRARY)

นอกจากนี้ คุณยังสามารถอ้างอิงไลบรารีที่สร้างไว้ล่วงหน้าในอีกโมดูลหนึ่งได้โดยใช้ ตัวแปร LOCAL_PREBUILTS สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้รายการที่สร้างไว้ล่วงหน้า โปรดดูที่ ใช้ไลบรารีที่สร้างไว้ล่วงหน้า

ไลบรารีสถิติเบื้องต้น

เหมือนกับ PREBUILT_SHARED_LIBRARY แต่สำหรับไลบรารีแบบคงที่ที่สร้างไว้ล่วงหน้า สำหรับ ข้อมูลเพิ่มเติมเกี่ยวกับการใช้รายการที่สร้างไว้ล่วงหน้า โปรดดูที่ใช้ไลบรารีที่สร้างไว้ล่วงหน้า

ตัวแปรข้อมูลเป้าหมาย

ระบบบิลด์จะแยกวิเคราะห์ Android.mk 1 ครั้งต่อ ABI ที่ระบุโดย APP_ABI ซึ่งมักกำหนดไว้ในไฟล์ Application.mk หาก APP_ABI มีค่า all ระบบบิลด์จะแยกวิเคราะห์ Android.mk 1 ครั้งต่อ ABI ส่วน NDK รองรับ ส่วนนี้จะอธิบายตัวแปรที่ระบบบิลด์กำหนดทุกครั้งที่ระบบ แยกวิเคราะห์ Android.mk

TARGET_ARCH

ตระกูล CPU ที่ระบบบิลด์กำหนดเป้าหมายขณะแยกวิเคราะห์ Android.mk นี้ ตัวแปรนี้จะเป็น arm, arm64, x86 หรือ x86_64

TARGET_PLATFORM

หมายเลขระดับ API ของ Android ที่ระบบบิลด์กำหนดเป้าหมายขณะแยกวิเคราะห์ Android.mk ไฟล์ ตัวอย่างเช่น อิมเมจระบบ Android 5.1 สอดคล้องกับ API ของ Android ระดับ 22: android-22 หากต้องการดูรายชื่อแพลตฟอร์มทั้งหมดและ อิมเมจระบบ Android ที่เกี่ยวข้อง โปรดดู Native API ตัวอย่างต่อไปนี้แสดงไวยากรณ์สำหรับการใช้ตัวแปรนี้:

ifeq ($(TARGET_PLATFORM),android-22)
    # ... do something ...
endif

TARGET_ARCH_ABI

ABI ที่ระบบบิลด์กำลังกำหนดเป้าหมายขณะแยกวิเคราะห์ไฟล์ Android.mk นี้ ตารางที่ 1 แสดงการตั้งค่า ABI ที่ใช้สำหรับ CPU และสถาปัตยกรรมที่รองรับแต่ละรายการ

ตาราง 1 การตั้งค่า ABI สำหรับ CPU และสถาปัตยกรรมที่ต่างกัน

CPU และสถาปัตยกรรม การเกริ่นนำ
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
I686 x86
X86-64 x86_64

ตัวอย่างต่อไปนี้แสดงวิธีตรวจสอบ ARMv8 AArch64 เป็นเป้าหมาย ชุดค่าผสม CPU และ ABI:

ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
  # ... do something ...
endif

ดูรายละเอียดเพิ่มเติมเกี่ยวกับ ABI ของสถาปัตยกรรมและปัญหาความเข้ากันได้ที่เกี่ยวข้อง ดู ABI ของ Android

ABI เป้าหมายใหม่ในอนาคตจะมีค่าที่แตกต่างกัน

TARGET_ABI

การเชื่อมโยงระดับ API ของ Android เป้าหมายกับ ABI เข้าด้วยกัน มีประโยชน์อย่างยิ่ง เมื่อต้องการทดสอบกับอิมเมจระบบเป้าหมายที่เฉพาะเจาะจงสำหรับอุปกรณ์จริง เช่น หากต้องการตรวจสอบอุปกรณ์ ARM 64 บิตที่ทำงานใน Android API ระดับ 22 ให้ทำดังนี้

ifeq ($(TARGET_ABI),android-22-arm64-v8a)
  # ... do something ...
endif

ตัวแปรคำอธิบายโมดูล

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

  1. เริ่มต้นหรือยกเลิกการกำหนดตัวแปรที่เชื่อมโยงกับโมดูล โดยใช้ ตัวแปร CLEAR_VARS
  2. กำหนดค่าให้กับตัวแปรที่ใช้อธิบายโมดูล
  3. ตั้งค่าระบบบิลด์ NDK ให้ใช้สคริปต์บิลด์ที่เหมาะสมสำหรับโมดูล โดยใช้ตัวแปร BUILD_XXX

เส้นทาง LOCAL_PATH

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

LOCAL_PATH := $(call my-dir)

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

โมดูลในพื้นที่

ตัวแปรนี้จัดเก็บชื่อโมดูลของคุณ ต้องไม่ซ้ำกันในทุกโมดูล และต้องไม่มีการเว้นวรรค คุณต้องกำหนดก่อนที่จะรวม สคริปต์ (นอกเหนือจากสคริปต์สำหรับ CLEAR_VARS) คุณไม่จำเป็นต้องเพิ่ม lib นำหน้าหรือนามสกุลไฟล์ .so หรือ .a ระบบบิลด์ทำให้ โดยอัตโนมัติ ตลอดทั้ง Android.mk และ Application.mk ให้อ้างอิงโมดูลด้วยชื่อที่ไม่มีการแก้ไข ตัวอย่างเช่น URL ต่อไปนี้ ผลลัพธ์บรรทัดในการสร้างโมดูลไลบรารีที่ใช้ร่วมกันชื่อ libfoo.so:

LOCAL_MODULE := "foo"

หากคุณต้องการให้โมดูลที่สร้างมีชื่ออื่นที่ไม่ใช่ lib + ค่าของ LOCAL_MODULE คุณสามารถใช้ตัวแปร LOCAL_MODULE_FILENAME เพื่อระบุฟิลด์ สร้างชื่อโมดูลที่คุณเลือกเองแทน

LOCAL_MODULE_FILENAME

ตัวแปรที่ไม่บังคับนี้ทำให้คุณสามารถลบล้างชื่อที่ระบบบิลด์ ใช้ค่าเริ่มต้นสำหรับไฟล์ที่สร้างขึ้นมา ตัวอย่างเช่น หากชื่อ LOCAL_MODULE คือ foo คุณบังคับให้ระบบเรียกไฟล์ที่ระบบสร้างได้ libnewfoo ตัวอย่างต่อไปนี้แสดงวิธีดำเนินการดังกล่าว

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

สำหรับโมดูลไลบรารีที่ใช้ร่วมกัน ตัวอย่างนี้จะสร้างไฟล์ชื่อ libnewfoo.so

LOCAL_SRC_FILES

ตัวแปรนี้มีรายการไฟล์ต้นฉบับที่ระบบบิลด์ใช้เพื่อ สร้างโมดูลนี้ แสดงเฉพาะไฟล์ที่ระบบบิลด์ผ่านจริงๆ เท่านั้น ไปยังคอมไพเลอร์ เนื่องจากระบบบิลด์จะคำนวณ ทรัพยากร Dependency โปรดทราบว่าคุณสามารถใช้ทั้งแบบสัมพัทธ์ (กับ LOCAL_PATH) และสัมบูรณ์ เส้นทางไฟล์

เราขอแนะนำให้หลีกเลี่ยงเส้นทางไฟล์แบบสัมบูรณ์ เส้นทางสัมพัทธ์จะทำให้ Android.mk ไฟล์สามารถพกพาได้มากขึ้น

LOCAL_CPP_EXTENSION

คุณสามารถใช้ตัวแปรที่ไม่บังคับนี้เพื่อระบุนามสกุลไฟล์นอกเหนือจาก .cpp สำหรับไฟล์ต้นฉบับ C++ ตัวอย่างเช่น บรรทัดต่อไปนี้จะเปลี่ยน ส่วนขยายไปยัง .cxx (การตั้งค่าต้องมีจุด)

LOCAL_CPP_EXTENSION := .cxx

คุณใช้ตัวแปรนี้เพื่อระบุส่วนขยายหลายรายการได้ ตัวอย่างเช่น

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

ฟีเจอร์ LOCAL_CPP

คุณสามารถใช้ตัวแปรที่ไม่บังคับนี้เพื่อระบุว่าโค้ดของคุณใช้ตัวแปร C++ ช่วยให้มีการแฟล็กคอมไพเลอร์และ Linker ที่เหมาะสมระหว่างบิลด์ ขั้นตอนได้ สำหรับไบนารีที่สร้างไว้ล่วงหน้า ตัวแปรนี้จะประกาศฟีเจอร์ จะขึ้นอยู่กับว่าลิงก์สุดท้ายทำงานได้อย่างถูกต้อง พ ขอแนะนำให้คุณใช้ตัวแปรนี้แทนการเปิดใช้ -frtti และ -fexceptions โดยตรงในคำจำกัดความ LOCAL_CPPFLAGS

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

เช่น เพื่อระบุว่าโค้ดของคุณใช้ RTTI (ข้อมูลประเภทรันไทม์) เขียน:

LOCAL_CPP_FEATURES := rtti

หากต้องการระบุว่าโค้ดของคุณใช้ข้อยกเว้น C++ ให้เขียนดังนี้

LOCAL_CPP_FEATURES := exceptions

คุณสามารถระบุหลายค่าสำหรับตัวแปรนี้ได้เช่นกัน เช่น

LOCAL_CPP_FEATURES := rtti features

ลำดับที่คุณอธิบายค่านั้นไม่สำคัญ

Local_C_INCLUDES

คุณสามารถใช้ตัวแปรที่ไม่บังคับนี้เพื่อระบุรายการเส้นทางที่สัมพันธ์กับ ไดเรกทอรี root ของ NDK เพื่อเพิ่มไปยังเส้นทางการค้นหาเมื่อรวบรวมข้อมูลทั้งหมด แหล่งที่มา (C, C++ และ Assembly) เช่น

LOCAL_C_INCLUDES := sources/foo

หรือแม้กระทั่ง:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo

กำหนดตัวแปรนี้ก่อนตั้งค่าแฟล็กการรวมที่เกี่ยวข้องผ่าน LOCAL_CFLAGS หรือ LOCAL_CPPFLAGS

ระบบบิลด์ยังใช้เส้นทาง LOCAL_C_INCLUDES โดยอัตโนมัติเมื่อเปิดตัวด้วย การแก้ไขข้อบกพร่องของระบบด้วย ndk-gdb

LOCAL_CFLAGS

ตัวแปรที่ไม่บังคับนี้ตั้งค่าแฟล็กคอมไพเลอร์เพื่อให้ระบบบิลด์ส่งต่อเมื่อ สร้างไฟล์ C และไฟล์ต้นฉบับ C++ ความสามารถในการดำเนินการข้างต้น มีประโยชน์สำหรับ โดยระบุคำจำกัดความของมาโครเพิ่มเติมหรือคอมไพล์ตัวเลือก ใช้ LOCAL_CPPFLAGS เพื่อระบุแฟล็กสำหรับ C++ เท่านั้น

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

คุณสามารถระบุเส้นทางรวมเพิ่มเติมได้ด้วยการเขียนดังนี้

LOCAL_CFLAGS += -I<path>,

อย่างไรก็ตาม การใช้ LOCAL_C_INCLUDES เพื่อวัตถุประสงค์นี้จะดีกว่า เนื่องจาก จึงทำให้สามารถใช้เส้นทางที่มีอยู่สำหรับการแก้ไขข้อบกพร่องของระบบด้วย ndk-gdb

LOCAL_CPPFLAGS

ชุดแฟล็กคอมไพเลอร์ที่ไม่บังคับซึ่งจะส่งผ่านเมื่อสร้างซอร์ส C++ เท่านั้น โดยจะปรากฏหลัง LOCAL_CFLAGS ใน บรรทัดคำสั่ง ใช้ LOCAL_CFLAGS เพื่อระบุแฟล็กสำหรับทั้ง C และ C++

ไลบรารี LOCAL_STATIC_LIBRARIES

ตัวแปรนี้จัดเก็บรายการโมดูลไลบรารีแบบคงที่ซึ่งฟังก์ชัน ขึ้นอยู่กับ

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

หากโมดูลปัจจุบันเป็นไลบรารีแบบคงที่ ตัวแปรนี้เพียงแค่ระบุว่า โมดูลอื่นๆ ที่ขึ้นอยู่กับโมดูลปัจจุบัน จะขึ้นอยู่กับโมดูล ห้องสมุด

ห้องสมุด LOCAL_SHARED_LIBRARIES

ตัวแปรนี้คือรายการโมดูลไลบรารีที่ใช้ร่วมกันซึ่งโมดูลนี้ใช้อยู่ ขึ้นอยู่กับรันไทม์ ข้อมูลนี้เป็นสิ่งจำเป็นในเวลาที่ลิงก์ และเพื่อฝัง ข้อมูลที่เกี่ยวข้องในไฟล์ที่สร้างขึ้น

ไลบรารี LOCAL_WHOLE_STATIC_LIBRARIES

ตัวแปรนี้เป็นตัวแปรของ LOCAL_STATIC_LIBRARIES และแสดงให้เห็นว่าฟังก์ชัน Linker ควรถือว่าโมดูลไลบรารีที่เกี่ยวข้องเป็นที่เก็บถาวรทั้งหมด สำหรับ สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับที่เก็บถาวรทั้งหมด โปรดดูเอกสารประกอบของ GNU ld สำหรับ แฟล็ก --whole-archive

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

LOCAL_LDLIBS

ตัวแปรนี้มีรายการแฟล็ก Linker เพิ่มเติมสำหรับใช้ในอาคาร ไลบรารีที่ใช้ร่วมกันหรือไฟล์ปฏิบัติการของคุณ ซึ่งช่วยให้คุณใช้คำนำหน้า -l เพื่อส่งผ่านได้ ชื่อของไลบรารีระบบที่เฉพาะเจาะจง ตัวอย่างเช่น ตัวอย่างต่อไปนี้บอก Linker เพื่อสร้างโมดูลที่ลิงก์ไปยัง /system/lib/libz.so ขณะโหลด เวลา:

LOCAL_LDLIBS := -lz

สำหรับรายการไลบรารีระบบที่เปิดเผยซึ่งคุณลิงก์ใน NDK นี้ได้ โปรดดู Native API

LOCAL_LDFLAGS

รายการแฟล็ก Linker อื่นๆ สำหรับระบบบิลด์เพื่อใช้เมื่อสร้าง ไลบรารีหรือไฟล์สั่งการที่ใช้ร่วมกัน เช่น หากต้องการใช้ตัวลิงก์ ld.bfd ใน ARM/X86:

LOCAL_LDFLAGS += -fuse-ld=bfd

LOCAL_ALLOW_UNDEFINED_SYMBOLS

โดยค่าเริ่มต้น เมื่อระบบบิลด์พบการอ้างอิงที่ไม่ได้กำหนด ขณะที่พยายามสร้างการแชร์ ก็จะเกิดข้อผิดพลาดเกี่ยวกับสัญลักษณ์ที่ไม่ระบุ ช่วงเวลานี้ สามารถช่วยให้พบข้อบกพร่องในซอร์สโค้ด

หากต้องการปิดใช้การตรวจสอบนี้ ให้ตั้งค่าตัวแปรนี้เป็น true โปรดทราบว่าการตั้งค่านี้อาจ ทำให้ไลบรารีที่ใช้ร่วมกันโหลดขณะรันไทม์

โหมด LOCAL_ARM

โดยค่าเริ่มต้น ระบบบิลด์จะสร้างไบนารีเป้าหมาย ARM ในโหมดภาพขนาดย่อ โดยแต่ละคำสั่งจะมีความกว้าง 16 บิตและเชื่อมโยงกับไลบรารี STL ใน ไดเรกทอรี thumb/ การกำหนดตัวแปรนี้เป็น arm จะบังคับให้ระบบบิลด์ สร้างไฟล์ออบเจ็กต์ของโมดูลในโหมด arm แบบ 32 บิต ตัวอย่างต่อไปนี้ แสดงวิธีดำเนินการ

LOCAL_ARM_MODE := arm

หรือจะสั่งให้ระบบบิลด์สร้างเฉพาะแหล่งที่มาที่เฉพาะเจาะจงใน arm ก็ได้ โดยเพิ่ม .arm ต่อท้ายชื่อไฟล์ต้นฉบับ ตัวอย่างเช่น พารามิเตอร์ ตัวอย่างต่อไปนี้จะบอกระบบบิลด์ให้คอมไพล์ bar.c ในโหมด ARM เสมอ แต่เพื่อสร้าง foo.c ตามค่าของ LOCAL_ARM_MODE

LOCAL_SRC_FILES := foo.c bar.c.arm

LOCAL_ARM_NEON

ตัวแปรนี้สําคัญเฉพาะเมื่อคุณกําหนดเป้าหมาย ABI armeabi-v7a เท่านั้น ทั้งนี้ อนุญาตให้ใช้คอมไพเลอร์ของ ARM Advanced SIMD (NEON) ใน C และ C++ ได้ รวมทั้งคำสั่ง NEON ในไฟล์ Assembly ด้วย

โปรดทราบว่า CPU ที่ใช้ ARMv7 บางรุ่นไม่รองรับส่วนขยายชุดคำสั่ง NEON ด้วยเหตุนี้ คุณจึงต้องตรวจหารันไทม์เพื่อให้ใช้ได้อย่างปลอดภัย โค้ดนี้ขณะรันไทม์ สำหรับข้อมูลเพิ่มเติม โปรดดูที่การสนับสนุนของ Neon และ ฟีเจอร์ของ CPU

หรือคุณจะใช้ส่วนต่อท้าย .neon เพื่อระบุว่าระบบบิลด์ก็ได้ คอมไพล์ไฟล์ต้นฉบับที่มีการรองรับ NEON เท่านั้น ในตัวอย่างต่อไปนี้ ระบบบิลด์คอมไพล์ foo.c พร้อมการรองรับนิ้วโป้งและนีออน bar.c ด้วย รองรับนิ้วหัวแม่มือ และ zoo.c พร้อมการรองรับ ARM และ NEON:

LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon

หากคุณใช้คำต่อท้ายทั้ง 2 แบบ .arm ต้องมาก่อน .neon

LOCAL_DISABLE_FORMAT_STRING_CHECKS

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

LOCAL_EXPORT_CFLAGS

ตัวแปรนี้บันทึกชุดแฟล็กคอมไพเลอร์ C/C++ ที่จะเพิ่มไปยัง LOCAL_CFLAGS ของโมดูลอื่นๆ ที่ใช้โมดูลนี้ผ่านทาง LOCAL_STATIC_LIBRARIES หรือ LOCAL_SHARED_LIBRARIES

ตัวอย่างเช่น ลองพิจารณาโมดูลคู่ต่อไปนี้ foo และ bar ซึ่ง ขึ้นอยู่กับ foo:

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

ในส่วนนี้ ระบบบิลด์จะส่งแฟล็ก -DFOO=1 และ -DBAR=2 ไปยังคอมไพเลอร์ เมื่อสร้างbar.c นอกจากนี้ยังเพิ่ม Flag ที่ส่งออกไว้หน้า Flag ของโมดูลของคุณ LOCAL_CFLAGSเพื่อให้คุณลบล้างค่าได้อย่างง่ายดาย

นอกจากนี้ ความสัมพันธ์ระหว่างโมดูลต่างๆ เป็นแบบทรานซิทีฟ: หาก zoo ขึ้นอยู่กับ bar ซึ่งก็ขึ้นอยู่กับ foo แล้ว zoo จะรับค่า Flag ทั้งหมดด้วย ส่งออกจาก foo

สุดท้าย ระบบบิลด์ไม่ได้ใช้ Flag ที่ส่งออกเมื่อสร้างในเครื่อง (เช่น การสร้างโมดูลที่มีการส่งออกธง) ดังนั้นในตัวอย่าง ด้านบน จะไม่ส่ง -DFOO=1 ไปยังคอมไพเลอร์เมื่อสร้าง foo/foo.c ถึง บิลด์ในเครื่อง ให้ใช้ LOCAL_CFLAGS แทน

LOCAL_EXPORT_CPPFLAGS

ตัวแปรนี้เหมือนกับ LOCAL_EXPORT_CFLAGS แต่สำหรับแฟล็ก C++ เท่านั้น

LOCAL_EXPORT_C_INCLUDES

ตัวแปรนี้เหมือนกับ LOCAL_EXPORT_CFLAGS แต่สำหรับ C รวมเส้นทาง ทั้งนี้ มีประโยชน์ในกรณีที่ bar.c จำเป็นต้องใส่ส่วนหัวจาก โมดูล foo

LOCAL_EXPORT_LDFLAGS

ตัวแปรนี้เหมือนกับ LOCAL_EXPORT_CFLAGS แต่มีไว้สำหรับแฟล็ก Linker

LOCAL_EXPORT_LDLIBS

ตัวแปรนี้เหมือนกับ LOCAL_EXPORT_CFLAGS บอกให้ระบบบิลด์ ส่งผ่านชื่อของไลบรารีระบบที่เฉพาะเจาะจงไปยังคอมไพเลอร์ แทรก -l ไว้ข้างหน้า ของไลบรารีแต่ละรายการที่คุณระบุ

โปรดทราบว่าระบบบิลด์จะเพิ่มแฟล็ก Linker ที่นำเข้าต่อท้ายค่าของ ตัวแปร LOCAL_LDLIBS ของโมดูล เนื่องจากวิธีการทํางานของ Unix Linker

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

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

ในตัวอย่างนี้ ระบบบิลด์จะใส่ -llog ไว้ที่ท้ายคำสั่ง Linker เมื่อสร้าง libbar.so การทำเช่นนี้จะบอกให้ Linker ทราบว่า เนื่องจาก libbar.so ขึ้นอยู่กับ foo และยังขึ้นอยู่กับไลบรารีการบันทึกของระบบด้วย

LOCAL_SHORT_COMMAND

ตั้งค่าตัวแปรนี้เป็น true เมื่อโมดูลมีแหล่งที่มาสูงมาก และ/หรือไลบรารีแบบคงที่หรือไลบรารีที่ใช้ร่วมกันไม่ได้ การทำเช่นนี้จะบังคับให้ระบบบิลด์ ใช้ไวยากรณ์ @ สำหรับที่เก็บถาวรที่มีไฟล์ออบเจ็กต์สื่อกลางหรือการลิงก์ ห้องสมุด

ฟีเจอร์นี้อาจมีประโยชน์ใน Windows ซึ่งบรรทัดคำสั่งยอมรับจำนวนสูงสุด โดยใช้อักขระเพียง 8, 191 ตัว ซึ่งอาจเล็กเกินไปสำหรับโปรเจ็กต์ที่ซับซ้อน และ ส่งผลต่อการคอมไพล์ไฟล์ต้นฉบับแต่ละไฟล์ โดยวางคอมไพเลอร์เกือบทั้งหมด ภายในไฟล์รายการด้วย

โปรดทราบว่าค่าอื่นที่ไม่ใช่ true จะเปลี่ยนกลับเป็นลักษณะการทำงานเริ่มต้น คุณ และยังสามารถกำหนด APP_SHORT_COMMANDS ในไฟล์ Application.mk เพื่อบังคับ ลักษณะนี้ของโมดูลทั้งหมดในโปรเจ็กต์ของคุณ

เราไม่แนะนำให้เปิดใช้ฟีเจอร์นี้โดยค่าเริ่มต้นเนื่องจากจะทำให้บิลด์ ช้าลง

LOCAL_THIN_ARCHIVE

ตั้งค่าตัวแปรนี้เป็น true เมื่อสร้างไลบรารีแบบคงที่ การดำเนินการนี้จะ สร้างที่เก็บถาวรแบบ Thin ซึ่งเป็นไฟล์ไลบรารีที่ไม่มีไฟล์ออบเจ็กต์ แต่ให้ส่งเส้นทางไปยังออบเจ็กต์จริงที่ตามปกติ มี

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

ค่าที่ถูกต้องคือ true, false หรือว่างเปล่า คุณสามารถกำหนดค่าเริ่มต้นได้ใน Application.mk ผ่านตัวแปร APP_THIN_ARCHIVE

LOCAL_FILTER_ASM

กำหนดตัวแปรนี้เป็นคำสั่ง Shell ที่ระบบบิลด์จะใช้เพื่อกรอง ไฟล์การประกอบที่แยกหรือสร้างจากไฟล์ที่คุณระบุ LOCAL_SRC_FILES การกําหนดตัวแปรนี้ทําให้เกิดเหตุการณ์ต่อไปนี้

  1. ระบบบิลด์จะสร้างไฟล์การประกอบชั่วคราวจากซอร์ส C หรือ C++ ใดก็ได้ แทนการรวบรวมเป็นไฟล์ออบเจ็กต์
  2. ระบบบิลด์จะเรียกใช้คำสั่ง Shell ใน LOCAL_FILTER_ASM บนอุปกรณ์ใดก็ได้ ไฟล์การประกอบชั่วคราวและไฟล์การประกอบที่ระบุใน LOCAL_SRC_FILES ดังนั้นจึงสร้างไฟล์การประกอบชั่วคราวขึ้นมาอีกไฟล์หนึ่ง
  3. ระบบบิลด์จะรวมไฟล์แอสเซมบ์ที่กรองแล้วเหล่านี้ลงในไฟล์ออบเจ็กต์

เช่น

LOCAL_SRC_FILES  := foo.c bar.S
LOCAL_FILTER_ASM :=

foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o
bar.S                                 --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o

"1" ตรงกับคอมไพเลอร์ "2" ลงในตัวกรอง และ "3" ให้กับโปรแกรมประกอบ ตัวกรองต้องเป็นคำสั่ง Shell แบบสแตนด์อโลนที่ใช้ชื่อของอินพุต เป็นอาร์กิวเมนต์แรก และชื่อไฟล์เอาต์พุตเป็นอาร์กิวเมนต์ที่สอง เช่น

myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S

มาโครฟังก์ชันที่ NDK มีให้

ส่วนนี้อธิบายถึงมาโครฟังก์ชันของ GNU ที่ NDK มีให้ ใช้ $(call <function>) เพื่อประเมินผล กลับมีข้อมูลที่เป็นข้อความ

ไดเรกทอรีของฉัน

มาโครนี้จะส่งคืนเส้นทางของ Makefile ที่รวมไว้ล่าสุด ซึ่งโดยทั่วไปจะเป็น ไดเรกทอรีปัจจุบันของ Android.mk my-dir มีประโยชน์สำหรับคำจำกัดความ LOCAL_PATH ที่จุดเริ่มต้นของไฟล์ Android.mk เช่น

LOCAL_PATH := $(call my-dir)

จากวิธีการทำงานของ GNU Make สิ่งที่มาโครนี้ส่งคืนจริงๆ คือเส้นทางของ ไฟล์สร้างครั้งล่าสุดที่ระบบบิลด์รวมไว้เมื่อแยกวิเคราะห์สคริปต์บิลด์ สำหรับ ด้วยเหตุนี้ คุณจึงไม่ควรเรียก my-dir หลังจากรวมไฟล์อื่น

ตัวอย่างเช่น โปรดพิจารณาตัวอย่างต่อไปนี้

LOCAL_PATH := $(call my-dir)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(call my-dir)

# ... declare another module

ปัญหาก็คือการเรียกครั้งที่ 2 ไปยัง my-dir กำหนด LOCAL_PATH เป็น $PATH/foo แทนที่จะเป็น $PATH เพราะนั่นเป็นตำแหน่งล่าสุดที่มี ชี้

คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยใส่การรวมเพิ่มเติมหลังส่วนอื่น ในไฟล์ Android.mk เช่น

LOCAL_PATH := $(call my-dir)

# ... declare one module

LOCAL_PATH := $(call my-dir)

# ... declare another module

# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk

หากวางโครงสร้างไฟล์ในลักษณะนี้ไม่ได้ ให้บันทึกค่าของแอตทริบิวต์ การเรียก my-dir ครั้งแรกไปยังตัวแปรอื่น เช่น

MY_LOCAL_PATH := $(call my-dir)

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare another module

ไฟล์ย่อยทั้งหมด

แสดงรายการไฟล์ Android.mk ที่อยู่ในไดเรกทอรีย่อยทั้งหมดของ เส้นทางmy-dirปัจจุบัน

คุณสามารถใช้ฟังก์ชันนี้เพื่อระบุลำดับชั้นของไดเรกทอรีต้นทางที่ซ้อนลึกสำหรับ ระบบบิลด์ โดยค่าเริ่มต้น NDK จะค้นหาเฉพาะไฟล์ในไดเรกทอรีเท่านั้น ที่มีไฟล์ Android.mk อยู่

ไฟล์รูปแบบนี้

แสดงเส้นทางของไฟล์บิลด์ปัจจุบัน (ซึ่งระบบบิลด์ใช้ชื่อว่า )

ไฟล์หลัก

แสดงเส้นทางของไฟล์รูปแบบหลักในโครงสร้างการรวม (เส้นทางของ ไฟล์ที่มีไฟล์ปัจจุบัน)

ไฟล์แบ่งย่า/ตายาย

แสดงเส้นทางของไฟล์รูปแบบพื้นฐานในโครงสร้างการรวม (เส้นทางของ ไฟล์ Makefile ที่รวมไฟล์ปัจจุบันไว้)

โมดูลนำเข้า

ฟังก์ชันที่ช่วยให้คุณค้นหาและรวมไฟล์ Android.mk ของโมดูลได้โดย ชื่อของโมดูล ตัวอย่างทั่วไปมีดังนี้

$(call import-module,<name>)

ในตัวอย่างนี้ ระบบบิลด์จะมองหาโมดูลที่ติดแท็ก <name> ใน รายการไดเรกทอรีที่อ้างอิงว่าสภาพแวดล้อม NDK_MODULE_PATH ของคุณ และรวมไฟล์ Android.mk ไว้ให้คุณโดยอัตโนมัติ