लिनक्स कर्नेल मॉड्यूल में स्थानीय हेडर फ़ाइलों को कैसे शामिल किया जाए


17

कहो कि मेरे पास mymodस्रोत फ़ाइलों के साथ एक मॉड्यूल है:

src / mod / mymod.c
src / inc / mymod.h

मैं mymod.h को निम्न प्रकार से शामिल करने का प्रयास करता हूं

#include <mymod.h>

मेरे मेकफाइल में शामिल है EXTRA_CFLAGS= -I$(shell pwd)/../inc/लेकिन जब कर्नेल बनाया जाता है, तो मुझे एक त्रुटि मिलती है:

mymod.h नहीं मिला

कारण यह प्रतीत होता है कि जब कर्नेल मॉड्यूल बनाए जाते हैं तो यह कमांड मेकफाइल से चला जाता है: ( makeV1 का उपयोग करके ):

make -C <path/to/linux/src> M=<path/to/mymod> modules

अन्य कार्यों में मेरा $(shell pwd)विस्तार हुआ <path/to/linux>। यह वह नहीं है जिसकी मुझे चाहत है। मैं अपने स्रोत पेड़ -Iको इंगित करने src/incके लिए पैरामीटर कैसे निर्दिष्ट कर सकता हूं mymod?

जवाबों:


19

लिनक्स कर्नेल मेकफाइल्स Kbuild फ्रेमवर्क का उपयोग करते हैं। यद्यपि इनकी व्याख्या GNU मेक द्वारा की गई है, क्रिप्ट में अजीबोगरीब उपयोग सम्मेलनों के साथ मैक्रोज़ का एक बड़ा सेट है, इसलिए विशिष्ट मेकफाइल दिशानिर्देश लागू नहीं होते हैं। Kbuild के बारे में अच्छी बात यह है कि आपको कार्य की जटिलता को देखते हुए बहुत कम बॉयलरप्लेट की आवश्यकता होती है।

क्रिप्ट को कर्नेल स्रोत में दर्ज़ किया गया है Documentation/kbuild। मॉड्यूल लेखक के रूप में, आपको विशेष रूप से modules.txt(और दूसरों के माध्यम से कम से कम स्किम) पढ़ना चाहिए ।

अब आप जो कर रहे हैं वह काम नहीं कर रहा है क्योंकि $(shell pwd)जब EXTRA_CFLAGSचर का उपयोग किया जाता है तो उसका विस्तार किया जाता है। चूंकि मेकफाइल आपके मॉड्यूल की डायरेक्टरी से बजाय कर्नेल सोर्स ट्री से चलता है (यह Kbuild के कई गैर-स्पष्ट पहलुओं में से एक है), यह गलत डायरेक्टरी उठा रहा है।

निर्दिष्ट करने के लिए आधिकारिक मुहावरा एक आउट-ऑफ-ट्री मॉड्यूल में निर्देशिकाओं को शामिल करने के लिए of5.3 में है modules.txtsrcचर अपने मॉड्यूल के उच्चस्तरीय निर्देशिका को तैयार है। इसलिए:

EXTRA_CFLAGS := -I$(src)/src/inc

ध्यान दें कि यह घोषणा Kbuildआपके मॉड्यूल ट्री की जड़ नामक एक फ़ाइल में होनी चाहिए । (आप srcनिर्देशिका को अपने मॉड्यूल ट्री की जड़ मान सकते हैं ; यदि हां, तो Kbuildवहां रखें और ऊपर दिए गए मान को बदलें -I$(src)/inc)। उन्हें अंदर रखना भी संभव है Makefile, लेकिन ध्यान रखें कि यह परिभाषा (जब तक कि कुछ और जो केवल कर्नेल मॉड्यूल का निर्माण करते समय लागू होता है) एक सशर्त निर्देश के भीतर होनी चाहिए ifeq ($(KERNELRELEASE),)। 4.1 को देखें modules.txt

यदि आपके पास Kbuildपहले से कोई फ़ाइल नहीं है और आप एक के पास जाना चाहते हैं, तो .14.1 पढ़ें modules.txt। एक अलग Kbuildफ़ाइल होने से थोड़ा स्पष्ट है। कॉल करने के लिए एक नियम के अलावा, अपने मुख्य मेकफाइल में कर्नेल पर लागू होने वाली किसी भी चीज़ को न डालें 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

मैं पद को अपडेट नहीं कर सका क्योंकि मेरे पास पर्याप्त प्रतिष्ठा नहीं थी।
ओम नरसिम्हन

1
@ ओएम नरसिम्हन: अगर इससे आपको समाधान निकालने में मदद मिली, तो आपको जवाब को स्वीकार करना चाहिए।
एक CVn

1

परंपरागत रूप से #includeवर्तमान स्रोत कोड की निर्देशिका के सापेक्ष पथ के साथ फाइल करने का तरीका कोण कोष्ठक के बजाय उद्धरण चिह्नों का उपयोग करना है:

#include <stdio.h>
#include "mygreatfunctions.h"

इस मामले में, पहले #includeसंकलक के खोज पथ को संदर्भित करेगा (जो, gcc के मामले में, -Iकमांड लाइन स्विच द्वारा नियंत्रित होता है ), जबकि दूसरा उस निर्देशिका में दिखेगा जिसमें स्रोत फ़ाइल है #include

ऐसे रास्ते रिश्तेदार भी हो सकते हैं। तो src / mod / mymod.c में, आप कह सकते हैं:

#include "../inc/mymod.h"

और इसे "बस काम" करना चाहिए।

मुझे नहीं पता कि यह लिनक्स कर्नेल ट्री में आम बात है, लेकिन निश्चित रूप से इसमें शामिल पथ के साथ घूमना बेहतर है, जिसमें किसी भी प्रकार के अनपेक्षित साइड इफेक्ट्स हो सकते हैं।


1
सामान्य रूप से अच्छी सलाह, हालांकि लिनक्स कर्नेल मेकफाइल्स बहुत अजीब हैं। वे मैक्रों के एक काफी जटिल सेट पर कॉल करते हैं जिसे क्रिल्ट कहा जाता है; Kbuild को लगभग एक भाषा के रूप में व्यवहार करना सबसे अच्छा है, लेकिन लगभग पूरी तरह से बनाने के विपरीत नहीं।
गिलेस एसओ- बुराई को रोकना '

1
निश्चित रूप से पर्याप्त है, लेकिन निर्देशिकाओं के कुछ कॉन्फ़िगर किए गए सेट में <foo> की तलाश में सी कंपाइलर व्यवहार, और "बार" के लिए वर्तमान निर्देशिका को पहले देख रहा है और फिर पहले बताए गए मार्ग पर वापस आ रहा है जो विचित्र का मतलब क्या है से नहीं बदलेगा पहली जगह में संकलक।
वॉनब्रांड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.