Linuxカーネルモジュールにローカルヘッダーファイルを含める方法


17

mymod次のようなソースファイルを含むモジュールがあるとします。

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

私は次のようにmymod.hをインクルードしようとします

#include <mymod.h>

メイクファイルには含まれてEXTRA_CFLAGS= -I$(shell pwd)/../inc/いますが、カーネルが作成されると、次のようなエラーが表示されます。

mymod.hが見つかりません

その理由は、カーネルモジュールが作成されると、このコマンドがmakefileから実行されるためだと思われます:(makeV1 を使用):

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

他の作品では私$(shell pwd)はに拡張されました<path/to/linux>。これは私が望むものではありません。どのようにして指定することができます-Iを指すようにパラメータをsrc/inc私のmymodソースツリー?

回答:


19

LinuxカーネルのメイクファイルはKbuildフレームワークを使用します。これらはGNU makeによって解釈されますが、Kbuildは固有の使用規則を持つ多数のマクロセットで構成されているため、一般的なmakefileのガイドラインは適用されません。Kbuildの良い点は、タスクの複雑さを考慮して、ほとんど定型文を必要としないことです。

Kbuildは、カーネルソースのに記載されていますDocumentation/kbuild。モジュールライターとして、特に読む必要がありますmodules.txt(少なくとも他のものをざっと読んでください)。

変数を使用$(shell pwd)すると展開されるため、現在実行していることは機能しませんEXTRA_CFLAGS。makefileはモジュールのディレクトリからではなくカーネルソースツリーから実行されるため(これはKbuildの多くの非自明な側面の1つです)、間違ったディレクトリを選択しています。

ツリー外モジュールでインクルードディレクトリを指定する公式のイディオムは、§5.3にありmodules.txtます。src変数は、あなたのモジュールのトップレベルのディレクトリに設定されています。したがって:

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

この宣言Kbuildは、モジュールツリーのルートで呼び出されるファイルにある必要があることに注意してください。(srcディレクトリをモジュールツリーのルートと見なすことができます。その場合は、Kbuildそこに置き、上記の値をで置き換えます-I$(src)/inc)。それらをに入れることも可能ですMakefileが、この定義は(カーネルモジュールの構築時にのみ適用されるものであれば)条件付きディレクティブ内にある必要がありますifeq ($(KERNELRELEASE),)。§4.1を参照してくださいmodules.txt

Kbuildまだファイルをお持ちでなく、そのファイルに切り替えたい場合は、§4.1をお読みくださいmodules.txt。別個のKbuildファイルを持つことは、わずかに明確です。を呼び出す規則以外は、メインメイクファイルにカーネルに適用されるものを置かないでくださいmake -C $(KERNELDIR) M=$(pwd)。ではKbuild、構築するモジュールのリスト(多くの場合1つだけ)と、モジュールに含めるファイルのリスト、および依存関係宣言が必要です。

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

評判が不十分だったため、投稿を更新できませんでした。
オムナラシンハン

1
@Om Narasimhan:これが解決策を見つけるのに役立ったなら、答えを受け入れられたものとしてマークするべきです。
CVn

1

従来、#include現在のソースコードのディレクトリに相対的なパスを持つファイルを表示する方法は、山括弧ではなく引用符を使用することです。

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

この場合、1つ目#includeはコンパイラのインクルード検索パス(gccの場合は-Iコマンドラインスイッチによって制御されます)を参照し、2つ目はでソースファイルを含むディレクトリを検索します#include

このようなパスも相対パスになります。src / mod / mymod.cでは、次のように言うことができます。

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

そして、それは「うまくいく」はずです。

これがLinuxカーネルツリーで一般的な慣行であるかどうかはわかりませんが、インクルードパスをいじり回すよりも良いのは確かです。


1
一般的には良いアドバイスですが、Linuxカーネルのメイクファイルは非常に独特です。Kbuildと呼ばれるかなり複雑なマクロのセットを呼び出します。多くの場合、Kbuildをmakeとはまったく異なる言語ですが、まったく同じではない言語として扱うことをお勧めします。
ジル「SO-悪であるのをやめる」

1
案の定、しかし、いくつかの設定されたディレクトリセットで<foo>を探し、最初に現在のディレクトリを探し、次に前述のパスにフォールバックする「bar」のCコンパイラの動作は、奇妙な意味とは異なりませんそもそもコンパイラー。
フォンブランド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.