Linux编程之Makefile(一)

      我刚开始学Linux的时候,并没有用Makefile。写一个test.c ,然后直接gcc -o -g test test.c。后来文件一多,各种.c .h 文件。原来的方法是没法编译的。所以这时候就要靠Makefile。

先写一个简单的例子吧。现在有一段代码

#include<stdio.h>

int main(int args,char *argv[])
{
      printf("hello,world!!");
      return 0;
}

稍微插一段编译原理:首先你的.c到Linux可执行文件.elf 要经历的过程是:.h .c->.i->.o->elf

首先是预编译:加载头文件和动态链接库  。然后是汇编,编译,最后是链接

其实是这样:

gcc -E hello.c -o hello.i
gcc -S hello.i -o hello.s
gcc -c hello.s -o hello.o

现在动手写一个Makefile   直接vim Makefile

test 是目标文件,而test.c是依赖文件。下面的红色字体是命令。在Makefile中的命令,必须要以【tab】键开始!

想一想,Linux内核成千个.c .h也这样写岂不是要累死!!!

如何写一个比较通用的Makefile呢

先上一个Makefile再慢慢讲解吧  !!!

SRC      =$(wildcard *.c)
OBJS     =$(patsubst %.c,%.o,$(SRC))
CC        = gcc
CFLAGS = -Wall -g
LIBS      = -lpthread
DEFS     = 
INCLUDE = -I ./
TARGET  = test
$(TARGET):$(OBJS)
    $(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $@ -o $^  $(LIBS)
.PHONY:clean
clean:
    rm -rf  *.o $(TARGET)

 红色字体是Makefile中的变量。使用变量的方式就是$(变量名)  $@表示目标文件   $^表示第一个依赖文件   翻译一下:

$(CC)  $(CFLAGS)  $(DEFS)  $(INCLUDE)  $@  -o  $^   $(LIBS) ==gcc  -Wall -g  -I ../ test -o test.c -lpthread

-I 表示加入的头文件即$(INCLUDE)   后面跟文件路径。           后面的$(LIBS)表示动态库。注意一下,这只是我起的名字,随便什么都可以的。

.PHONY表示伪目标

生成clean。clean 执行的是删除生成的文件。如果当前文件夹没有clean的文件,其实也可以不用加.PHONY。

wildcard是makefile中的函数,放在这里是取当前文件夹中的所有.c文件。

一点点文字只能大致描述一下。很多地方都没讲到。比如1.已经编译的一个项目,需要改一点东西,这时候makefile只会重新编译改了的文件。makefile会自动根据文件改动时间来判断的。2.在多目录结构下有多个makefile怎么来编译。等等。希望对读者有些帮助!!


 

原文地址:https://www.cnblogs.com/haibiandemoumoumou/p/11064883.html