簡體   English   中英

如何正確鏈接KBuild Makefiles以在內核模塊中構建子文件夾

[英]How to chain KBuild Makefiles properly to build subfolders inside kernel module

我有一個內核模塊(通常使用CONFIG_MYMODULE = m編譯),其設置如下:

mymodule/Makefile
../foo/Makefile
../foo/component1/Makefile
../foo/component2/Makefile

目前正在使用的是:

MyModule的/ Makefile文件:

mymodule-y += mod1file.o mod2file.o mod3file.o #etc
include ../foo/Makefile
mymodule-y += $(FOO_FILES)
obj-$(CONFIG_MYMODULE) += mymodule.o

../foo/Makefile:

include component1/Makefile
include component2/Makefile

在我擁有的每個組件文件夾中:

../foo/component1/Makefile

FOO_FILES += foo1file.o foo2file.o foo3file.o #etc

這絕對不是正確的解決方法,因為所有內容都直接包含在mymodule / Makefile中,因此無法設置特定於文件夾的gcc標志。

在將所有內容構建到單個內核模塊中的同時組織這個的正確方法是什么? 我已經閱讀了kbuild / modules.txt文檔,但我沒有看到任何直接相關的內容,而且我無法弄清楚如何解決這個問題,或者它確實可行。

謝謝


我嘗試了以下內容,但是我收到以下錯誤:

“ld:找不到foo:文件格式無法識別”

MyModule的/ Makefile文件:

mymodule-y += mod1file.o mod2file.o mod3file.o #etc
mymodule-y += ../foo/
obj-$(CONFIG_MYMODULE) += mymodule.o

../foo/Makefile

ccflags-y := -I$(src)/component1/ -I$(src)/component2/
foo-y := foo1file.o foo2file.o foo3file.o
foo-y += component1
foo-y += component2

../foo/component1/Makefile

component1-y := component1file.o component1file.o

../foo/component2/Makefile

component2-y := component2file.o component2file.o

如果我改為使用obj-y + = ../foo而不是mymodule-y + = ../foo它至少進入文件夾,但似乎沒有嘗試編譯,我希望這是單個內核模塊的所有部分。

這似乎並不太難。

MyModule的/ Makefile文件:

...
include ../foo/Makefile
...
# whatever rules use the folder-specific flags:
foo:
    gcc blah blah $(FOLDERFLAGS) blah

../foo/component1/Makefile:

FOLDER_FILES := foo1file.o foo2file.o foo3file.o #etc
$(FOLDER_FILES): FOLDER_FLAGS=folder_1_flag
FOO_FILES += FOLDER_FILES

../foo/component2/Makefile:

FOLDER_FILES := foo20file.o foo21file.o foo22file.o #etc
$(FOLDER_FILES): FOLDER_FLAGS=folder_2_flag
FOO_FILES += FOLDER_FILES

這足以滿足您的目的嗎?

您可以使用subdir-extra-y來獲取父目錄,但這只是一個開銷,每個目錄仍然無法使用ccflags。 也許正確的方法是將組件作為子模塊,依賴於mymodule。

我會將模塊構建在頂層目錄mymodule/Makefile ,很容易從一個目錄構建多個模塊但我沒有發現子目錄中多個對象的一個​​模塊(也許保持一個干凈的設計策略,或者這樣更簡單)。

obj-m定義要構建的內核模塊列表(在下面的示例中只有一個: hello.ko ,名為hello.o但會輸出hello.ko

hello-objs hello.ko使用相同的名稱定義要鏈接的編譯對象列表以獲取hello.kohello

作為Makefile很容易有條件地鏈接對象(參見CONFIG_HELLO_COMPONENT1

最終,如果每個組件有很多對象,並且我們希望保持頂級Makefile清潔,我們仍然可以使用include但只是有條件地將對象添加到hello-objs ccflags-y並將標志添加到ccflags-y (或者任何需要的變量,只是不是obj-* ) 。

CFLAGS_$*.o (見下文)可用於設置每個對象的cflags,但它不支持路徑,因此不同目錄中具有相同名稱的對象將具有相同的標志。

mymodule/Makefile

ifeq ($(CONFIG_HELLO_COMPONENT1), y)
 ccflags-y += -I$(src)/foo/component1 -DCONFIG_HELLO_COMPONENT1
endif
ccflags-y += -I$(src)/foo/component2

obj-m += hello.o

CFLAGS_component2.o += -DTEST_CFLAGS

hello-objs = hello-1.o
ifeq ($(CONFIG_HELLO_COMPONENT1), y)
 hello-objs += foo/component1/component1.o
endif
hello-objs += foo/component2/component2.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

為了在所有文件下面的完整性,應該使用makemake CONFIG_HELLO_COMPONENT1=y來構建和工作。

mymodule/hello-1.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#ifdef CONFIG_HELLO_COMPONENT1
#include <component1.h>
#endif
#include <component2.h>
static int __init init_hello(void) {
#ifdef CONFIG_HELLO_COMPONENT1
    component1();
#endif
    component2();
    printk(KERN_INFO "Hello world 1.\n");
    return 0;
}
static void __exit cleanup_hello(void) {
    printk(KERN_INFO "Goodbye world 1.\n");
}
module_init(init_hello);
module_exit(cleanup_hello);

mymodule/foo/component2/component2.h

#ifndef COMPONENT2_H
#define COMPONENT2_H
void component2(void);
#endif

mymodule/foo/component2/component2.c

#include <linux/kernel.h>
void component2(void) {
    printk(KERN_INFO "component2\n");
}

mymodule/foo/component1/component1.h

#ifndef COMPONENT1_H
#define COMPONENT1_H
void component1(void);
#endif

mymodule/foo/component1/component1.c

#include <linux/kernel.h>
void component1(void) {
    printk(KERN_INFO "component1\n");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM