谁都能看懂的Makefile(一)

微软作为PC操作系统的霸主,确实给广大人民群众带来了便利,让一个完全不懂计算机的小白也能在一台PC上写写文档,玩玩游戏。
对开发者,微软的VS系列也是把便利性做到了极致,但便利,上手快的不好之处是让程序员对编译链接这些过程知之甚少,而在linux下进行编程学习就与win刚好相反,linux学习难度就像 l n x lnx lnx,win下的学习难度就像 e x e^x ex函数。
为了更好理解一个可执行文件是怎么产生的,我们就从Makefile开始聊一聊。
假设有三个文件

/* hellomake.c */
#include "hellomake.h"

int main() {
  // call a function in another file
  PrintHello();
  return(0);
}
/* hellofun.c */
#include <stdio.h>
#include "hellomake.h"

void PrintHello(void) {
  printf("Hello makefiles!\n");
  return;
}
/* hellomake.h */
void PrintHello(void);

在linux下想编译他们并产生可执行文件可以使用

gcc -o hellomake hellomake.c hellofunc.c -I./* -I.表示需要用到的头文件在当前目录 */

如果文件发生了修改,只要在命令行回滚这条命令就可以了,但是这样做有个问题就是有时会记不清命令,而且换一台电脑的话要重新输入编译命令,而且对于大型项目,改动其中的一个文件却需要重新编译整个项目,这样比较耗时,由于此类种种不便,Makefile便产生了。
先在你的工程文件夹下创建名为Makefile的文件,并输入

hellomake: hellomake.c hellofunc.c
     gcc -o hellomake hellomake.c hellofunc.c -I.

需要特别注意的是gcc前面是一个“Tab”,第一行是的意思是我想产生名为hellomake的文件,这个文件的产生依赖于hellomake.c和hellofunc.c,此时Makefile会去当前文件夹下找这两个文件,经过寻找发先这两个文件已经存在了,接下来Makefile就会去执行第二行的命令从而产生可执行文件 h e l l o m a k e \color{green}hellomake hellomake
一般产生一个可执行文件需要编译产生 . o \color{blue}.o .o和链接产生可执行文件两步,所以我们将这个Makefile写得更清晰一些

CC=gcc
CFLAGS=-I.
hellomake: hellomake.o hellofunc.o
     gcc -o hellomake hellomake.o hellofunc.o

CC告诉make我们需要用到的编译器,CFLAGS告诉make编译时需要添加的编译选项,当make看到依赖项为 . o \color{blue}.o .o文件时,make会自动去寻找相应的 . c \color{green}.c .c文件,并编译他们。
这样做仿佛还是不够好,因为当hellomake.h文件发生变化时,make并不能发现文件的变化,为了解决这个问题,我们将 . c \color{blue}.c .c文件与 . h \color{red}.h .h文件产生依赖

CC=gcc
CFLAGS=-I.
DEPS = hellomake.h

%.o: %.c $(DEPS)
	$(CC) -c -o $@ $< $(CFLAGS)

hellomake: hellomake.o hellofunc.o 
	$(CC) -o hellomake hellomake.o hellofunc.o

第四行的依赖项表明 . o \color{blue}.o .o文件的产生需要依赖 . c \color{green}.c .c . h \color{red}.h .h文件
%.o指hellomake.o hellofunc.o
%.c指hellomake.c hellofunc.c
$@指的是":" 左边所指的内容,
$<指的是依赖的首项,即%.c
新增的语句翻译一下就是

gcc -c -o hellomake.o hellomake.c -I.
gcc -c -o hellofunc.o hellofunc.c -I.

Makefile中提供了 $^ 来表示":"右边的内容,所以我们的代码能做进一步的简化

CC=gcc
CFLAGS=-I.
DEPS=hellomake.h
OBJ=hellomake.o hellofunc.o

%.o: %.c $(DEPS)
	$(CC)  -c -o $@ $< $(CFLAGS)

hellomake:OBJ
	$(CC) -o $@ $^ $(CFLAGS)

在一般的工程中,我们都会把所有的 . c \color{green}.c .c . h \color{red}.h .h放在不同的文件夹中,同时会包含一些库文件,并且隐藏掉不是那么有用的 . o \color{blue}.o .o文件,一个真实工程中的较为完成的Makefile文件可以写成这样

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

ODIR=obj
LDIR =../lib

LIBS=-lm
#
_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) /* 给文件加一层目录 */

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
	$(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
	rm -f $(ODIR)/*.o *~ core $(INCDIR)/*

这只是Makefile皮毛的皮毛,但是已经勉强能用了,Makefile有很多晦涩的语法和隐式规则,那就一点点的看吧。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值