Makefile自學

MakeFile的規則

  1. 若是這個工程沒有編譯過,那麼咱們的全部C文件都要編譯並被連接。
  2. 若是這個工程的某幾個C文件被修改,那麼咱們只編譯被修改的C文件,並連接目標程序。
  3. 若是這個工程的頭文件被改變了,那麼咱們須要編譯引用了這幾個頭文件的C文件,並連接目標程序。

makefile文件定義的規則以下:ui

target... : prerequisites ...spa

          command操作系統

  1. target也就是一個目標文件,能夠是Object File,也能夠是執行文件。還能夠是一個標籤(Label)。
  2. prerequisites就是,要生成那個target所須要的文件或是目標。
  3. command也就是make須要執行的命令。(任意的Shell命令)。

這是一個文件的依賴關係,也就是說,target這一個或多個的目標文件依賴於prerequisites中的文件,其生成規則定義在command中。說白一點就是說,prerequisites中若是有一個以上的文件比target文件要新的話,command所定義的命令就會被執行。這就是Makefile的規則。也就是Makefile中最核心的內容。.net

make是如何工做的?

在默認的方式下,也就是咱們只輸入make命令。那麼,會進行以下的步驟:code

  1.   make會在當前目錄下找名字叫「Makefile」或「makefile」的文件。
  2.   若是找到,它會找文件中的第一個目標文件(target),並把這個文件做爲最終的目標文件。
  3.   若是第一個目標文件不存在,或是它所依賴的後面的 .o 文件的文件修改時間要比這個文件新,那麼,他就會執行後面所定義的命令來生成這個文件。
  4.   若是目標文件所依賴的.o文件也不存在,那麼make會在當前文件中找目標爲.o文件的依賴性,若是找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程)
  5.   固然,你的C文件和H文件是存在的啦,因而make會生成 .o 文件,而後再用 .o 文件聲明make的終極任務,也就是執行文件了。

以下一個makefile樣例:blog

反斜槓(\)是換行符的意思。這樣比較便於Makefile的易讀。咱們能夠把這個內容保存在文件爲「Makefile」或「makefile」的文件中,而後在該目錄下直接輸入命令「make」就能夠生成執行文件edit。若是要刪除執行文件和全部的中間目標文件,那麼,只要簡單地執行一下「make clean」就能夠了。get

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

在定義好依賴關係後,後續的那一行定義瞭如何生成目標文件的操做系統命令,必定要以一個Tab鍵做爲開頭。記住,make並無論命令是怎麼工做的,他只管執行所定義的命令。make會比較targets文件和prerequisites文件的修改日期,若是prerequisites文件的日期要比targets文件的日期要新,或者target不存在的話,那麼,make就會執行後續定義的命令。it

這裏要說明一點的是,clean不是一個文件,它只不過是一個動做名字,有點像C語言中的lable同樣,其冒號後什麼也沒有,那麼,make就不會自動去找文件的依賴性,也就不會自動執行其後所定義的命令。要執行其後的命令,就要在make命令後明顯得指出這個lable的名字。編譯

makefile中使用變量

咱們在makefile一開始就這樣定義:class

    objects = main.o kbd.o command.o display.o \

             insert.o search.o files.o utils.o

因而,咱們就能夠很方便地在咱們的makefile中以「$(objects)」的方式來使用這個變量了,因而咱們的改良版makefile就變成下面這個樣子:

objects = main.o kbd.o command.o display.o \
             insert.osearch.o files.o utils.o 
   edit : $(objects)
           cc -o edit $(objects)
   ......
因而若是有新的 .o 文件加入,咱們只需簡單地修改一下 objects 變量就能夠了。

讓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
 
   .PHONY : clean
   clean :
           rm edit $(objects)

那麼多的重複的[.h],能不能把其收攏起來?看如下新的文件

   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
 
   .PHONY : clean
   clean :
           rm edit $(objects)

這種風格,讓咱們的makefile變得很簡單,但咱們的文件依賴關係就顯得有點凌亂了。

今天就先學這麼多。

參考自:http://blog.csdn.net/ruglcc/article/details/7814546/

相關文章
相關標籤/搜索