zoukankan      html  css  js  c++  java
  • Makefile文件编写

    源代码文件

    main3.c

     1 #include <stdio.h>
     2 #include "static_lib.h"
     3 #include "fun.h"
     4 
     5 int main(void){
     6     int a=2,b=3;
     7     printf("add:%d sub:%d mul:%d div:%d
    ",add(a,b),sub(a,b),mul(a,b),div(a,b));
     8     fun1();
     9     return 0;
    10 }

    static_lib.h和

    1 extern int add(int a,int b);
    2 extern int sub(int a,int b);
    3 extern int mul(int a,int b);
    4 extern int div(int a,int b);

    static_lib.c

     1 int add(int a,int b){
     2     return a + b;
     3 }
     4 
     5 int sub(int a,int b){
     6     return a - b;
     7 }
     8 
     9 int mul(int a,int b){
    10     return a * b;
    11 }
    12 
    13 int div(int a,int b){
    14     return a / b;
    15 }

    fun.h和

    1 extern void fun1();

    fun.c

    1 #include <stdio.h>
    2 void fun1(){
    3     printf("fun1 ...");
    4 }

    其中stati_lib.c中的文件编译成静态库

    正常编译

    按照正常的编译方法,这个程序可以按如下顺序编译

    但是每次改了源代码之后都这样子编译显然是不明智的,所以需要编写一个Makefile规则文件

    Makefile Base

    Makefile的规则为

    其中target是目标文件或者动作

    prerequisites是生成目标依赖的文件

    command是规则执行的命令,如果命令与依赖规则在一行,则以';'分割,如果在另一行,则以tab开头

    编写一个最简单的Makefile编译这些源码

     1 app3  : static_lib.a fun.o
     2     gcc main3.c static_lib.a fun.o -o app3
     3 
     4 fun.o :
     5     gcc -c fun.c
     6 static_lib.o : 
     7     gcc -c static_lib.c
     8 
     9 static_lib.a : static_lib.o
    10     ar rcs static_lib.a static_lib.o
    11 
    12 clean :
    13     rm static_lib.a static_lib.o fun.o app3

    执行make clean可以将原来的清理掉

    执行make会重新编译源码

     这样当我们修改源代码之后就可以简单的编译源码了

    Makefile hidden

    但上面的Makefile显然不够简洁,我们可以利用一些make的隐式规则,简写makefile,这些隐含规则可以通过 make -p 指令查看。

    1 app3  : static_lib.a fun.o main3.o
    2     gcc main3.o fun.o static_lib.a -o app3
    3 
    4 static_lib.a : static_lib.o # 隐含会寻找*.c文件编译成*.o文件
    5     ar rcs static_lib.a static_lib.o
    6 
    7 clean :
    8     rm *.a *.o app3

    执行make可以看到依然能够编译成功

    其中cc是一个符号链接

    Makefile Var

    还可以进一步使用一些变量,进一步提高Makefile的可维护性

     1 CC       = gcc
     2 OBJS     = main3.o static_lib.a fun.o
     3 GEN_OPTS = -o 
     4 app3  : $(OBJS)
     5     $(CC) $(OBJS) $(GEN_OPTS) app3
     6 
     7 static_lib.a : static_lib.o # 隐含会寻找*.c文件编译成*.o文件
     8     ar rcs static_lib.a static_lib.o
     9 
    10 clean :
    11     rm *.a *.o app3

    执行make

    而且可以看到 1,2,4行的gcc存在缩进,说明隐含规则也使用指明的CC变量编译。

    Makefile autoVar

    进一步的,我们可以使用一些自动化的变量。

     1 CC       = gcc
     2 OBJS     = main3.o static_lib.a fun.o
     3 GEN_OPTS = -o 
     4 app3  : $(OBJS)
     5     $(CC) $(OBJS) $(GEN_OPTS) app3
     6 
     7 static_lib.a : static_lib.o # 隐含会寻找*.c文件编译成*.o文件
     8     ar rcs $@ $^
     9 
    10 clean :
    11     rm *.a *.o app3

    其中自动化变量 $@表示规则中的目标文件集,$^表示依赖集,这个Makefile执行之后也能得到想要的结果

    Makefile Fun

    最后结合前面的变量,再结合函数,等写一个更完善的makefile,可以做到增加了新的c文件或h文件不需要修改Makefile文件,再次之前,首先将static_lib.* 移动到lib目录下,将其余源码文件移动到src目录。

    并修改main3.c的include为 ../lib/static_lib.h,修改Makefile文件如下

     1 CC       = gcc
     2 SRC      = ./src
     3 LIB      = ./lib
     4 OBJS     = $(patsubst %.c, %.o, $(wildcard $(SRC)/*.c))
     5 LIBS     = $(patsubst %.c, %.a, $(wildcard $(LIB)/*.c))
     6 GEN_OPTS = -o 
     7 app3  : $(OBJS) $(LIBS)
     8     $(CC) $(OBJS) $(LIBS) $(GEN_OPTS) app3
     9     @echo "gen done"
    10 # 将lib目录下的c文件编译成a库文件
    11 $(LIBS) : $(patsubst %.c, %.o, $(wildcard $(LIB)/*.c))
    12     ar rcs $@ $^
    13 
    14 clean :
    15     -rm $(SRC)/*.o $(LIB)/*.a app3
    16     @echo clean done.

    其中patsubst是一个函数,替换通配符,wildcard函数扩展通配符,展开目录下的所有匹配文件。

    命令前面加'-'的话表示即便出错也继续执行。

  • 相关阅读:
    数组初始化 和 vector初始化
    剑指offer42 左旋转字符串
    k sum(lintcode)
    背包问题2 (lintcode)
    92.背包问题(lintcode)
    72. Edit Distance
    79 最长公共子串 (lintcode)
    77 最长公共子序列 (lintcode)
    132. Palindrome Partitioning II
    Mysql经常使用函数汇总
  • 原文地址:https://www.cnblogs.com/lvyahui/p/4777311.html
Copyright © 2011-2022 走看看