Makefile的制作
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就想一个Shell脚本一样,其中也可以执操作系统的命令。
Linux环境下的程序员如果不会使用GUN make来构建和管理自己的工程,应该不能算是一个合格的专业程序员。在Linux(Unix)环境下使用GUN的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间去完成一个或者多个称之为makefile文件的编写。
所要完成的makefile文件描述了整个工程的编译、连接等规则。其中包括:工程的哪些源文件需要编译、需要创建哪些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为了工程编写makefile的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个正确的makefile。编译整个工程你嗦要做的唯一的一件事就是在shell提示符下输入make命令,这个工程完全自动编译,极大地提高了效率。
Makefile结构
#表示注释
变量定义
VAR=test 定义变量VAR,强制付志伟test
VAR+=app 在VAR之前定义的值后面再追加app这个值
VAR?=testapp 如果之前VAR没有被定义,则定义并使用testapp,否则使用之前的值
第一条目标为总的目标
依赖可以是文件(目录)或为其他目标
动作可以是Linux命令,动作的哪一行第一个字符必须是以TAB键补齐的
target: depend1 depend2 depend3 ......
[TAB] action1
[TAB] action2
target:
[TAB] action1
[TAB] action2
makefile的使用
make找makefile或者Makefile文件执行总的目标
make clean 执行makefile文件中的clean目标
make -C directory 进入到directory文件夹中去执行总的目标
make clean -c directory 进入到directory文件夹中去执行clean目标
make -f comm_makefile 通过-f选项指定一个makefile文件
make VAR=value 给makefile传一个参数VAR,其值为value
案例:
分别创建vendor1与vendor2两个文件夹,在这两个文件夹中放两个函数
[xiaohexiansheng@centos6 library]$ mkdir vendor1
[xiaohexiansheng@centos6 library]$ mkdir vendor2
[xiaohexiansheng@centos6 library]$ cd vendor1
[xiaohexiansheng@centos6 vendor1]$ vim crypto.c
#include <stdio.h> void crypto(void) { printf("Start crypt..."); return ; }
[xiaohexiansheng@centos6 vendor1]$ vim crypto.h
#ifndef _CRYPTO_H_ #define _CRYPTO_H_ void crypto(void); #endif
[xiaohexiansheng@centos6 vendor1]$ vim makefile
LIB_NAME=vendor1 all: shared static rm -f *.o shared: gcc -shared -fpic -o lib${LIB_NAME}.so *.c static: gcc -c *.c ar -rcs lib${LIB_NAME}.a *.o clean: rm -f *.a *.so rm -f *.o install: cp lib${LIB_NAME}.* ../libs
[xiaohexiansheng@centos6 vendor1]$ cd ../vendor2
[xiaohexiansheng@centos6 vendor2]$ vim func.c
#include <stdio.h> void func(void) { printf("Start func..."); return ; }
[xiaohexiansheng@centos6 vendor2]$ vim func.h
#ifndef _FUNC_H_ #define _FUNC_H_ void func(void); #endif
[xiaohexiansheng@centos6 vendor2]$ vim makefile
LIB_NAME=vendor2 all: shared static rm -f *.o shared: gcc -shared -fpic -o lib${LIB_NAME}.so *.c static: gcc -c *.c ar -rcs lib${LIB_NAME}.a *.o clean: rm -f *.a *.so rm -f *.o install: cp lib${LIB_NAME}.* ../libs
[xiaohexiansheng@centos6 vendor2]$ cd ..
[xiaohexiansheng@centos6 library]$ vim main.c
#include "crypto.h" #include "func.h" int main(void) { crypto(); func(); return 0; }
[xiaohexiansheng@centos6 library]$ vim makefile
APP_NAME?=app all: lib_vendor1 lib_vendor2 gcc -static main.c -Ivendor1 -Ivendor2 -o ${APP_NAME} -Lvendor1 -Lvendor2 -lvendor1 -lvendor2 lib_vendor1: make -C vendor1 lib_vendor2: make -C vendor2
[xiaohexiansheng@centos6 library]$ ls
main.c makefile vendor1 vendor2
[xiaohexiansheng@centos6 library]$ make
make -C vendor1
make[1]: Entering directory `/home/xiaohexiansheng/cc/library/vendor1'
gcc -shared -fpic -o libvendor1.so *.c
gcc -c *.c
ar -rcs libvendor1.a *.o
rm -f *.o
make[1]: Leaving directory `/home/xiaohexiansheng/cc/library/vendor1'
make -C vendor2
make[1]: Entering directory `/home/xiaohexiansheng/cc/library/vendor2'
gcc -shared -fpic -o libvendor2.so *.c
gcc -c *.c
ar -rcs libvendor2.a *.o
rm -f *.o
make[1]: Leaving directory `/home/xiaohexiansheng/cc/library/vendor2'
gcc main.c -Ivendor1 -Ivendor2 -o app -Lvendor1 -Lvendor2 -lvendor1 -lvendor2
[xiaohexiansheng@centos6 library]$ ls
app main.c makefile vendor1 vendor2