linux--Makefile概述

38 篇文章 3 订阅
3 篇文章 0 订阅

一、程序的编译和链接

1、见图

2、一般来说,无论是 C、C++、还是 pas,首先要把源文件编译成中间代码文件,在 Windows 下也就是 .obj 文件,UNIX 下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的 Object File 合成执行文件,这个动作叫作链接(link)编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在 C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O 文件或是 OBJ 文件)。链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O 文件或是 OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File)在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在 Windows 下这种包叫“库文件”(Library File),也就是 .lib 文件,在 UNIX下,是 Archive File,也就是 .a 文件。总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成 Object File。而在链接程序时,链接器会在所有的 Object File 中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error)

 

二、Makefile介绍

1、Makefile的核心

    文件依赖关系是Makefile的核心!根据依赖关系,执行对应的命令,最后生成目标文件。

2、Makefile的规则

//
target ... : prerequisites ...
command
...
...
//

注意:command可以写在依赖后面,如果不写在依赖后面,则必须以“Tab”键开始

target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,请见“伪目标”。prerequisites 就是,要生成那个 target 所需要的文件或是目标。command 也就是 make 需要执行的命令。(任意的 Shell 命令)

3、一个示例

4、make是如何工作的

(1)首先判断目标文件有没有,没有执行对应的命令。

(2)目标文件有的情况下,根据目标文件和依赖文件的文件时间来决定;

(3)只要依赖文件的文件日期比目标文件时间更新,对应的命令就会执行!

注意:make 只管文件的依赖性

5、Makefile 中使用变量

(1)为了 makefile 的易维护,在 makefile 中我们可以使用变量。makefile 的变量也就是一个字符串,理解成 C 语言中的宏可能会更好。比如,我们声明一个变量,叫 objects, OBJECTS, objs, OBJS, obj, 或是 OBJ,反正不管什么啦,只要能够表示 obj 文件就行了。我们在 makefile 一开始就这样定义:objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o 于是,我们就可以很方便地在我们的 makefile 中以“$(objects)”的方式来使用这个变量了。

 

四、示例(from 实验楼)

1、main.c

/* main.c */
#include <stdio.h>
#include "complicated.h"

int main()
{
    printf("%s\n", HELLO_STRING);
    complicated();

    return 0;
}

2、complicated.h

/* complicated.h */

#ifndef __COMPLICATED_H__
#define __COMPLICATED_H__
#define HELLO_STRING "Hi !"
#define PROJECT_NAME "complicated"

extern void complicated(void);

#endif

3、complicated.c

/* complicated.c */

#include <stdio.h>
#include "complicated.h"

void complicated(void)
{
    printf("This is a %s project\n", PROJECT_NAME);
}

4、Makefile

#描述:complicated 项目 makefile文件
#版本:v1.0
#修改记录:
#1.使用变量改进makefile
#2.使用静态模式规则,简化makefile
#3.使用伪目标加上clean
#4.引进wildcard函数,自动扫描当前目录下的源文件
#5.加入自动规则依赖

#定义可执行文件变量
executable := complicated
#引进wildcard函数扫描源文件,定义源文件列表变量
sources := $(wildcard *.c)
#使用变量的引用替换,定义object文件列表
objects := $(sources:.c = .o)
#使用变量的引用替换,定义依赖描述文件列表
deps := $(soueces:.c = .d)

#定义编译命令变量
CC := gcc
RM := rm -rf 

#终极目标规则,生成complicated可执行文件
$(executable): $(objects)
#使用自动化变量改造我们的编译命令
	$(CC) -o $@ $^

#静态模式规则简化main.o complicated.o 生成规则
$(objects): %.o : %.c
	$(CC) -o $@ -c %<

#使用伪目标添加clean规则
.PHONY: clean
clean:
	$(RM) $(executable) $(objects) $(deps)

#自动规则依赖
include $(deps)

$(deps): %.d : %.c
	$(CC) -MM $< > $@

5、下载链接

Makefile示例链接

 

致谢

1、《Makefile》 作者 陈皓,整理 祝冬华

2、生成可执行文件的makefile,生成静态链接库的makefile,生成动态链接库的makefile。

3、Makefile 使用总结(prefect)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

worthsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值