linux编程学习笔记(五) make的使用和Makefile

时间:2021-12-19 04:43:27

原地址:http://blog.csdn.net/a8887396/article/details/8996358


1 基本构成语法

基本单位目标target
目标名:依赖目标 依赖目标 #空格分开 '#是注释'
\t@目标指令 #可以加@来隐藏打印命令
\t目标指令

make  -f 脚本文件 目标名


[cpp] view plaincopy
  1. 1输入一个整数判定是否是素数  
  2.         input.c  
  3.         #include <stdio.h>  
  4.         int input()  
  5.         {  
  6.             int r;  
  7.             printf("输入一个整数:");  
  8.             scanf("%d",&r);  
  9.             return r;  
  10.         }  
  11.       
  12.     primer.c  
  13.     int primer(int n)  
  14.     {  
  15.         int i=2;  
  16.         for(;i*i<=n; i++)  
  17.         {  
  18.             if( n%i == 0)  
  19.             {  
  20.                 return 0;  
  21.             }  
  22.               
  23.         }  
  24.         return 1;  
  25.     }  
  26.       
  27.         demo.c  
  28.         #include <stdio.h>  
  29.         main()  
  30.         {  
  31.             int r =input();  
  32.             if(primer(r))  
  33.             {  
  34.                 printf("%d是素数\n",r);  
  35.             }  
  36.             else  
  37.             {  
  38.                 printf("%d是和数\n",r);  
  39.             }     
  40.         }  
  41.           

[plain] view plaincopy
  1. #demo.mk  
  2.       
  3. main:demo.c libpm.so  
  4.     gcc -o main demo.c -lpm -L.  
  5. libpm.so:input.o primer.o  
  6.     gcc -shared -olibpm.so input.o primer.o   
  7. input.o:input.c  
  8.     gcc -c -fpic input.c  
  9. primer.o:primer.c   
  10.     gcc -c -fpic primer.c  
  11. .PHONY:clean  
  12. clean:  
  13.     rm *.o main *.so *.a.  



编译
make -f demo.mk (默认执行第一个目标main)
执行
export LD_LIBRARY_PATH=.
./main


2默认规则

a若不指定目标 默认只执行第一个目标
b不指定make文件 默认执行makefile Makefile
小写makefile优先

3 目标调用规则:

make执行目标:(make把目标当文件)
搜索与目标相同的文件
如果文件存在,则判定日期,若日期是最新的,则停止执行,输出提示
如果文件日期不是最新,则进行执行
文件存在提示:
zhao@ubuntu:~/unix/two/demo-excise$ make -f demo.mk main
make: “main”是最新的。
比较:当前目标与依赖目标进行比较,依赖目标比当前目标新,则要执行


4 建议:(见demo.mk)

每个编译结果做为一个目标,并且把编译结果做为目标名
第一次make ,main不存在,需要执行
第二次make,main是最新的,则不执行
第三次,改变input.c 再 make执行目标
发现
1 demo.c和main一样新
2 再查main的另一个依赖 libpm.so是否更新,此时要查看libpm.so的依赖 input.o primer.o 是否更新
3 发现input.o的依赖input.c比input.o更新,则要执行input.o目标下的语句
4 input.o比libpm.so更新,执行libpm.so下的语句
5 libpm.so比main 更新,执行main下的语句

5 潜规则(不建议使用)

.c目标与.o目标
查找.o目标 目标不存在 就把.o替换成.c

查找.c存在,实施潜规则,直接调用gcc把.c变成.o

[plain] view plaincopy
  1. #demo.mk  
  2.   
  3. CC=gcc  
  4. main:demo.c libpm.so  
  5.     gcc -o main demo.c -lpm -L.  
  6. libpm.so:input.o primer.o  
  7.     gcc -shared -olibpm.so input.o primer.o   
  8. clean:  
  9.     rm *.o main *.so *.a  
zhao@ubuntu:~/unix/two/demo-excise$ make -f demo.mk main
gcc    -c -o input.o input.c
gcc    -c -o primer.o primer.c
gcc -shared -olibpm.so input.o primer.o 
gcc -o main demo.c -lpm -L.


6 变量

变量名可以大写可以小写


定义:
变量名=值 值
OBJ=input.o primer.o
使用:
$(变量名)
$(OBJ)
或者
$(环境变量)
( ) 与 { }作用是相同的

[plain] view plaincopy
  1. OBJ=input.o primer.o  
  2. main:demo.c libpm.so  
  3.     gcc -o main demo.c -lpm -L.  
  4. libpm.so:input.o primer.o  
  5.     gcc -shared -olibpm.so $(OBJ)  
  6. input.o:input.c  
  7.     gcc -c -fpic input.c  
  8. primer.o:primer.c   
  9.     gcc -c -fpic primer.c  
  10. clean:  
  11.     echo $(LD_LIBRARY_PATH)  
  12.     rm *.o main *.so *.a  


7 伪目标:不把目标作为文件处理的目标

比如上面那个clean,如果当前目录下有个clean文件,makefile会觉得clean是最新的。
此时声明clean为伪目标


声明伪目标
.PHONY:clean play


[plain] view plaincopy
  1. OBJ=input.o primer.o  
  2. main:demo.c libpm.so  
  3.     gcc -o main demo.c -lpm -L.  
  4. libpm.so:input.o primer.o  
  5.     gcc -shared -olibpm.so $(OBJ)  
  6. input.o:input.c  
  7.     gcc -c -fpic input.c  
  8. primer.o:primer.c   
  9.     gcc -c -fpic primer.c  
  10. .PHONY:clean play  
  11. clean:  
  12.     echo $(LD_LIBRARY_PATH)  
  13.     rm *.o main *.so *.a  
  14. play:  
  15.     echo "play"