Dis que j'ai un module mymod
avec des fichiers source comme suit:
src/mod/mymod.c
src/inc/mymod.h
J'essaie d'inclure myMod.h comme suit
#include <mymod.h>
Mon fabricant contient EXTRA_CFLAGS= -I$(Shell pwd)/../inc/
Mais lorsque le noyau est fait, je reçois une erreur indiquant:
mymod.h non trouvé
La raison semble être que lorsque les modules de noyau sont fabriqués cette commande est exécutée à partir du makefile: (en utilisant make
v1):
make -C <path/to/linux/src> M=<path/to/mymod> modules
Dans d'autres œuvres, ma $(Shell pwd)
a été étendue à <path/to/linux>
. Ce n'est pas ce que je veux. Comment puis-je spécifier le paramètre -I
À pointer sur src/inc
De mon mymod
arbre source?
Les maquillages de noyau Linux utilisent le cadre de Kbuild. Bien que ceux-ci soient interprétés par GNU FAIRE, KBUILD consiste en un grand ensemble de macros avec des conventions d'utilisation particulières, de sorte que les directives de fabrication typiques de Makefile ne s'appliquent pas. La bonne chose à propos de Kbuild est que vous avez besoin de très peu de boiseries compte tenu de la complexité de la tâche.
Kbuild est documentée dans la source du noyau, en Documentation/kbuild
. En tant qu'auteur de module, vous devriez lire en particulier modules.txt
(et au moins écrémé par les autres).
Ce que vous faites est maintenant ne fonctionne pas parce $(Shell pwd)
est étendu lorsque la variable EXTRA_CFLAGS
Est utilisé. Étant donné que le maquillage fonctionne de l'arborescence source du noyau plutôt que de votre répertoire de votre module (c'est l'un des nombreux aspects nonobevés de Kbuild), il ramasse le mauvais répertoire.
L'idiome officiel pour spécifier include dans un module hors-arbre est dans §5.3 de modules.txt
. La variable src
est définie sur le répertoire Toplevel de votre module. Par conséquent:
EXTRA_CFLAGS := -I$(src)/src/inc
Notez que cette déclaration doit être dans un fichier appelé Kbuild
à la racine de votre arbre de module. (Vous voudrez peut-être envisager le répertoire src
pour être la racine de votre arborescence de module; si oui, mettez Kbuild
là et remplacez la valeur ci-dessus par -I$(src)/inc
). Il est également possible de les mettre dans un Makefile
, mais cette définition (tant que toute autre chose qui ne s'applique que lorsque la construction d'un module de noyau) doit être dans une directive conditionnelle ifeq ($(KERNELRELEASE),)
. Voir la section 4.1 de modules.txt
.
Si vous ne disposez pas d'un Kbuild
fichier déjà et que vous voulez passer à avoir une, lecture de §4.1 modules.txt
. Avoir un fichier Kbuild
est légèrement plus clair. Ne mettez rien qui s'applique au noyau dans votre maquillage principal, autre qu'une règle d'appel make -C $(KERNELDIR) M=$(pwd)
. Dans Kbuild
, le minimum dont vous avez besoin est la liste des modules que vous construisez (souvent juste celui) et une liste de fichiers à inclure dans votre module, plus une déclaration de dépendance:
EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h
Traditionnellement la voie à #include
Les fichiers avec des chemins par rapport au répertoire du code source actuel consiste à utiliser des guillemets plutôt que des crochets:
#include <stdio.h>
#include "mygreatfunctions.h"
Dans ce cas, le premier #include
Référencera le chemin de recherche du compilateur (qui, dans le cas de GCC, est contrôlé par le -I
Commutateur de ligne de commande), alors que la seconde apparaît dans le répertoire contenant le fichier source avec le #include
.
Ces chemins peuvent aussi être relatifs. Donc, dans src/mod/mymod.c, vous pouvez dire:
#include "../inc/mymod.h"
et il devrait "travailler juste".
Je ne sais pas si cela est une pratique courante dans l'arbre du noyau de Linux, mais c'est sûrement mieux que de vous brouiller avec le chemin incluant, qui pourrait avoir un nombre quelconque d'effets secondaires inattendus.