有時候看到一段程式碼裡有一大堆#include
如下:
#include < linux/init.h >
#include < linux/spinlock.h >
#include < linux/workqueue.h >
#include < linux/delay.h >
#include < linux/errno.h >
#include < linux/err.h >
#include < linux/clk.h >
#include < linux/platform_device.h >
#include < linux/spi/spi.h >
#include < linux/spi/spi_bitbang.h >
#include < asm/io.h >
#include < asm/dma.h >
#include < asm/hardware.h >
#include < asm/arch/regs-gpio.h >
#include < asm/plat-s3c24xx/regs-spi.h >
#include < asm/arch/spi.h >
有時候我會在好幾個地方看到一樣的東西
那到底編譯時用的是哪一個,該如何知道?
kernel src code裡應該有個include 資料夾,kernel code裡的include linux/spi/spi.h 應該就是 kernel src dir裡的include/spi/spi.h,header file的路徑設定方式 1. gcc預設 2. Makefile特別指定。像我的kernel 最上層Makefile裡有一段
回覆刪除# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-include include/linux/autoconf.h
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
先說明一下,雖然你可能已經知道了:
對gcc 而言,如果要多增加include path,可以下參數 -Imypath: 這樣gcc就會去mypath這個路徑搜尋標頭檔。如果有多個path: -Imypath1 mypath2 mypath3
然後,讓我們看看那一段Makefile在做什麼:
LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -include include/linux/autoconf.h
這裡先定義一個變數LINUXINCLUDE ,其值為-Iinclude 加上後面的
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -include include/linux/autoconf.h
所產生output。
在Makefile裡面,變數值的表示方式: $(var)。
這裡的 if 是Makefile 的 if function,別跟shell script的if搞錯了
if $(KBUILD_SRC),-Iinclude2
的意思是,如果 KBUILD_SRC 這個變數有值,傳回-Iinclude2。
所以
LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -include include/linux/autoconf.h
的意思是說,如果 KBUILD_SRC 變數有值,
定義 LINUXINCLUDE 為: -Iinclude -Iinclude2 -I$(srctree)/include) -include include/linux/autoconf.h
這裡的-I$(srctree)/include ,就是一開始提到的kernel src dir裡的include資料夾。所以才說 include linux/spi/spi.h 應該就是kernel src dir裡的include/spi/spi.h
LINUXINCLUDE 最後會被export出來變環境變數,
export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
最後gcc 在build 個別.c 的時候,就會用到LINUXINCLUDE,所以 gcc知道要去include, include2, $(srctree)/include......
先謝謝學姐!我覺得我真的找到救星了,真是感人T_T
回覆刪除之後還要麻煩學姐照顧了m(_ _)m
把學姐寫的看過一遍,我在想我大概要多看幾遍才會懂orz
這大部分是makefile的語法嗎?
另外
我想問一個問題
就是學姐一開始提到的那個"kernel code"指的是?
是說只要是driver module之類的
都算是嗎?
所以我要區分為kernel code和user code?
謝謝!!
是阿,都是Makefile的語法,Makefile寫起來可以寫得超複雜@@,不過如果想要知道header file的include path,搜尋-I 就對了。
回覆刪除kernel module是kernel src code的一部份,具有一些異於user base的code特型,像無法使用libc,因為它只認識kernel的code(不能使用printf要使用printk, 不能使用malloc要使用kmalloc...),所以在kernel code裡從來都不會看到include "stdio.h"之類的。Linux的device driver用kernel module的方式寫的話,就是kernel code ,算是kerenl 的一部份。
我不會的還有很多@@,像我就沒自己裝過tool chain,都用人家已經安裝好的@@ 請多多指教,一起學習。
現在的 Makefile 也不會是作者自己打的
回覆刪除有很多套件可以自動產生 Makefile
目前 cmake 好像還蠻紅的
可以去玩玩看 XD