最简单的Makefile
文件列表:
main.c
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
命令:
$ gcc -o main main.c
Makefile:
main: main.o
main.o: main.c
gcc -c main.c
clean:
rm main main.o
定义变量
Makefile:
cc = gcc
main: main.o
main.o: main.c
$(cc) -c main.c
clean:
rm main main.o
更稳健
Makefile:
cc = gcc
main: main.o
main.o: main.c
$(cc) -c main.c
# Makefile所在目录出现clean文件时, 忽略它; 没有PHONY, 出现clean文件时make clean出错
.PHONY: clean
clean:
rm main main.o
多个源文件
文件列表:
main.c
#include <stdio.h>
void func();
int main()
{
func();
return 0;
}
comm.c
#include <stdio.h>
void func()
{
printf("hello world\n");
}
命令:
方式一
$ gcc -c main.c
$ gcc -c comm.c
$ gcc -o main main.o comm.o
方式二:
$ gcc -o main main.c comm.c
Makefile:
cc = gcc
main: main.o comm.o
main.o: main.c
$(cc) -c main.c -o main.o
comm.o: comm.c
$(cc) -c comm.c -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
头文件
文件列表:
main.c
#include <stdio.h>
#include "comm.h"
int main()
{
func();
return 0;
}
comm.c
#include "comm.h"
#include <stdio.h>
void func()
{
printf("hello world\n");
}
comm.h
void func();
命令:
$ gcc main.c comm.c -o main
Makefile:
cc = gcc
main: main.o comm.o
main.o: main.c
$(cc) -c main.c -o main.o
comm.o: comm.c
$(cc) -c comm.c -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
多个头文件
文件列表:
同一个目录下
main.c
#include <stdio.h>
#include "comm.h"
int main()
{
func();
return 0;
}
comm.c
#include "comm.h"
#include <stdio.h>
void func()
{
printf("hello world\n");
}
comm.h
void func();
comm2.c
#include "comm2.h"
#include <stdio.h>
void func2()
{
printf("comm2 hello world\n");
}
comm2.h
void func2();
命令:
$ gcc main.c comm.c comm2.c -o main
Makefile:
cc = gcc
main: main.o comm.o comm2.o
main.o: main.c
$(cc) -c main.c -o main.o
comm.o: comm.c
$(cc) -c comm.c -o comm.o
comm2.o: comm2.c
$(cc) -c comm2.c -o comm2.o
.PHONY: clean
clean:
rm main main.o comm.o comm2.o
寻找头文件
文件列表:
.
├── Makefile
├── comm.c
├── include
│ └── comm.h
└── main.c
main.c
#include <stdio.h>
#include "comm.h"
int main()
{
func();
return 0;
}
comm.c
#include "comm.h"
#include <stdio.h>
void func()
{
printf("hello world\n");
}
include/comm.h
void func();
命令:
$ gcc main.c comm.c -Iinclude -o main
Makefile:
cc = gcc
main: main.o comm.o
main.o: main.c
$(cc) -c main.c -Iinclude -o main.o
comm.o: comm.c
$(cc) -c comm.c -Iinclude -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
生成静态库
文件列表:
.
├── Makefile
├── comm.c
├── comm.h
└── main.c
0 directories, 4 files
main.c
#include <stdio.h>
#include "comm.h"
int main()
{
func();
return 0;
}
comm.c
#include "comm.h"
#include <stdio.h>
void func()
{
printf("hello world\n");
}
comm.h
void func();
命令:
$ gcc -c comm.c
$ ar rcs libcomm.a comm.o
$ gcc -o main main.c -L. libcomm.a
Makefile:
cc = gcc
all: mylib main
mylib: comm.o
ar rcs libcomm.a comm.o
comm.o: comm.c
$(cc) -c comm.c -o comm.o
main: main.c
$(cc) main.c -L. libcomm.a -o main
.PHONY: clean
clean:
rm main main.o comm.o
c++含头文件
文件列表:
.
├── Makefile
├── comm.cpp
├── comm.h
└── main.cpp
0 directories, 4 files
main.cpp
#include <stdio.h>
#include "comm.h"
int main()
{
mynamespace::func();
return 0;
}
comm.cpp
#include "comm.h"
#include <stdio.h>
namespace mynamespace
{
void func()
{
printf("hello world\n");
}
}
comm.h
namespace mynamespace
{
void func();
}
命令:
$ g++ main.cpp comm.cpp -o main
Makefile:
cc = g++
main: main.o comm.o
main.o: main.cpp
$(cc) -c main.cpp -o main.o
comm.o: comm.cpp
$(cc) -c comm.cpp -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
自动推导
只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,下面的Makefile是等同的:
Makefile
cc = g++
main: main.o comm.o
main.o: main.cpp
$(cc) -c main.cpp -o main.o
comm.o: comm.cpp
$(cc) -c comm.cpp -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
Makefile
cc = g++
main: main.o comm.o
main.o:
$(cc) -c main.cpp -o main.o
comm.o:
$(cc) -c comm.cpp -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
隐含规则
“.o”的目标的依赖目标会自动推导为“.c”,并且其生成命令是“$(CC) –c $(CPPFLAGS) $(CFLAGS)”,下面两个Makefile是等同的:
cc = g++
main: main.o comm.o
main.o:
$(cc) -c main.cpp -o main.o
comm.o:
$(cc) -c comm.cpp -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
cc = g++
main: main.o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
后缀规则
如果你定义了一个规则是".c.o"那么其就是双后缀规则,意义就是".c"是源文件的后缀,".o"是目标文件的后缀。如下示例:
.c.o:
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
自动化变量$@ $^ $<
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。 下面两个Makefile是等同的。
Makefile
main:main.o comm.o
gcc -o main main.o comm.o
main.o:main.c comm.h
gcc -c main.c
comm.o:comm.c comm.h
gcc -c comm.c
Makefile
main:main.o comm.o
gcc -o $@ $^
main.o:main.c comm.h
gcc -c $<
comm.o:comm.c comm.h
gcc -c $<
打印执行序列(命令集合)
我们想看一下执行make后都运行了哪些命令,可以使用-n参数。
有Makefile如下:
cc = g++
main: main.o comm.o
main.o:
$(cc) -c main.cpp -o main.o
comm.o:
$(cc) -c comm.cpp -o comm.o
.PHONY: clean
clean:
rm main main.o comm.o
$ make -n
显示如下信息:
g++ -c main.cpp -o main.o
g++ -c comm.cpp -o comm.o
cc main.o comm.o -o main
文章不错,支持一下
参考:http://wiki.ubuntu.org.cn/index.php?title=Gcchowto&variant=zh-hans