$ cat makefile
.SUFFEXES:.c .o
.c.o:
gcc -Wall -c $<
OBJS=my_file.o
all: my_exec_file
my_exec_file:$(OBJS)
gcc -Wall $(OBJS) -o $@
$ make
gcc -Wall -c my_file.c
gcc -Wall my_file.o -o my_exec_file
簡單說明:
.SUFFEXES:.c .o :告訴make識別哪些源程序和目標程序
.c.o: :告訴make命令.c程序如何生成.o文件,採用其下的gcc -Wall -c $<($<代表任意一個編譯時用到的.c文件)命令。
all: my_exec_file :告訴make命令自動生成哪個可執行程序
my_exec_file:$(OBJS) :告訴make命令如何生成my_exec_file文件,需要哪些目標代碼($(OBJS)),採用其下的命令: gcc -Wall $(OBJS) -o $@ ($@代表my_exec_file,即要編譯的可執行文件名)
㈡ 如何在Makefile中定義宏進行條件編譯
你可以藉助BASHSHELL強大的字元串處理能力來實現啊!
比如你可以將你想定義的「宏」放在makefile.include中,然後將其賦值,而在makefile中加入include makefile.include一行,在其後需要進行條件預編譯時進行字元串比較來實現啊!
㈢ 編寫一個簡單的 makefile 文件
makefile文件裡面主要有三種內容:
1.變數聲明:
變數聲明就是一種基本的嚴格字元替換的操作。
比如在前面聲明了:objects=program.o foo.o utils.o
那麼在後面出現的所有$(objects)或者${objects}都會被自動替換成上面的那個字元序列,而且是嚴格替換,即不帶空格的。
2.映射法則
3.命令:
映射法則和命令通常都是聯合起來組成這樣的結構形式:
target... : prerequisites..
command
可以簡單地理解為通過prerequisites,也就是先決的依賴文件,採取後面描述的相應的命令(這里的命令都是linux里的shell命令)command之後(一般是)生成了文件target。命令的前面都要按以下tab建留一段空白來表示它是命令。
有的target後面並沒有先決條件,也就是後面的命令是無條件執行的。
makefile 文件c語言程序:
#include <linux/init.h>
#include <linux/mole.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
mole_init(hello_init);
mole_exit(hello_exit);
makefile:
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR ?= /lib/moles/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) moles
endif
㈣ 用makefile編輯的文件怎麼編譯
我們在linux下進行編程的時候,會發現我們沒有工程文件,然後,我們在不同目錄下
的文件如此雜亂無章,讓我們感到頭疼,怎麼可以把它們進行同步在一起,然後,一起進行編譯呢,
這里,就是我們需要用到的工具了,makefile文件的作用了,makefile可以有效地組織文件和目錄,
把處於不同目錄下的文件進行同時編譯,而不會因為目錄的不同,而有所差別。
這里,我來分享一下makefile的簡單的用法。
1:基本的格式:
magproc:magproc.o dbproc.o
$(EC) -o $(BINPATH)/$@ $? $(LIB)
可執行文件名:鏈接文件
編譯工具 (參數) (鏈接庫) 文件名
2:工程文件Make.defines
3:makefile文件
http://jingyan..com/article/48206aeaf9e82e216ad6b335.html
㈤ 如何寫Makefile
相信很多朋友都有過這樣的經歷,看著開源項目中好幾頁的makefile文件,不知所雲。在日常學習和工作中,也有意無意的去迴避makefile,能改就不寫,能用ide就用ide。其實makefile並沒有想像的那麼難寫,只要你明白了其中的原理,自己實踐幾次。你也可以自己寫makefile,讓別人對你頭來羨慕的目光。
下面本人介紹一下自己的學習成果,初學階段,歡迎大家多多指正。
簡單的說,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要後編譯,哪些文件需要重新編譯,甚至可以在makefile中執行shell腳本。makefile帶來的好處就是——「自動化編譯」,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟體開發的效率。
關於程序的編譯和鏈接
一般來說,無論是C還是C++,首先要把源文件編譯成中間代碼文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,這個動作叫做編譯(compile),一般來說,每個源文件都應該對應於一個中間目標文件(O文件或是OBJ文件)。然後再把大量的Object File合成執行文件,這個動作叫作鏈接(link)。
編譯時,編譯器需要的是語法的正確,函數與變數的聲明的正確。對於後者,通常是你需要告訴編譯器頭文件的所在位置(頭文件中應該只是聲明,而定義應該放在C/C++文件中),只要所有的語法正確,編譯器就可以編譯出中間目標文件。
鏈接時,主要是鏈接函數和全局變數,所以,我們可以使用這些中間目標文件(O文件或是OBJ文件)來 鏈接我們的應用程序。鏈接器並不管函數所在的源文件,只管函數的中間目標文件(Object File),在大多數時候,由於源文件太多,編譯生成的中間目標文件太多,而在鏈接時需要明顯地指出中間目標文件名,這對於編譯很不方便,所以,我們要給 中間目標文件打個包,在Windows下這種包叫「庫文件」(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。
下面我們開始看看如何自己寫出makefile。
Makefile的規則
目標 : 需要的條件 (注意冒號兩邊有空格)
命令(注意前面用tab鍵開頭)
解釋一下:
1 目標可以是一個或多個,可以是Object File,也可以是執行文件,甚至可以是一個標簽。
2 需要的條件就是生成目標所需要的文件或目標
3 命令就是生成目標所需要執行的腳本
總結一下,就是說一條makefile規則規定了編譯的依賴關系,也就是目標文件依賴於條件,生成規則用命令來描述。在編譯時,如果需要的條件的文件比目標更新的話,就會執行生成命令來更新目標。
下面舉個簡單的例子說明。如果一個工程有3個頭文件,和8個C文件,我們為了完成前面所述的那三個規則,我們的Makefile應該是下面的這個樣子的。
edit : main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
將上面的內容寫入到Makefile文件中,然後執行make就可以進行編譯,執行make clean就可以刪除所有目標文件。解釋一下,也就是說生成最終的目標文件edit,依賴於一系列的.o目標文件,而這些.o文件又是需要用源文件來編譯生成的。
需要注意的是,clean後面沒有條件,而clean本身也不是文件,它只不過是一個動作名字,其冒號後什麼也沒有,那麼,make就不會自動去找文件的依賴性,也就不會自動執行其後所定義的命令。
make是如何工作的
在默認的方式下,也就是我們只輸入make命令。那麼,
1、make會在當前目錄下找名字叫「Makefile」或「makefile」的文件。
2、如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到「edit」這個文件,並把這個文件作為最終的目標文件。
3、如果edit文件不存在,或是edit所依賴的後面的 .o 文件的文件修改時間要比edit這個文件新,那麼,他就會執行後面所定義的命令來生成edit這個文件。
4、如果edit所依賴的.o文件也不存在,那麼make會在當前文件中找目標為.o文件的依賴性,如果找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程)
5、當然,你的C文件和H文件是存在的啦,於是make會生成 .o 文件,然後再用 .o 文件生命make的終極任務,也就是執行文件edit了。
makefile中使用變數
前面的知識已經足以讓你自己完成一個簡單的makefile了,不過makefile的精妙之處遠不止如此,下面來看看如何在makefile中使用變數吧。
在上面的例子中,先讓我們看看edit的規則:
edit : main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
我們可以看到[.o]文件的字元串被重復了兩次,如果我們的工程需要加入一個新的[.o]文 件,那麼我們需要在兩個地方加(應該是三個地方,還有一個地方在clean中)。當然,我們的makefile並不復雜,所以在兩個地方加也不累,但如果 makefile變得復雜,那麼我們就有可能會忘掉一個需要加入的地方,而導致編譯失敗。所以,為了makefile的易維護,在makefile中我們 可以使用變數。makefile的變數也就是一個字元串,理解成C語言中的宏可能會更好。
於是,我們使用變數objects
objects = main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
這樣一來,原來的makefile變成如下的樣子:
objects = main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
這樣看起來方便多了吧,也更加省事了。如果有新的.o文件怎麼辦?當然是在objects裡面添加了,這樣只需要一處改變,很方便吧。
讓make自動推導
GNU的make很強大,它可以自動推導文件以及文件依賴關系後面的命令,於是我們就沒必要去在每一個[.o]文件後都寫上類似的命令,因為,我們的make會自動識別,並自己推導命令。
只要make看到一個[.o]文件,它就會自動的把[.c]文件加在依賴關系中,如果make找到一 個whatever.o,那麼whatever.c,就會是whatever.o的依賴文件。並且 cc -c whatever.c 也會被推導出來,於是,我們的makefile再也不用寫得這么復雜。我們的是新的makefile又出爐了。
objects = main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
clean :
rm edit $(objects)
當然,如果你覺得那麼多[.o]和[.h]的依賴有點不爽的話,好吧,沒有問題,這個對於make來說很容易,誰叫它提供了自動推導命令和文件的功能呢?來看看最新風格的makefile吧。
objects = main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
clean :
rm edit $(objects)
不過話說回來,本人並不推薦這種方法。雖然簡單,但是這種方法破壞了文件本身的依賴關系。如果文件過多的話,可能你自己都不清楚了。
㈥ 如何在makefile中定義宏進行條件編譯
你可以藉助BASHSHELL強大的字元串處理能力來實現啊!
比如你可以將你想定義的「宏」放在makefile.include中,然後將其賦值,而在makefile中加入include makefile.include一行,在其後需要進行條件預編譯時進行字元串比較來實現啊!
㈦ 如何 編譯 c code mikefile
Makefile 介紹
make命令執行時,需要一個 Makefile 文件,以告訴make命令需要怎麼樣的去編譯和鏈接程序。
首先,我們用一個示例來說明Makefile的書寫規則。以便給大家一個感興認識。這個示例來源於GNU的make使用手冊,在這個示例中,我們的工程有8個C文件,和3個頭文件,我們要寫一個Makefile來告訴make命令如何編譯和鏈接這幾個文件。我們的規則是:
1. 如果這個工程沒有編譯過,那麼我們的所有C文件都要編譯並被鏈接。
2. 如果這個工程的某幾個C文件被修改,那麼我們只編譯被修改的C文件,並鏈接目標程序。
3. 如果這個工程的頭文件被改變了,那麼我們需要編譯引用了這幾個頭文件的C文件,並鏈接目標程序。
只要我們的Makefile寫得夠好,所有的這一切,我們只用一個make命令就可以完成,make命令會自動智能地根據當前的文件修改的情況來確定哪些文件需要重編譯,從而自己編譯所需要的文件和鏈接目標程序。
1.1 Makefile的規則
在講述這個Makefile之前,還是讓我們先來粗略地看一看Makefile的規則。 target ... : prerequisites ...
command
...
...
target也就是一個目標文件,可以是Object
File,也可以是執行文件。還可以是一個標簽(Label),對於標簽這種特性,在後續的「偽目標」章節中會有敘述。
prerequisites就是,要生成那個target所需要的文件或是目標。
command也就是make需要執行的命令。(任意的Shell命令)
這是一個文件的依賴關系,也就是說,target這一個或多個的目標文件依賴於
prerequisites中的文件,其生成規則定義在command中。說白一點就是說,prerequisites中如果有一個以上的文件比target文件要新的話,command所定義的命令就會被執行。這就是Makefile的規則。也就是Makefile中最核心的內容。
說到底,Makefile的東西就是這樣一點,好像我的這篇文檔也該結束了。呵呵。還不盡然,這是Makefile的主線和核心,但要寫好一個Makefile還不夠,我會以後面一點一點地結合我的工作經驗給你慢慢到來。內容還多著呢。:)
1.2 一個示例
正如前面所說的,如果一個工程有3個頭文件,和8個C文件,我們為了完成前面所述的那三個規則,我們的Makefile應該是下面的這個樣子的。
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
反斜杠(\)是換行符的意思。這樣比較便於Makefile的易讀。我們可以把這個內容保存在文件為「Makefile」或「makefile」的文件中,然後在該目錄下直接輸入命令「make」就可以生成執行文件edit。如果要刪除執行文件和所有的中間目標文件,那麼,只要簡單地執行一下「make
clean」就可以了。
在這個makefile中,目標文件(target)包含:執行文件edit和中間目標文件(*.o),依賴文件(prerequisites)就是冒號後面的那些
.c 文件和 .h文件。每一個 .o 文件都有一組依賴文件,而這些 .o 文件又是執行文件 edit
的依賴文件。依賴關系的實質上就是說明了目標文件是由哪些文件生成的,換言之,目標文件是哪些文件更新的。
在定義好依賴關系後,後續的那一行定義了如何生成目標文件的操作系統命令,一定要以一個Tab鍵作為開頭。記住,make並不管命令是怎麼工作的,他只管執行所定義的命令。make會比較targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的話,那麼,make就會執行後續定義的命令。
這里要說明一點的是,clean不是一個文件,它只不過是一個動作名字,有點像C語言中的lable一樣,其冒號後什麼也沒有,那麼,make就不會自動去找文件的依賴性,也就不會自動執行其後所定義的命令。要執行其後的命令,就要在make命令後明顯得指出這個lable的名字。這樣的方法非常有用,我們可以在一個makefile中定義不用的編譯或是和編譯無關的命令,比如程序的打包,程序的備份,等等。
1.3 make是如何工作的
在默認的方式下,也就是我們只輸入make命令。那麼,
1. make會在當前目錄下找名字叫「Makefile」或「makefile」的文件。
2. 如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到「edit」這個文件,並把這個文件作為最終的目標文件。
3. 如果edit文件不存在,或是edit所依賴的後面的 .o
文件的文件修改時間要比edit這個文件新,那麼,他就會執行後面所定義的命令來生成edit這個文件。
4.
如果edit所依賴的.o文件也存在,那麼make會在當前文件中找目標為.o文件的依賴性,如果找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程)
5. 當然,你的C文件和H文件是存在的啦,於是make會生成 .o 文件,然後再用 .o 文件聲明make的終極任務,也就是執行文件edit了。
這就是整個make的依賴性,make會一層又一層地去找文件的依賴關系,直到最終編譯出第一個目標文件。在找尋的過程中,如果出現錯誤,比如最後被依賴的文件找不到,那麼make就會直接退出,並報錯,而對於所定義的命令的錯誤,或是編譯不成功,make根本不理。