makefile 之阶段总结--1--写一个简单的makefile

一. 没有makefile&&make的时候


在没有make&&makefile的时候,我是在IDE中编译程序的.最开始使用命令行编译程序,是在写OJ题目的时候,毕竟OJ题目只需要一个文件,在命令行中编译运行还是比较容易的.但是一但文件多了,或者有了多个文件且放在不同的目录中,在命令行中编译就比较麻烦了.而且文件多了之后,修改也肯定要很频繁,再用命令行的方式编译,就是傻了.

其实促使我使用makefile的原因就很简单,在ubuntu中,使用eclipse ide for c/c++的时候,总是时不时的出点问题,而且eclipse的console的输入很让人蛋疼. 于是我终于开始使用makefile.在大约三个月之前我就知道makefile了,不过那个时候还在学习linux的基本操作,连ubuntu都不会安装.也写过简单的makefile,不过那只是把编译命令写在makefile文件中,像自动化变量,宏等根本没有用过,<跟我一起写makefile>也看了一点点,只不过看的很吃力就是了.一下到linux的基本操作会了一点点,而且在ubuntu中,eclipse总是出问题,也就是个星期之前,才看了<跟我一起写makefile>和<GNU make项目管理>.

现在写下的,并不是一个教程,也不是一个心得体会,可能连一个好点的总结都算不上,只能说是一个学习记录吧


二. 我的第一个makefile:

比如有如下代码:

code


#include<stdio.h>
int main( void ){
    int a = 0;
    int b = 0;
    puts("输入两个整数:");
    scanf("%d %d",&a,&b);
    printf("%d + %d = %d\n",a,b,a+b);
    printf("\nHello World!\n小代码!\n");
    return 0;
}

那么我的makefile就是:

makefile



test:test.o
	gcc test.o -o test
test.o:test.c
	gcc -c -Wall test.c


此时我的Makefile的作用也就是少打了一次命令而已.

总结:

makefile就是把编译命令写入到一个文本文件,可以使用make命令解析这些命令之间的依赖关系,从而实现自动化编译程序,当然前提是编写的命令都是正确的.

这个阶段,是在我写OJ题目的时候,因为那会儿还不会在gcc中指定头文件目录,如果遇到多个文件编译,就只能在IDE中了,如果需要输入,那么只能在ide中编译运行一次,没有问题了,再在终端./app来执行测试.


三. 有了多个文件之后的Makefile-使用简单变量


但是写代码的实力总是要提高的,那么文件不可能总是一个.于是就有了类似于下面这三个文件的代码结构

code:

sum.h


#ifndef _SUM_H_
#define _SUM_H_

int sum( int a, int b );


#endif//_SUM_H_
sum.c



#include"../include/sum.h"

int sum( int a, int b ){
    return a + b;
}
test.c



#include<stdio.h>
#include"../include/sum.h"
int main( void ){
    int a = 0;
    int b = 0;

    puts("输入两个整数:");
    scanf("%d %d",&a,&b);
    printf("%d + %d = %d\n",a,b,sum(a,b));

    return 0;
    
}


makefile:



OBJS=test.o sum.o

test:${OBJS}
	gcc ${OBJS} -o test
test.o:test.c sum.h
	gcc -c -Wall test.c
sum.o:sum.c sum.h
	gcc -c -Wall sum.c


总结:


这个阶段大约在五天之前.使用了make的简单变量,也就是:OBJS=test.o sum.o.其它的东西可以说是一点没有


四. 源代码开始布局-初步使用隐含规则


在看了<GNU make项目管理>之后,我开始布局我的源代码,于是我的代码目录如下:

代码目录结构:

laolang@laolang-Lenovo-G470:~/code/makefile/blog/two$ tree
.
├── include
│   └── sum.h
├── Makefile
└── src
    ├── sum.c
    └── test.c

2 directories, 4 files
laolang@laolang-Lenovo-G470:~/code/makefile/blog/two$


makefile:

OBJS=test.o sum.o

CC=gcc
CFLAGS=-Wall -I include


vpath %.h include
vpath %.c src




test:${OBJS}
	gcc ${OBJS} -o test

test.o:sum.h
sum.o:sum.h

.PHNOY: clean
clean:
	-rm *.o test


总结:

此时开始初步使用make的隐含规则,伪目标,以及vpath.这个阶段大概在两天之前.此时已经可以写简单的Makefile,使用伪目标来清除中间文件和生成的可执行程序.


五. 现在的Makefile

这个阶段也就是写下这个记录的时刻.基本上可以编写单一的Makefile了.但是对于make的变量的理解还是远远的不足,而且之后几天肯定也会用到多个Makefile.另外看到<GNU make项目管理>的第三四章,就要有一定的shell script编程能力才行.这个Makefile和之前的没有太大的改进,就是写了注释,多了几个目标而已

源代码布局:

laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ tree
.
├── include
│   └── sum.h
├── Makefile
└── src
    ├── sum.c
    └── test.c

2 directories, 4 files
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ 


code:

test.c

#include<stdio.h>
#include"../include/sum.h"
int main( void ){
    int a = 0;
    int b = 0;

    puts("输入两个整数:");
    scanf("%d %d",&a,&b);
    printf("%d + %d = %d\n",a,b,sum(a,b));

    return 0;
    
}





sum.h


#ifndef _SUM_H_
#define _SUM_H_

int sum( int a, int b );


#endif//_SUM_H_



sum.c

#include"../include/sum.h"

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





makefile:


# 功能: makefile笔记
#
# 作者:小代码
# 时间:2014年 11月 14日 星期五 15:12:51 CST
#

# 程序名称
PROGRAM=test


# 指定C编译器
CC=gcc
# 指定编译选项
CFLAGS=-Wall -I include


# 指定头文件目录
vpath %.h include
# 指定源文件目录
vpath %.c src

# 指定删除命令
RM=rm -rf


# 帮助列表
define HELP_LIST
	echo "#make\t\t\t\t编译程序"
	echo "#make runt\t\t\t运行程序"
	echo "#make rebuild\t\t\t重新构建"
	echo "#make clean\t\t\t清除中间文件和可执行程序"
	echo "#make help\t\t\t输出此帮助列表"
endef


# 默认目标,生成主程序
all:${PROGRAM}

# 重新构建
rebuild:clean all

# 生成主程序
${PROGRAM}:test.o sum.o

tees.o:sum.h
sum.o:sum.h


.PHNOY:clean run help

# 清除中间文件和可执行程序
clean:
	-${RM} ${PROGRAM} *.o

# 运行程序
run:
	./${PROGRAM}

# 显示帮助列表
help:
	@${HELP_LIST}


运行效果:


laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ tree
.
├── include
│   └── sum.h
├── Makefile
└── src
    ├── sum.c
    └── test.c

2 directories, 4 files
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ make help
#make				编译程序
#make runt			运行程序
#make rebuild			重新构建
#make clean			清除中间文件和可执行程序
#make help			输出此帮助列表
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ make 
gcc -Wall -I include   -c -o test.o src/test.c
gcc -Wall -I include   -c -o sum.o src/sum.c
gcc   test.o sum.o   -o test
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ make run
./test
输入两个整数:
3 4
3 + 4 = 7
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ make rebuild
rm -rf test *.o
gcc -Wall -I include   -c -o test.o src/test.c
gcc -Wall -I include   -c -o sum.o src/sum.c
gcc   test.o sum.o   -o test
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ tree
.
├── include
│   └── sum.h
├── Makefile
├── src
│   ├── sum.c
│   └── test.c
├── sum.o
├── test
└── test.o

2 directories, 7 files
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ make clean
rm -rf test *.o
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$ tree
.
├── include
│   └── sum.h
├── Makefile
└── src
    ├── sum.c
    └── test.c

2 directories, 4 files
laolang@laolang-Lenovo-G470:~/code/makefile/blog/three$




总结:

到了现在,简单的Makefile已经可以写了.可以初步使用隐含规则,make的变量的使用,.PHNOY伪目标的使用,make宏的使用



六. 下一步的目标:


但是也只是在使用阶段,对于它们的本质还不了解.比如从一个.c文件编译为.o文件的隐含规则,make的预定义变量的含义,以及多个Makefile的使用.这只

是Makefile本身的.更多的是gcc的使用.比如如何使用gdb调试程序,如何引用第三方库,如何建立一个自己的库.还有就是shell script编程能力,这方面我还是个小白.最后,就是linux命令行操作了,现在我也只是会简单的用一下grep而已.这些都是下一步要学习的.

为了学习这些,我选择了libxml2这个第三方库,程序就是使用xml文件作为数据库部分的学生信息管理系统.

开发方式:

Eclipse --写源代码,主要是因为有libxml2的代码提示

gvim -- 写Makefile

make -- 程序的编译,调试,运行





你可能感兴趣的:(makefile 之阶段总结--1--写一个简单的makefile)