2017-06-01 28 views
1

我有一個足夠大的項目,可以通過目錄對文件進行分類。我試圖建立一個一個內核模塊。如何鏈接其他目錄中的文件?

documentation狀態如下:

--- 3.6 Descending down in directories 

A Makefile is only responsible for building objects in its own 
directory. Files in subdirectories should be taken care of by 
Makefiles in these subdirs. The build system will automatically 
invoke make recursively in subdirectories, provided you let it know of 
them. 

To do so, obj-y and obj-m are used. 
ext2 lives in a separate directory, and the Makefile present in fs/ 
tells kbuild to descend down using the following assignment. 

Example: 
    #fs/Makefile 
    obj-$(CONFIG_EXT2_FS) += ext2/ 

If CONFIG_EXT2_FS is set to either 'y' (built-in) or 'm' (modular) 
the corresponding obj- variable will be set, and kbuild will descend 
down in the ext2 directory. 

然而,這似乎是從我需要什麼不同。這是兩個獨立的.ko文件;每個目錄中有一個,每個目錄文件在其自己的目錄中合併。

這是我的項目(簡體):

root directory 
| 
+--- Makefile 
| 
+--- foo.c 
| 
+--- subdir 
     | 
     +--- Makefile 
     | 
     +--- bar.c 

我會認爲像這樣的東西碰得將是合理的:

root directory 
| 
+--- Makefile 
| 
+--- foo.c 
| 
+--- foo.o (containing foo.c's stuff) 
| 
+--- subdir 
|  | 
|  +--- Makefile 
|  | 
|  +--- bar.c 
|  | 
|  +--- bar.o (containing bar.c's stuff) 
| 
+--- kernel-module.ko (containing foo.o and subdir/bar.o) 

我真的結束了是這樣的:

root directory 
| 
+--- Makefile 
| 
+--- foo.c 
| 
+--- foo.o (containing foo.c's stuff) 
| 
+--- subdir 
|  | 
|  +--- Makefile 
|  | 
|  +--- bar.c 
|  | 
|  +--- bar.o (containing bar.c's stuff) 
|  | 
|  +--- bar.ko (containing bar.o) 
| 
+--- kernel-module.ko (containing only foo.o) 

我希望每個目錄建立一個模塊不是K的基本假設構建的設計。運輸幾個模塊聽起來像是一團糟,沒有收穫。

這是我的根Makefile

KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build 

obj-m += kernel-module.o 
obj-m += subdir/ 
kernel-module-objs += foo.o 

all: 
    make -C ${KERNEL_DIR} M=$$PWD 
modules: 
    make -C ${KERNEL_DIR} M=$$PWD [email protected] 
clean: 
    make -C ${KERNEL_DIR} M=$$PWD [email protected] 

這是subdir/Makefile

obj-m += bar.o 

這是foo.c

int external_function(void); 

int test(void) 
{ 
    return external_function(); 
} 

這是subdir/bar.c

int external_function(void) 
{ 
    return 4; 
} 

make(根目錄)吐以下警告:

WARNING: "external_function" [(...)/kernel-module.ko] undefined! 

而我試圖插入kernel-module.ko被拒絕:

$ sudo insmod kernel-module.ko 
insmod: ERROR: could not insert module kernel-module.ko: Unknown symbol in module 
$ dmesg | tail -1 
[11688.540153] kernel_module: Unknown symbol external_function (err 0) 

我怎麼告訴kbuild的是subdir/bar.o應該成爲kernel-module.ko的一部分,而不是它自己的模塊?

+0

該文檔中的建議不好,或者至少不清楚。你的源文件是'foo.c','bar.c'和'bar.h';他們在哪?你想在頂部目錄或'subdir /'或'build /'或其他地方使用目標文件'foo.o'和'bar.o'嗎?同樣,你想在哪裏最終產品'outside.ko'? – Beta

+0

@貝塔:感謝您的提問。我在編輯時找到了解決方案。但爲了完整起見,以下是您的答案:'foo.c'位於根目錄中,'bar.c'屬於'subdir /'。生成的文件最終不在這個問題的範圍內;我更關心他們的內容。我真的希望他們最終會在'build /'中,但看到我的編輯可以接受的結果。 –

+0

@Beta:另外:關於'bar.h',我最終把它從問題中刪除了,因爲它是不需要的。關鍵是,foo可以看到酒吧的聲明,但不是它的定義。 –

回答

0

一個解決方案是將bar的目標文件追加到內核模塊的目標列表中。這段代碼的問題:

obj-m += kernel-module.o 
obj-m += subdir/ 
kernel-module-objs += foo.o 

的是,它告訴kbuild的下降到subdir/,但它不告訴它包括在kernel-module的那個結果。

這將解決這個問題:

obj-m += kernel-module.o 
obj-m += subdir/ 
kernel-module-objs += foo.o subdir/bar.o 

但是,因爲它打破了DRY原則,我不喜歡這樣的解決方案都:這意味着bar.o已被命名爲兩次;一個在/Makefile,另一個在/subdir/Makefile

此外,此解決方案不會阻止Kbuild創建冗餘subdir/bar.ko模塊。

最後,某些documentation指出這是「不推薦的做法」,因爲某些完全沒有說明的原因。

所以這個解決方案非常糟糕。我不認爲我會堅持下去。


另一種解決方案(其與前一個分支)是隻刪除subdir/Makefile和,根生成文件內,而不是這樣的:

obj-m += kernel-module.o 
obj-m += subdir/ 
kernel-module-objs += foo.o 

做到這一點:

obj-m += kernel-module.o 
kernel-module-objs += foo.o subdir/bar.o 

這解決了DRY問題,並防止產生subdir/bar.ko,但仍受到不鼓勵的練習。

在此期間我會堅持這個解決方案,但既然他們都不是理想的,我想我會留下一段時間的問題。

+0

我同意不鼓勵這種做法。 – 0andriy

+0

@ 0andriy whyyy? –

相關問題