
次のソースファイルを含むモジュールがあるとしますmymod
。
src/mod/mymod.c
src/inc/mymod.h
次のようにmymod.hを含めてみました。
#include <mymod.h>
私のメイクファイルには次のものが含まれていますが、EXTRA_CFLAGS= -I$(shell pwd)/../inc/
カーネルを作成するとエラーメッセージが表示されます。
mymod.hが見つかりません
その理由は、カーネルモジュールを作成するときに次のコマンドがmakefileで実行されるためです(make
V1を使用)。
make -C <path/to/linux/src> M=<path/to/mymod> modules
他の作品では私が望む内容ではない$(shell pwd)
のにコンテンツが拡張されました。ソースツリーを指すパラメータを<path/to/linux>
どのように指定しますか?-I
src/inc
mymod
答え1
Linuxカーネルmakefileは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
もう少し明確になります。呼び出し規則を除いて、カーネルに適用されるものはデフォルトのmakefileに入れないでください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
答え2
#include
伝統的に、現在のソースコードディレクトリへの相対パスを持つファイルをインポートする方法は、山カッコの代わりに引用符を使用することです。
#include <stdio.h>
#include "mygreatfunctions.h"
この場合、最初は#include
コンパイラのインクルード検索パス( gccの場合はコマンドラインスイッチで制御されます-I
)を参照し、2番目は#include
これらの経路は相対的であってもよい。したがって、src/mod/mymod.cで次のように言うことができます。
#include "../inc/mymod.h"
「ただ働く」必要があります。
これがLinuxカーネルツリーで一般的な慣行であるかどうかはわかりませんが、意図しない副作用が多く発生する可能性のあるインクルードパスを混乱させるよりもはるかに優れています。