您的位置:首页 > 其它

工程中编写自己的makefile---2 实例

2017-06-05 16:05 453 查看

1        实例来学习使用方法

需要准备的工程目录结构如下

.
├── add
│   ├──add_float.c
│   ├──add.h
│   └──add_int.c
├── main.c
└── sub
    ├── sub_float.c
    ├── sub.h
    └── sub_int.c
文件编译为可执行文件xxxx

1.1             命令行编译程序

[root@9527 5]# gcc -c add/add_int.c -o add_int.o -ggdb
[root@9527 5]# gcc -c sub/sub_int.c -o sub_int.o -ggdb
[root@9527 5]# gcc -c add/add_float.c -o add_float.o -ggdb
[root@9527 5]# gcc -c sub/sub_float.c -o sub_float.o -ggdb
[root@9527 5]# gcc -c main.c -o main.o -Iadd -Isub -ggdb
[root@9527 5]# gcc -o xxxx main.o sub_int.o sub_float.oadd_int.o add_float.o -ggd
[root@9527 5]# ./xxxx
float x-y IS:0.000000
int a+b IS:22
int a-b IS:-2
float x+y IS:11.110000
float x-y IS:0.000000
float x-y IS:-8.642000
-ggdb使 GCC 为 GDB 生成专用的更为丰富的调试信息,但是,此时就不能用其他的调试器来进行调试了 (如 ddx)

1.2             使用make进行项目管理

编写Makefile,把上面的指令按makefile格式写下即可
xxxx:sub_int.o sub_float.o add_int.o add_float.o main.o
    @gcc -o xxxx main.osub_int.o sub_float.o add_int.o add_float.o -ggdb
 
add_float.o:add/add_float.c
    @gcc -c add/add_float.c-o add_float.o -ggdb
 
add_int.o:add/add_int.c
    @gcc -c add/add_int.c-o add_int.o -ggdb
 
sub_float.o:sub/sub_float.c
    @gcc -c sub/sub_float.c-o sub_float.o -ggdb
 
sub_int.o:sub/sub_int.c
    @gcc -c sub/sub_int.c-o sub_int.o -ggdb
 
main.o:main.c
    @gcc gcc -c main.c -omain.o -Iadd -Isub -ggdb
 
.PHONY:clean
clean:
    @rm -f *.o xxxx
 

1.3             使用用户自定义变量的Makefile

在Makefile文件中,用户可以自定义变量,方便用户修改参数。使用变量后,原本冗长的文件可以化简
CC := gcc
RM := rm -f
 
OBJS := sub/sub_int.o sub/sub_float.o add/add_int.oadd/add_float.o main.o
TARGET := xxxx
CFLAGS := -Iadd -Isub -O2
 
$(TARGET):$(OBJS)
    @$(CC) -o $(TARGET)$(OBJS) $(CFLAGS)
 
$(OBJS):%.o:%.c
    $(CC) -c $< -o $@$(CFLAGS)
 
.PHONY:clean
clean:
    @rm -f $(OBJS)$(TARGET)

1.4             设置搜索路径

在大的系统中,通常存在很多目录,手动添加目录的方法不仅十分笨拙而且容易造成错误。Make 的目录搜索功能提供了一个解决此问题的方法,指定需要搜索的目录(依赖文件和目标文件), make 会自动找到指定文件的目录并添加到文件上, VPATH 变量可以实现此目的。

VPATH 变量的使用方法如下:

CC := gcc
RM := rm -f
VPATH := sub:add:.
 
OBJDIR := objs
OBJS := sub_int.o sub_float.o add_int.o add_float.o main.o
TARGET := xxxx
CFLAGS := -Iadd -Isub -O2
 
$(TARGET):$(OBJDIR) $(OBJS)
    @$(CC) -o $(TARGET)$(OBJDIR)/*.o $(CFLAGS)
 
$(OBJDIR):
    @mkdir -p ./$@
 
$(OBJS):%.o:%.c
    $(CC) -c $< -o$(OBJDIR)/$@ $(CFLAGS)
 
.PHONY:clean
clean:
@rm -f $(OBJDIR)/*.o$(TARGET)
 

1.5             自动推导规则

使用命令 make 编译扩展名为 .c 的 C 语言文件的时候,源文件的编译规则不用明确地给出。这是因为 make 进行编译的时候会使用一个默认的编译规则,按照默认规则完成对 .c 文件的编译,生成对应的 .o 文件。它执行命令 cc -c 来编译 .c 源文件。在 Makefile 中只需要给出需要重建的目标文件(一个 .o 文件),make 会自动为这个.o 文件寻找合适的依赖文件(对应的 .c 文件),并且使用默认的命令来构建这个目标文件。
对于上边的例子,默认规则是使用命令cc -cmain.c -o main.o来创建文件 main.o 。对一个目标文件是“文件名.o“,依赖文件是”文件名.c“的规则,可以省略其编译规则的命令行,由 make 命令决定如何使用编译命令和选项。此默认规则称为 make 的隐含规则。
这样,在书写 Makefile 时,就可以省略掉描述 .c 文件和 .o 依赖关系的规则,而只需要给出那些特定的规则描述(.o 目标所需要的 .h 文件)。因此上面的例子可以使用更加简单的方式书写, Makefile 文件的内容如下:
CC := gcc
RM := rm -f
VPATH := sub:add:.
 
OBJS := sub_int.o sub_float.o add_int.o add_float.o main.o
TARGET := xxxx
CFLAGS := -Iadd -Isub -O2
 
$(TARGET):$(OBJS)
    @$(CC) -o $(TARGET)$(OBJS) $(CFLAGS)
 
.PHONY:clean
clean:
    @rm -f $(OBJS)$(TARGET)

1.6             递归 make

对于规模比较大的程序,需要多个人在多个目录下进行开发。如果只用一个 Makefile 来维护就会比较麻烦,因此可以在每个目录下建立自己的 Makefile,然后在总控 Makefile 中调用子目录的Makefile 文件。
 
目录结构如下
.
├── add
│   ├──add_float.c
│   ├──add.h
│   ├──add_int.c
│   └──Makefile
├── main.c
├── Makefile
└── sub
    ├── Makefile
    ├── sub_float.c
    ├── sub.h
└── sub_int.c
 

1.6.1        总控Makefile

export OBJSDIR := $(shell pwd)/objs
 
CC := gcc
RM := rm -f
 
OBJS := main.o
TARGET := xxxx
CFLAGS := -Iadd -Isub -O2
 
$(TARGET):$(OBJSDIR) $(OBJS)
    $(MAKE) -C add
    $(MAKE) -C sub
    @$(CC) -o $(TARGET)$(OBJSDIR)/*.o $(CFLAGS)
 
$(OBJSDIR):
    @mkdir -p $@
 
$(OBJS):%o:%c
    @$(CC) -c $< -o$(OBJSDIR)/$@ $(CFLAGS)
 
.PHONY:clean
clean:
    @rm -f $(OBJSDIR)/*.o$(TARGET)
 

1.6.2        add下makefile

CFLAGS := -O2
CC := gcc 
RM := rm -f
 
OBJS := add_float.o add_int.o
 
all:$(OBJS)
 
$(OBJS):%.o:%.c
    $(CC) -c $< -o$(OBJSDIR)/$@ $(CFLAGS)

1.6.3        sub下makefile

CFLAGS := -O2
CC := gcc 
RM := rm -f
 
OBJS := sub_float.o sub_int.o
 
all:$(OBJS)
 
$(OBJS):%.o:%.c
    $(CC) -c $< -o$(OBJSDIR)/$@ $(CFLAGS)
 
 
 

1.7             使用函数编写makefile

CC := gcc
RM := rm -f
CFLAGS := -Iadd -Isub -O2
 
TARGET := xxxx
DIRS := add sub .
#获取所有的.c文件,包括其相对路径
FILES := $(foreach dirs, $(DIRS), $(wildcard $(dirs)/*.c))
OBJS := $(patsubst %.c, %.o, $(FILES))
 
$(TARGET):$(OBJS)
    @$(CC) -o $(TARGET)$(OBJS) $(CFLAGS)
 
.PHONY:clean
clean:
    @rm -f $(OBJS)$(TARGET)
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: