Linux çekirdek modülüne yerel başlık dosyaları nasıl eklenir


17

Diyelim ki mymodkaynak dosyaları olan bir modülüm var:

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

Mymod.h dosyasını aşağıdaki gibi eklemeye çalışıyorum

#include <mymod.h>

Dosyam içeriyor EXTRA_CFLAGS= -I$(shell pwd)/../inc/ancak çekirdek yapıldığında şunu belirten bir hata alıyorum:

mymod.h bulunamadı

Bunun nedeni, çekirdek modülleri yapıldığında bu komutun makefile'dan çalıştırılmasıdır ( makeV1 kullanarak ):

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

Diğer işlerde $(shell pwd)genişledim <path/to/linux>. İstediğim bu değil. Nasıl belirtebilirsiniz -Inoktaya parametreyi src/incbenim bir mymodkaynak ağacının?

Yanıtlar:


19

Linux çekirdek markaları Kbuild çerçevesini kullanır. Bunlar GNU markası tarafından yorumlanmasına rağmen, Kbuild kendine özgü kullanım kurallarına sahip çok sayıda makrodan oluşur, bu nedenle tipik makefile yönergeleri geçerli değildir. Kbuild ile ilgili güzel olan şey, görevin karmaşıklığını göz önünde bulundurarak çok az kazan plakasına ihtiyaç duymanızdır.

Kbuild, içindeki çekirdek kaynağında belgelenmiştir Documentation/kbuild. Bir modül yazarı olarak, özelliklemodules.txt (ve en azından diğerlerini gözden geçirmelisiniz).

Şu anda yaptığınız şey çalışmıyor çünkü değişken kullanıldığında $(shell pwd)genişliyor EXTRA_CFLAGS. Makefile modülünüzün dizininden ziyade çekirdek kaynak ağacından çalıştığından (bu, Kbuild'in pek çok açık olmayan yönlerinden biridir), yanlış dizini alıyor.

Ağaç dışı bir modül içindeki dizinleri belirtmek için resmi deyim, §5.3 modules.txt. srcDeğişken sizin modülün toplevel dizinine ayarlanır. Bu nedenle:

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

Bu bildirimin Kbuildmodül ağacınızın kökünde çağrılan bir dosyada olması gerektiğini unutmayın . ( srcDizinin modül ağacınızın kökü olduğunu düşünebilirsiniz ; öyleyse, Kbuildburaya koyun ve yukarıdaki değeri değiştirin -I$(src)/inc). Onları a'ya koymak da mümkündür Makefile, ancak bu tanımın (sadece bir çekirdek modülü oluştururken geçerli olan herhangi bir şey olduğu sürece) koşullu bir yönerge içinde olması gerektiğini unutmayın ifeq ($(KERNELRELEASE),). Bkz.modules.txt .

KbuildZaten bir dosyanız yoksa ve bir dosyaya geçmek istiyorsanız, §4.1 modules.txt. Ayrı bir Kbuilddosyaya sahip olmak biraz daha nettir. Ana kuralınızdaki çekirdek için geçerli bir çağırma kuralı dışında hiçbir şey koymayın make -C $(KERNELDIR) M=$(pwd). Olarak Kbuild, size gereken asgari Sen yapı modüllerinin listesi (genellikle sadece bir) ve modülünde dahil etmek dosyaların bir listesini, artı bir bağımlılık beyanıdır:

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

Yeteri kadar itibarım olmadığından yazıyı güncelleyemedim.
Om Narasimhan

1
@Om Narasimhan: Eğer bu çözümü bulmanıza yardımcı olduysa, cevabı kabul edilmiş olarak işaretlemelisiniz.
CVn

1

Geleneksel #includeolarak, geçerli kaynak kodunun dizinine göre yolları olan dosyalara giden yol, açılı ayraçlar yerine tırnak işaretleri kullanmaktır:

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

Bu durumda, birincisi #includederleyicinin içerdiği arama yoluna (gcc durumunda -Ikomut satırı anahtarı tarafından kontrol edilir ) referans verirken, ikincisi kaynak dosyayı içeren dizine bakacaktır.#include .

Bu yollar da göreli olabilir. Yani src / mod / mymod.c'de şunları söyleyebilirsiniz:

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

ve "sadece işe yarar".

Bunun Linux çekirdek ağacında yaygın bir uygulama olup olmadığını bilmiyorum, ancak elbette, herhangi bir sayıda istenmeyen yan etkisi olabilen içerme yolu ile uğraşmaktan daha iyidir.


1
Genel olarak iyi tavsiyeler, ancak Linux çekirdek markaları çok tuhaftır. Kbuild adında oldukça karmaşık bir makro seti çağırıyorlar; Kbuild'e neredeyse tamamen farklı bir dil olarak davranmak en iyisidir.
Gilles 'SO- kötü olmayı bırak

1
Tabii ki, ama C derleyici bazı yapılandırılmış dizin kümesinde <foo> arama davranışı ve "bar" için önce geçerli dizine bakmak ve sonra daha önce belirtilen yola geri düşme tuhaf anlamına gelir değişmez derleyici ilk etapta.
vonbrand
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.