makefiles เคอร์เนล Linux ใช้เฟรมเวิร์ก Kbuild แม้ว่าสิ่งเหล่านี้จะถูกตีความโดย GNU make แต่ Kbuild ประกอบด้วยชุดของแมโครขนาดใหญ่ที่มีข้อกำหนดการใช้งานที่แปลกประหลาดดังนั้นแนวทาง makefile ทั่วไปจึงไม่มีผลบังคับใช้ สิ่งที่ดีเกี่ยวกับ Kbuild คือคุณต้องมีหม้อไอน้ำน้อยมากเมื่อพิจารณาถึงความซับซ้อนของงาน
Kbuild Documentation/kbuild
การบันทึกไว้ในแหล่งเมล็ดใน ในฐานะนักเขียนโมดูลคุณควรอ่านเป็นพิเศษmodules.txt
(และอย่างน้อยก็อ่านผ่าน ๆ )
สิ่งที่คุณทำอยู่ตอนนี้ไม่ทำงานเพราะ$(shell pwd)
ถูกขยายเมื่อใช้EXTRA_CFLAGS
ตัวแปร เนื่องจาก makefile เรียกใช้จากแผนผังซอร์สเคอร์เนลแทนที่จะมาจากไดเรกทอรีของโมดูลของคุณ (นี่คือหนึ่งในหลาย ๆ แง่มุมที่ไม่ได้ทำให้เห็นได้ชัดของ Kbuild) มันจึงรวบรวมไดเรกทอรีที่ไม่ถูกต้อง
modules.txt
สำนวนอย่างเป็นทางการสำหรับการระบุรวมไดเรกทอรีในโมดูลออกจากต้นไม้ที่อยู่ใน§5.3ของ src
ตัวแปรมีการตั้งค่าไปยังไดเรกทอรีระดับบนสุดโมดูลของคุณ ดังนั้น:
EXTRA_CFLAGS := -I$(src)/src/inc
โปรดทราบว่าการประกาศนี้ควรอยู่ในไฟล์ที่เรียกKbuild
ที่รูทของทรีโมดูลของคุณ (คุณอาจต้องการพิจารณาว่าsrc
ไดเรกทอรีเป็นรูทของโมดูลทรีของคุณถ้าเป็นเช่นนั้นให้ใส่ที่Kbuild
นั่นและแทนที่ค่าข้างต้นด้วย-I$(src)/inc
) นอกจากนี้ยังเป็นไปได้ที่จะใส่ไว้ในMakefile
แต่ทราบว่าคำนิยามนี้ (ตราบใดที่สิ่งอื่นที่ใช้เฉพาะเมื่อมีการสร้างเคอร์เนลโมดูล) ifeq ($(KERNELRELEASE),)
ควรจะอยู่ในคำสั่งเงื่อนไข modules.txt
ดู§4.1ของ
หากคุณไม่ได้มีไฟล์อยู่แล้วและต้องการที่จะสลับไปมีหนึ่งอ่าน§4.1ของKbuild
modules.txt
การมีKbuild
ไฟล์แยกต่างหากจะชัดเจนขึ้นเล็กน้อย อย่าใส่อะไรที่ใช้กับเคอร์เนลใน Makefile make -C $(KERNELDIR) M=$(pwd)
หลักของคุณนอกเหนือจากกฎเพื่อโทร ในKbuild
ขั้นต่ำที่คุณต้องการคือรายการของโมดูลที่คุณกำลังสร้าง (มักจะเป็นเพียงหนึ่ง) และรายการของไฟล์ที่จะรวมในโมดูลของคุณรวมถึงการประกาศการพึ่งพา:
EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h