make 与 makefile1.目标的语法 目标名:依赖目标 @命令 @命令 make的命令行使用 make -f make 脚本文件 目标名 2.目标的划分demo.mkdemo: gcc -c -fpic input.c gcc -c -fpic primer.c gcc -shared -olibdemo.so input.o primer.o gcc demo.c -ldemo -L. -omain 转变为 demo1.mk: compile: gcc -c -fpic input.c gcc -c -fpic primer.clink:complie gcc -shared -olibdemo.so input.o primer.odemo:link gcc demo.c -ldemo -L. -omainmake -f demo1.mk compilemake -f demo1.mk linkmake -f demo1.mk demo 3.默认目标 a.不指定目标,执行第一个目标 make -f demo1.mk 等介于make -f demo1.mk compile b.不指定make 文件,默认文件是makefile ,Makefile, makefile优先加载 make 目标的调用规则 make执行目标:(make把 目标 当作文件) 搜索与目标相同的文件 如果文件存在,则判定日期. 日期最新,则停止执行,输出提示 日期不是最新,则进行执行. 没有依赖就是最新的目标文件,不编绎 比较:当前目标与依赖目标 demo2.mk: //跟据编译结果文件依赖,make就可以对实际存在的文件时间比较,决定编译进程input.o:input.c: gcc -c -fpic input.cprimer.o:primer.c gcc -c -fpic primer.clibdemo.so:input.o primer.o gcc -shared -olibdemo.so input.o primer.odemo:demo.c libdemo.so gcc demo.c -ldemo -L. -odemoclean: rm -rf *o demo *.so *a 5.建义: 只要有文件输出,就把任务作为一个目标,并把输出的文件作为目标名6.潜规则(不建议) 注释符号 # .C目标与.O目标 查找.O目标,目标不存在,就把.O替换成.C 如果.C存在,实施潜规则:直接调用GCC 把.C执行为.O demo3.mk: //跟据编译结果文件依赖,make就可以对实际存在的文件时间比较,决定编译进程#input.o:input.c:# gcc -c -fpic input.c#primer.o:primer.c# gcc -c -fpic primer.clibdemo.so:input.o primer.o gcc -shared -olibdemo.so input.o primer.odemo:demo.c libdemo.so gcc demo.c -ldemo -L. -odemoclean: rm -rf *o demo *.so *a 7.定义变量变量名=值1 值2$(变量名) ${变量名} demo4.mk: OBJ=input.o primer.oinput.o:input.c: gcc -c -fpic input.cprimer.o:primer.c gcc -c -fpic primer.clibdemo.so:$(OBJ) gcc -shared -olibdemo.so input.o primer.odemo:demo.c libdemo.so gcc demo.c -ldemo -L. -odemo.PHONY:cleanclean: rm -rf *o demo *.so *a echo ${PATH} //环境变量 echo $(PATH) 8.伪目标 不把目标当成文件处理的 声明伪目标 .PHONY:clean没有讲的: 1.make的配制 2.make变量的操作函数 3.多make文件使用 二.环境变量 env.cint main(int args,char *argv,char **arge) { while(*arge) { printf("%s\n",*arge); arge++; } } arge** ---->char*------>内容 char* 0makefileenv:env.c gcc env.c -omainclean: rm -rf main *.o 命令行参数 argv与环境行arge都是字符串数组 约定:最后一个字符串是NULL/0 2.在C的标准库提代了一个外部变量#include #include void main(){ extern char **environ while(*environ) { printf("%s\n,*environ") *environ++ } } make env ---------------------------------------------- 3.取环境变量的值 getenv setenv unsetenv #include #include #include main() { char *val=getenv("PATH"); printf("%s",val); } 三.IO的认识 1.认识内核对象 不允许访问内核算设备和内存 但可以通过内核系统函数去访问 对每个内核对象进行编号ID. 如果访问内核算对象,只能通过ID 编程模型: 申请得到一个ID 在内核系统函数中使用ID得到对应内核对象 2.如何访问文件: 使用函数,传递一个文件,系统打开文件,加载文件返加一个ID 使用函数,传递ID,得到数据 使用函数传ID,告诉系统释放文件 ID:文件描述符号.(fd) 每个程序执行的时候都有一个目录,存放打开的文件的描述符 #include #include main() { printf("%p",getpid()); while(1); } cd /proc/25857/fd ls ::每个程序可打开三个设备(0,1,2) 0:标准输入 1:标准输出 2:错误输出 4.操作文件描述符号 sszie_t write(int fd, void * buf,size_t size); 返回: >0 实际写入的数据 -1 写入错误 ssize_t read(int fd, void *buf ,size_t size); 返回: >0:实际读取的数据 =0:碰到文件结束符号EOF ctrl+d -1:读取错误 #include #include main() { while(0,"HELLO\n",6); while(1,"world\n",6); while(2,"louis\n",6); } 建议: 0:输入 1:输出 2:错误 #include #include main() { while(0,"HELLO\n",6); while(1,"world\n",6); while(2,"louis\n",6); int a=20; write(1,&a,4); } 乱码: #include #include main() { char buf[30]; int r=read(0,buf,30); printf("youput:%d\n",r); if(r>0) { buf[r]=0; printf("::%s\n",buf); } if(r==0) { printf("ctrl+d\n"); } if(r==-1) { printf("error\n"); } }