Makefile

原文地址:http://blog.csdn.net/yourtommy/article/details/6887686

創建C程序

先寫個c程序,保存在main.c裏:

  1. //////////////////   
  2. // file: main.c   
  3. //////////////////   
  4.   
  5. #include <stdio.h>   
  6.   
  7. int main()  
  8. {  
  9.     int c = 0;  
  10.     printf("Tommy: %d\n", c+5);  
  11.     return 0;  
  12. }  
//////////////////
// file: main.c
//////////////////

#include <stdio.h>

int main()
{
    int c = 0;
    printf("Tommy: %d\n", c+5);
    return 0;
}

看看我這時的目錄結構

  1. ~/code/makefile$ ls  
  2. main.c  
~/code/makefile$ ls
main.c

這時敲個“make”命令試試?
  1. ~/code/makefile$ make  
  2. make: *** 沒有指明目標並且找不到 makefile。 停止。  
~/code/makefile$ make
make: *** 沒有指明目標並且找不到 makefile。 停止。


創建makefile文件

顯然,我們要建個名爲“makefile”的文件。先建一個空的名爲makefile的文件:
  1. ~/code/makefile$ touch makefile  
  2. tommy@tommy-zheng-ThinkPad-T61:~/code/makefile$ ls  
  3. main.c  makefile  
~/code/makefile$ touch makefile
tommy@tommy-zheng-ThinkPad-T61:~/code/makefile$ ls
main.c  makefile
這時再試試“make”命令:
  1. ~/code/makefile$ make  
  2. make: *** 無目標。 停止。  
~/code/makefile$ make
make: *** 無目標。 停止。

加入target
錯誤“無目標”告訴我們需要在makefile裏添加一些東西:
  1. # 註釋 file: makefile  
  2. target:  
# 註釋 file: makefile
target:
再執行“make”命令:
  1. ~/code/makefile$ make  
  2. make: 沒有什麼可以做的爲 `target'。  
~/code/makefile$ make
make: 沒有什麼可以做的爲 `target'。

可以看到前面“無目標”的錯誤已經解決了。


加入命令

繼續往makefile裏添加東西:
  1. # 註釋 file: makefile  
  2. target:  
  3.     gcc -o tommy main.c # 注意,最前面是tab,不是空格!  
# 註釋 file: makefile
target:
	gcc -o tommy main.c # 注意,最前面是tab,不是空格!
好了,執行make命令:
  1. ~/code/makefile$ make  
  2. gcc -o tommy main.c  
  3. ~/code/makefile$ ls  
  4. main.c  makefile  tommy  
~/code/makefile$ make
gcc -o tommy main.c
~/code/makefile$ ls
main.c  makefile  tommy
main.c被編譯了,一個可執行文件“tommy”產生了。我們執行一下試試:
  1. ~/code/makefile$ ./tommy  
  2. Tommy: 5  
~/code/makefile$ ./tommy
Tommy: 5

得意我們的makefile寫完了!!!

 

好吧,之前的makefile實在是太簡單,以至於沒什麼實際的用途。現在再深入研究下。


Target
在前面的makefile裏,有一個叫"target"的東西。其實它可以是任何名字,而且一個makefile裏可以有多個target。比如下面的makefile:
  1. # 註釋 file: makefile  
  2. tommy:  
  3.     gcc -o tommy main.c # 注意,最前面是tab,不是空格!  
  4. dosomething:  
  5.     echo just for fun.  
# 註釋 file: makefile
tommy:
	gcc -o tommy main.c # 注意,最前面是tab,不是空格!
dosomething:
	echo just for fun.
給make命令一個參數:
  1. ~/code/makefile$ make dosomething  
  2. echo just for fun.  
  3. just for fun.  
~/code/makefile$ make dosomething
echo just for fun.
just for fun.

可以看到,make可以用來執行任何一個target底下的命令,而這種命令並不侷限於gcc這種編譯的命令。每個target用冒號隔開。如果make命令沒有指定哪個target,那第一個target下的命令會被執行。


Dependencies

make命令一次只能處理一個target,但如果我想一次處理多個target怎麼辦?這時可以爲一個target在冒號後面指定它所依賴的target。修改下makefile:

  1. # 註釋 file: makefile  
  2. tommy:  
  3.     gcc -o tommy main.c # 注意,最前面是tab,不是空格!  
  4. dosomething: dofirst dosecond # 先執行另兩個target的命令  
  5.     echo just for fun.  
  6. dofirst:  
  7.     echo first.  
  8. dosecond:  
  9.     echo second.  
  10. donothing:  
  11.     echo nothing.  
# 註釋 file: makefile
tommy:
	gcc -o tommy main.c # 注意,最前面是tab,不是空格!
dosomething: dofirst dosecond # 先執行另兩個target的命令
	echo just for fun.
dofirst:
	echo first.
dosecond:
	echo second.
donothing:
	echo nothing.
make一下看看:
  1. ~/code/makefile$ make dosomething  
  2. echo first.  
  3. first.  
  4. echo second.  
  5. second.  
  6. echo just for fun.  
  7. just for fun.  
~/code/makefile$ make dosomething
echo first.
first.
echo second.
second.
echo just for fun.
just for fun.
可以看到,dofirst和dosecond在dosomething之前都被make了,但tommy和donothing都沒有執行。

編譯多個C文件

現在增加兩個文件f.h和f.c,同時改一下main.c:
  1. ////////////////   
  2. // file: f.h   
  3. ////////////////   
  4.   
  5. int add(intint);  
  6.   
  7. ////////////////   
  8. // file: f.c   
  9. ////////////////   
  10.   
  11. int add(int a, int b)  
  12. {  
  13.     return a + b;  
  14. }  
  15.   
  16. //////////////////   
  17. // file: main.c   
  18. //////////////////   
  19.   
  20. #include <stdio.h>   
  21. #include "f.h"   
  22.   
  23. int main()  
  24. {  
  25.     printf("Tommy-add: %d\n", add(2, 4));  
  26.     return 0;  
  27. }  
////////////////
// file: f.h
////////////////

int add(int, int);

////////////////
// file: f.c
////////////////

int add(int a, int b)
{
    return a + b;
}

//////////////////
// file: main.c
//////////////////

#include <stdio.h>
#include "f.h"

int main()
{
    printf("Tommy-add: %d\n", add(2, 4));
    return 0;
}
看看我的目錄結構:
  1. ~/code/makefile$ ls  
  2. f.c  f.h  main.c  makefile  
~/code/makefile$ ls
f.c  f.h  main.c  makefile
基於前面的“Dependencies”得到的結論,我們可以改寫makefile,來讓main函數調用f函數:
  1. # file: makefile  
  2. tommy: main.o f.o  
  3.     gcc -o tommy main.o f.o  
  4. main.o:  
  5.     gcc -c main.c -o main.o  
  6. f.o:  
  7.     gcc -c f.c -o f.o  
# file: makefile
tommy: main.o f.o
	gcc -o tommy main.o f.o
main.o:
	gcc -c main.c -o main.o
f.o:
	gcc -c f.c -o f.o
看下生成的結果:
  1. ~/code/makefile$ make  
  2. gcc -c main.c -o main.o  
  3. gcc -c f.c -o f.o  
  4. gcc -o tommy main.o f.o  
  5.   
  6. ~/code/makefile$ ls  
  7. f.c  f.h  f.o  main.c  main.o  makefile  tommy  
  8.   
  9. ~/code/makefile$ ./tommy  
  10. Tommy-add: 6  
~/code/makefile$ make
gcc -c main.c -o main.o
gcc -c f.c -o f.o
gcc -o tommy main.o f.o

~/code/makefile$ ls
f.c  f.h  f.o  main.c  main.o  makefile  tommy

~/code/makefile$ ./tommy
Tommy-add: 6
可以看到我們的生成了我們想要的東西。

clean與install
經常可以看到“make clean”和“make install”的命令。我們也可以提供它們:
  1. # file: makefile  
  2. tommy: main.o f.o  
  3.     gcc -o tommy main.o f.o  
  4. main.o:  
  5.     gcc -c main.c -o main.o  
  6. f.o:  
  7.     gcc -c f.c -o f.o  
  8. clean:  
  9.     rm *.o  
  10. install:  
  11.     mv tommy /usr/local  
# file: makefile
tommy: main.o f.o
	gcc -o tommy main.o f.o
main.o:
	gcc -c main.c -o main.o
f.o:
	gcc -c f.c -o f.o
clean:
	rm *.o
install:
	mv tommy /usr/local


最後再研究下makefile裏的宏。其實就是定義一個變量,之後再使用它:

  1. # file: makefile  
  2. INSTALL_PATH = /usr/local  
  3. TEMP_FILES = *.o  
  4. tommy: main.o f.o  
  5.     gcc -o tommy \  
  6.         main.o f.o # 這裏演示反斜槓用於換行,注意反斜槓後沒有空格,行首是tab而非空格  
  7. main.o:  
  8.     gcc -c main.c -o main.o  
  9. f.o:  
  10.     gcc -c f.c -o f.o  
  11. clean:  
  12.     rm $(TEMP_FILES)  
  13. install:  
  14.     mv tommy $(INSTALL_PATH)  
# file: makefile
INSTALL_PATH = /usr/local
TEMP_FILES = *.o
tommy: main.o f.o
	gcc -o tommy \
		main.o f.o # 這裏演示反斜槓用於換行,注意反斜槓後沒有空格,行首是tab而非空格
main.o:
	gcc -c main.c -o main.o
f.o:
	gcc -c f.c -o f.o
clean:
	rm $(TEMP_FILES)
install:
	mv tommy $(INSTALL_PATH)

(完)

 

發佈了79 篇原創文章 · 獲贊 17 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章