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