創建C程序
先寫個c程序,保存在main.c裏:
- //////////////////
- // file: main.c
- //////////////////
- #include <stdio.h>
- int main()
- {
- int c = 0;
- printf("Tommy: %d\n", c+5);
- return 0;
- }
//////////////////
// file: main.c
//////////////////
#include <stdio.h>
int main()
{
int c = 0;
printf("Tommy: %d\n", c+5);
return 0;
}
看看我這時的目錄結構
- ~/code/makefile$ ls
- main.c
~/code/makefile$ ls
main.c
這時敲個“make”命令試試?
- ~/code/makefile$ make
- make: *** 沒有指明目標並且找不到 makefile。 停止。
~/code/makefile$ make
make: *** 沒有指明目標並且找不到 makefile。 停止。
創建makefile文件
- ~/code/makefile$ touch makefile
- tommy@tommy-zheng-ThinkPad-T61:~/code/makefile$ ls
- main.c makefile
~/code/makefile$ touch makefile
tommy@tommy-zheng-ThinkPad-T61:~/code/makefile$ ls
main.c makefile
這時再試試“make”命令:
- ~/code/makefile$ make
- make: *** 無目標。 停止。
~/code/makefile$ make
make: *** 無目標。 停止。
加入target
錯誤“無目標”告訴我們需要在makefile裏添加一些東西:
- # 註釋 file: makefile
- target:
# 註釋 file: makefile
target:
再執行“make”命令:
- ~/code/makefile$ make
- make: 沒有什麼可以做的爲 `target'。
~/code/makefile$ make
make: 沒有什麼可以做的爲 `target'。
可以看到前面“無目標”的錯誤已經解決了。
加入命令
- # 註釋 file: makefile
- target:
- gcc -o tommy main.c # 注意,最前面是tab,不是空格!
# 註釋 file: makefile
target:
gcc -o tommy main.c # 注意,最前面是tab,不是空格!
好了,執行make命令:
- ~/code/makefile$ make
- gcc -o tommy main.c
- ~/code/makefile$ ls
- main.c makefile tommy
~/code/makefile$ make
gcc -o tommy main.c
~/code/makefile$ ls
main.c makefile tommy
main.c被編譯了,一個可執行文件“tommy”產生了。我們執行一下試試:
- ~/code/makefile$ ./tommy
- Tommy: 5
~/code/makefile$ ./tommy
Tommy: 5
我們的makefile寫完了!!!
好吧,之前的makefile實在是太簡單,以至於沒什麼實際的用途。現在再深入研究下。
在前面的makefile裏,有一個叫"target"的東西。其實它可以是任何名字,而且一個makefile裏可以有多個target。比如下面的makefile:
- # 註釋 file: makefile
- tommy:
- gcc -o tommy main.c # 注意,最前面是tab,不是空格!
- dosomething:
- echo just for fun.
# 註釋 file: makefile
tommy:
gcc -o tommy main.c # 注意,最前面是tab,不是空格!
dosomething:
echo just for fun.
給make命令一個參數:
- ~/code/makefile$ make dosomething
- echo just for fun.
- 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:
- # 註釋 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.
# 註釋 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一下看看:
- ~/code/makefile$ make dosomething
- echo first.
- first.
- echo second.
- second.
- echo just for fun.
- 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:
- ////////////////
- // 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;
- }
////////////////
// 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;
}
看看我的目錄結構:- ~/code/makefile$ ls
- f.c f.h main.c makefile
~/code/makefile$ ls
f.c f.h main.c makefile
基於前面的“Dependencies”得到的結論,我們可以改寫makefile,來讓main函數調用f函數:
- # 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
# 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
看下生成的結果:
- ~/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
~/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”的命令。我們也可以提供它們:
- # 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
# 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裏的宏。其實就是定義一個變量,之後再使用它:
- # 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)
# 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)
(完)