[英]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.ko
: hello
。
作為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
為了在所有文件下面的完整性,應該使用make
或make 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.