Makefile工程管理

2020-02-28 14:37:45 浏览数 (1)

Makefile工程管理

课程截图如下:

demo文件如下:

sequence.h

代码语言:javascript复制
#ifndef _SEQUENCE_H_
#define _SEQUENCE_H_

void sequence(unsigned char*sp,unsigned char num);

#endif

sequence.c

代码语言:javascript复制
#include "sequence.h"void sequence(unsigned  char *sp,unsigned char num)
{
    unsigned char i,j;
    unsigned char a;
    for(j=0;j<num-1;i  )
    {
        for(i=j 1;i<num;i  )
        {
            if(sp[j]>sp[i])
            {
                a=sp[i];
                sp[i]=sp[j];
                sp[j]=a;
            }
        }
    }     
}

main.c

代码语言:javascript复制
#include <stdio.h>
#include "sequence.h"

unsigned char dis_num[8] = {10,9,17,92,2,8,35,12};

int main(void)
{
    unsigned char i;
    sequence(dis_num,sizeof(dis_num));
    for(i=0;i<8;i  )printf("%d ",dis_num[i]);
    printf("rn");
    return 0;        
}

针对模块化程序如何去编译:

处理如下:

代码语言:javascript复制
gcc -o sequence.o -c sequence.c
gcc -o main.o -c main.c
gcc -o main sequence.o main.o
./main

  假设 sequence.c 文件有修改了或者工程里面有很多的.c文件,按照上面的方式处理,工程量就很大,而且一旦有一个文件修改了,那么你就要重新再搞一遍。

  针对上面的情况,咋们就用 makefile 进行工程管理。

  • Makefile规则:

    1)先创建一个名称为 makefile 或者 Makefile 的文档;

    2)在文档里面输入相应的内容:

      输入相应内容的时候,要遵循相应的规则。 

代码语言:javascript复制
      规则:用于说明如何生成一个或多个目标文件;
      规则格式:
           target:dependency_files                //目标项:依赖项
           <TAB>command                          //必须以tab开头,command编译命令

      规则就是为了生成某一个文件的。

      目标项:这个就是你要生成的文件名;

      依赖项:要生成目标项需要的文件;

      编译命令:如果有依赖项生成目标项;必须以TAB开头;

      makefile 文件里面可以有很多规则,但是第一个规则是最终生成的文件规则。

      编写规则如下:

代码语言:javascript复制
      main:main.c
          gcc -o main main.c

    3)如何运行这个 makefile 文件

代码语言:javascript复制
      make
代码语言:javascript复制
main:main.o sequence.o
    gcc -o main main.o sequence.o

main.o:main.c
    gcc -o main.o -c main.c

sequence.o:sequence.c
    gcc -o sequence.o -c sequence.c
  • Makefile的伪目标:

    1)使用 .PHONY 这个makefile的关键字来定义你的伪目标;

代码语言:javascript复制
.PHONY:clean rebuild

    2)再编写对应的伪目标:

代码语言:javascript复制
clean:
    rm -f main.o main sequence.o

rebuild:clean main

    3)要想执行伪目标,直接  make 伪目标名就可以了。

代码语言:javascript复制
make rebuild
make clean
  •  Makefile的变量:

    变量类似C语言里面的宏定义。

    变量分为:用户自定义变量,自动变量,预定义变量,环境变量;

    1)自定义变量:

      定义变量格式如下:

代码语言:javascript复制
        变量名:=变量值

      如何引用变量:

代码语言:javascript复制
        $(变量名)=???    //赋值
        ???=$(变量名)    //引用

      在 Makefine 体现如下:

代码语言:javascript复制
SOURCE:=main.o sequence.o
EXE:=main

$(EXE):$(SOURCE)
    gcc -o $(EXE) $(SOURCE)

main.o:main.c
    gcc -o main.o -c main.c

sequence.o:sequence.c
    gcc -o sequence.o -c sequence.c

.PHONY:clean rebuild
clean:
    rm -f main.o main sequence.o

rebuild:clean main

    2)自动变量:

      使用的时候,使用特定的值去替换。

      自动变量,可以认为是 makefile 里面设定好的符号。

代码语言:javascript复制
SOURCE:=main.o sequence.o
EXE:=main

$(EXE):$(SOURCE)
    gcc -o $@ $^

main.o:main.c
    gcc -o $@ -c $^

sequence.o:sequence.c
    gcc -o $@ -c $^

.PHONY:clean rebuild
clean:
    rm -f main.o main sequence.o

rebuild:clean main

    3)预定义变量和环境变量:

      都是系统里面设定好的自定义变量。

  • Makefile的规则:

    1)普通规则:

    2)隐含规则:

      *.o 文件自动依赖 *.c 或 *.cc 文件,所以可以省略 main.o:main.c等。

代码语言:javascript复制
main:main.o sequence.o
    gcc -o main main.o sequence.o

.PHONY:clean rebuild
clean:
    rm -f main.o main sequence.o

rebuild:clean main

     3)模式规则:

代码语言:javascript复制
main:main.o sequence.o
    gcc -o main main.o sequence.o

%.o:%.c
    gcc -o $@ -c $^   #注意这里面不能再使用%.o来代替了

.PHONY:clean rebuild
clean:
    rm -f main.o main sequence.o

rebuild:clean main
  •  把生成的目标存放到其他的文件夹里面:
代码语言:javascript复制
DIR:=./debug/

${DIR}main:${DIR}main.o ${DIR}sequence.o
    gcc -o ${DIR}main ${DIR}main.o ${DIR}sequence.o

${DIR}main.o:main.c
    gcc -o ${DIR}main.o -c main.c

${DIR}sequence.o:sequence.c
    gcc -o ${DIR}sequence.o -c sequence.c

.PHONY:clean rebuild
clean:
    rm -f ${DIR}main.o ${DIR}main ${DIR}sequence.o

rebuild:clean main

改进

代码语言:javascript复制
DIR:=./debug/
OBJS:=${DIR}main.o ${DIR}sequence.o

${DIR}main:${OBJS}
    gcc -o ${DIR}main ${OBJS}

${DIR}main.o:main.c
    gcc -o ${DIR}main.o -c main.c

${DIR}sequence.o:sequence.c
    gcc -o ${DIR}sequence.o -c sequence.c

.PHONY:clean rebuild
clean:
    rm -f ${DIR}main ${OBJS}

rebuild:clean main
  • Makefile里面的函数: 
代码语言:javascript复制
SOURCE = $(wildcard *.c)            #SOURCE = main.c sequence.c
OBJS = $(patsubst %.c,%.o,$(SOURCE))      #OBJS = main.o sequence.o

main:$(OBJS)
    gcc -o main $(OBJS)

main.o:main.c
    gcc -o main.o -c main.c 

sequence.o:sequence.c
    gcc -o sequence.o -c sequence.c

.PHONY:clean rebuild
clean:
    rm -f main.o main sequence.o

rebuild:clean main
  • 其他:

    1)Makefile里面的注释使用#

    2)命令如果不想显示到终端,在命令前加@

代码语言:javascript复制
SOURCE = $(wildcard *.c)            #SOURCE = main.c sequence.c
OBJS = $(patsubst %.c,%.o,$(SOURCE))      #OBJS = main.o sequence.o

main:$(OBJS)
    @gcc -o main $(OBJS)

main.o:main.c
    @gcc -o main.o -c main.c 

sequence.o:sequence.c
    @gcc -o sequence.o -c sequence.c

.PHONY:clean rebuild
clean:
    @rm -f main.o main sequence.o

rebuild:clean main

    3)如果你命名的Makefile文档名并非Makefile,那么就要加上 -f

代码语言:javascript复制
make -f Makefile1

这个老师的课程内容如下:

0 人点赞