创建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
![得意](http://static.blog.csdn.net/xheditor/xheditor_emot/default/proud.gif)
好吧,之前的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)
(完)