Makefile和shell
一、 Makefile
描述了整个工程的编译、链接规则。当源码文件比较多的时候就不适合通过输入 gcc 命令来编译,Makefile 文件描述了编译哪些源码文件、如何编译,每次需要编译工程时只需要使用这个文件就行了。
1.makefile的基本语法
makefile功能强大,makefile的语法与shell脚本相似,首先makefile大概有三种元素,分别是,目标,依赖和动作,目标是一个代号,即你要完成什么,依赖是你完成这个目标所需要的文件,进程,或其他目标等等,动作就是我们为了实现这个目标,让系统执行的操作,比如gcc,rm -rf等命令。
#注意:Makefile 中空出来的部分用 Tab 键,不能用空格;注释用 “#”,不能用 “//”。
#赋值语法:
VAR = testvalue #var变量被强制赋值为testvalue。
VAR ?=testvalue1 #若var未被赋值,那么就赋值为testvalue1,若在此语句前已经赋值,那么就忽略。
VAR +=testvalue2 #在之前定义的var值后面追加testvalue2值,例如之前var已经被赋值testvalue,
#此时+=后,var的值就变成了testvaluetestvalue2。
#总目标,makefile中的第一个目标就是总目标,后面跟的是实现这个目标需要的依赖。
#依赖可以是工作路径下的某个文件,也可以是某个目标,若依赖某目标,则需要先执行这个被依赖的目标。
#例如总目标all就会先执行target1中的动作,结束后接着执行all目标的动作。
all: depend1 depend2 target1
[TAB]action1 #这个目标要实行什么动作
[TAB]action2 #动作前必须是TAB
target1:
[TAB]action1
[TAB]action2
#运行makefile时,默认会打印执行了的动作,如果不需要打印这些信息,可以将@加在action之前,便不会打印action了。若要取出某个变量中的值,可以用${变量}的形式,取出其中的值。
使用 Makefile 的方法:直接在命令行中输入 “make”,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到后就解释并执行该文件,如果找不到就提示错误并退出。一般Makeifle文件名我们会用Makefile或makefile,而不会使用GNUmakefile。
APPNAME=server
LIBPATH=`pwd`/../lib/
CFLAGS+=-I${LIBPATH}
CFLAGS+=-I ../../../sqlite/include/
LDFLAGS+=-L${LIBPATH}
LDFLAGS+=-L ../../../sqlite/lib/
CC=gcc
all:
${CC} ${CFLAGS} main.c -o ${APPNAME} ${LDFLAGS} -lmy_server -lsqlite3
clean:
rm -f ${APPNAME}
run:
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:LIBPATH && ./${APPNAME} -p 12345
另外还需要注意的是:makefile里每一个指令是一个独立的进程,export这一行是一个进程,export是临时改变环境变量,它结束了以后,对于下一行执行的这个进程来说,环境变量其实并没有改变
二、shell 脚本
1、什么是shell脚本
我们如果要实现一个需求,需要在 shell 窗口中输入很多命令,可以直接在 shell 窗口中输入,但每次用到相同的需求时都需要重新敲,我们可以把这些命令记录在一个文档中,然后去执行这个文档中的命令,这样就能一步操作完成。
1、shell 脚本就是一些命令的集合,它是个纯文本文件,命令从上而下,一行一行的开始执行。
2、shell 脚本提供数组、循环、条件判断等功能。
3、shell 脚本扩展名为 .sh。
注意:shell 脚本第一行一定要为: #!/bin/bash -------> 表示使用 bash
2、Shell脚本如何运行
对于脚本文件,我们有两种执行方式:
sh script_name.sh
./script_name.sh
Linux 中一切皆文件,脚本/命令/程序都是一个文件,文件作为一个对象,具有权限的属性。在执行别人发送或从网上下载的脚本时可能会遇到权限问题,赋予执行权限可解决:
chmod +x xxx.sh
需要注意的是,当我们使用Shell脚本的时候,Shell脚本的路径需要被包含在PATH路径当中。我们可以用PATH=$PATH:路径名来添加路径名(通过命令行添加的时候是临时生效的,而不是永久生效)。
#永久修改 $PATH 需要在 .bashrc 或 .bash_profile 中添加 export PATH=“$$PATH:/new/path”
三、Makefile 和 shell 脚本的区别
1、通配符区别
shell 中通配符 * 表示所有的字符
Makefile 中通配符 % 表示所有的字符
2、shell 不允许 “=” 号两边有空格;Makefile 允许变量赋值时,“=” 号两边留空格。
3、命令和变量的引用
shell $() 放命令,${} 放变量
Makefile $() 和 ${} 都能进行取变量值
四、Makefile 和 shell文件互相调用
1、shell 文件内调用makefile文件
#!/bin/bash
make
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:`pwd`/../lib/
./server -p 12345
2、makefile文件内调用shell 文件
APPNAME=server
LIBPATH=`pwd`/../lib/
CFLAGS+=-I${LIBPATH}
CFLAGS+=-I ../../../sqlite/include/
LDFLAGS+=-L${LIBPATH}
LDFLAGS+=-L ../../../sqlite/lib/
CC=gcc
all:
${CC} ${CFLAGS} main.c -o ${APPNAME} ${LDFLAGS} -lmy_server -lsqlite3
clean:
rm -f ${APPNAME}
run:
#export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:LIBPATH && ./${APPNAME} -p 12345
./test.sh