Come includere file di intestazione locali nel modulo del kernel linux


17

Di 'che ho un modulo mymodcon i file sorgente come segue:

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

Cerco di includere mymod.h come segue

#include <mymod.h>

Il mio makefile contiene EXTRA_CFLAGS= -I$(shell pwd)/../inc/ma quando viene creato il kernel, viene visualizzato un errore che indica:

mymod.h non trovato

Il motivo sembra essere che quando vengono creati i moduli del kernel questo comando viene eseguito dal makefile: (usando makeV1):

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

In altri lavori mi $(shell pwd)sono espanso <path/to/linux>. Questo non è quello che voglio. Come posso specificare il -Iparametro a cui puntare il src/incmio mymodalbero dei sorgenti?

Risposte:


19

I makefile del kernel Linux usano il framework Kbuild. Sebbene questi siano interpretati da GNU make, Kbuild è costituito da un ampio set di macro con particolari convenzioni di utilizzo, quindi non si applicano le linee guida tipiche del makefile. La cosa bella di Kbuild è che hai bisogno di pochissime piastre di cottura considerando la complessità del compito.

Kbuild è documentato nel sorgente del kernel, in Documentation/kbuild. Come scrittore di moduli, dovresti leggere in particolare modules.txt(e almeno sfogliare gli altri).

Quello che stai facendo ora non funziona perché $(shell pwd)viene espanso quando EXTRA_CFLAGSviene utilizzata la variabile. Poiché il makefile viene eseguito dall'albero dei sorgenti del kernel piuttosto che dalla directory del tuo modulo (questo è uno dei molti aspetti non visibili di Kbuild), sta raccogliendo la directory sbagliata.

Il linguaggio ufficiale per specificare le directory include in un modulo out-of-tree è in §5.3 di modules.txt. La srcvariabile è impostata sulla directory di livello superiore del modulo. Perciò:

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

Nota che questa dichiarazione dovrebbe essere in un file chiamato Kbuildnella radice dell'albero del tuo modulo. (È possibile considerare la srcdirectory come la radice dell'albero del modulo; in tal caso, inserirla Kbuilde sostituire il valore sopra con -I$(src)/inc). È anche possibile metterli in a Makefile, ma attenzione che questa definizione (purché qualsiasi altra cosa si applichi solo quando si costruisce un modulo kernel) dovrebbe essere all'interno di una direttiva condizionale ifeq ($(KERNELRELEASE),). Vedi §4.1 di modules.txt.

Se non hai Kbuildgià un file e vuoi passare ad averne uno, leggi §4.1 di modules.txt. Avere un Kbuildfile separato è leggermente più chiaro. Non mettere nulla che si applica al kernel nel tuo makefile principale, tranne una regola da chiamare make -C $(KERNELDIR) M=$(pwd). In Kbuild, il minimo necessario è l'elenco dei moduli che stai costruendo (spesso solo quello) e un elenco di file da includere nel modulo, oltre a una dichiarazione di dipendenza:

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h

Non ho potuto aggiornare il post perché non avevo abbastanza reputazione.
Om Narasimhan,

1
@Om Narasimhan: se questo ti ha aiutato a capire la soluzione, dovresti contrassegnare la risposta come accettata.
un CVn il

1

Tradizionalmente il modo di #includefile con percorsi relativi alla directory del codice sorgente corrente è usare le virgolette anziché le parentesi angolari:

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

In questo caso, il primo #includefarà riferimento al percorso di ricerca include del compilatore (che, nel caso di gcc, è controllato dall'opzione della -Iriga di comando), mentre il secondo cercherà nella directory che contiene il file sorgente con il file #include.

Anche questi percorsi possono essere relativi. Quindi in src / mod / mymod.c, puoi dire:

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

e dovrebbe "funzionare".

Non so se questa è una pratica comune nell'albero del kernel di Linux, ma sicuramente è meglio che confondersi con il percorso include, che potrebbe avere un numero qualsiasi di effetti collaterali indesiderati.


1
Un buon consiglio in generale, tuttavia i makefile del kernel Linux sono molto particolari. Invocano un insieme abbastanza complesso di macro chiamato Kbuild; è spesso meglio trattare Kbuild come un linguaggio che è quasi, ma non del tutto, completamente diverso da quello di marca.
Gilles 'SO- smetti di essere malvagio' il

1
Abbastanza sicuro, ma il comportamento del compilatore C di cercare <foo> in alcuni set configurati di directory, e di "bar" guardando prima la directory corrente e poi ricadendo nel percorso menzionato prima non cambierà con ciò che bizzarro significa chiamato il compilatore in primo luogo.
vonbrand,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.