Make入门教程

Make 快速入门

Makefiles是一种方便的组织代码编译方式。这篇文章不会深入的讲述如何使用make,只会作为一篇入门教程来让大家快速地为小中型项目创建自己的makefiles.

一个简单的例子

首先举一个简单的例子,在项目文件夹中有三个文件:main.cfunc.cfunc.h,分别代表着主程序,函数实现和对应的头文件。

main.c

// main.c
#include <stdio.h>
#include "func.h"
int main() {
	sayHello();
	return 0;
}

func.h

// func.h
void sayHello();

func.c

// func.c
#include <stdio.h>
#include "func.h"
void sayHello() {
	printf("Hello makefiles!\n");
}

一般情况下,我们将使用以下命令来编译这个项目:

gcc -o hello main.c func.c -I.	# 注意最后的点代表当前目录

这条命令编译了两个.c文件并将可执行文件命名为hello. -I.代表gcc将在当前目录(.)寻找包含的头文件. 当只有轻微的改动时适当修改一下这条命令就已经足够了,但当添加更多文件时,这就很麻烦了。

另外,如果你只改动了其中某一个.c文件,这条命令每次都将重新编译所有文件,对于大项目来说效率很低,所以这才需要makefile.

Makefile 1

hello: main.c func.c
	gcc -o hello main.c func.c -I.

将这条规则写进一个名为makefile或者Makefile(一般两者等同,但有些IDE只能识别其中一种)的文件,然后在命令行中键入make就可以执行文件中的第一条规则了。其中冒号:后面放置的是规则hello所依赖的文件,当这些文件改动时,规则hello会被重新执行。这里没有放置头文件,所以即使头文件改变,命令行中键入make,这条规则也不会被执行。当然,就目前来说,这条规则效率很低。

需要注意的是,在gcc命令前有一个tab制表符,在任何命令前都必须有个tab制表符。

接下来对这条规则进行适当改进。

Makefile 2

CC=gcc
CFLAGS=-I.

hello: main.o func.o
	$(CC) -o hello main.o func.o

这里我们定义的宏CCCFLAGS,将告诉make如何编译.c文件,这里CC代表着C编译器,CFLAGS代表着命令可选参数列表。通过把目标文件main.ofunc.o放置在规则依赖列表中,make将自动使用我们已经定义的宏来分别编译对应的.c文件,以生成目标文件,接下来的命令便是链接目标文件生成可执行文件hello

这样的makefile足够应对小型项目,但是像之前提到的:依赖文件中没有包含头文件,所以头文件改变后make将不会重新编译.c文件。为了修补这个问题,我们需要将头文件加入到依赖列表中。

Makefile 3

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

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

hello: main.o func.o
	$(CC) -o hello main.o func.o

这次更改主要创建了宏DEPS,它代表着.c文件依赖的头文件.h。接着我们定义了一个作用于所有.o文件的规则,它依赖于所有的.c文件和宏DEPS。具体的命令指出make使用宏CC代表的编译器去编译.c文件,且-c指出仅生成目标文件,-o $@指出生成的目标文件命名为:左侧部分,%可以理解为匹配符,即.o.c文件一一对应,前缀相同,$<是依赖列表中的第一个对象。

接下来使用$@$^来进一步简化,这两个宏分别代表着:的左侧和右侧。为了使得这些规则更加通用,所有的目标文件用宏OBJ来表示。

Makefile 4

CC=gcc
CFLAGS=-I.
DEPS=func.h
OBJ = main.o func.o

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

hello: $(OBJ)
	$(CC) -o $@ $^

Makefile 5

但实际项目通常会把.h文件放在include目录中,源文件放在src目录中,链接库放在lib中,生成的目标文件放在obj目录中(可能也不需要)下面就是一个实际的例子(点击下载):

.
├── include
│   ├── dylib.h
│   ├── fun1.h
│   └── fun2.h
├── lib
│   └── libdy.so
├── Makefile
├── obj
└── src
    ├── fun1.c
    ├── fun2.c
    └── main.c

对应的Makefile文件如下所示。其中.PHONY: clean是避免有名称为clean的文件而造成错误。

CC=gcc
IDIR =include
CFLAGS =-I$(IDIR)
 
ODIR=obj
LDIR=lib
 
LIBS=$(LDIR)/libdy.so
 
SRC =src
 
_DEPS = dylib.h fun1.h fun2.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) 
_OBJ = main.o fun1.o fun2.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
 
$(ODIR)/%.o: $(SRC)/%.c $(DEPS)
	$(CC) -c -o $@ $< $(CFLAGS)
 
main: $(OBJ)
    $(CC) -o $@ $^ $(LIBS) 
 
.PHONY: clean
 
clean:
    rm -f $(ODIR)/*.o

现在我们有了一个比较完美的makefile,大家可以自己修改以适应自己的需求。更多的参考如下:

A Simple Makefile Tutorial

GNU make

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux嵌入式开发是指在嵌入式系统中使用Linux操作系统进行开发。Linux操作系统具有开放性、可定制性、模块化等特点,使得它成为了嵌入式系统开发中最流行的操作系统之一。 本教程将以树莓派作为开发板,介绍Linux嵌入式开发的基础知识和实践。 准备工作: 1. 树莓派开发板 2. SD卡 3. 电脑 4. USB转串口工具 5. HDMI显示器和键盘(可选) 步骤1:安装Linux系统 1. 下载Raspberry Pi官方提供的系统镜像,可以从官网上下载:https://www.raspberrypi.org/downloads/ 2. 解压镜像文件,并将其写入SD卡中。可以使用Rufus等工具进行写入。 3. 将SD卡插入树莓派,连接电源和USB转串口工具。 步骤2:连接串口 1. 在电脑上安装串口调试工具,如SecureCRT、Putty等。 2. 打开串口调试工具,设置串口号和波特率,连接树莓派。 3. 在串口调试工具中输入用户名和密码登录树莓派。 步骤3:配置网络 1. 使用ifconfig命令查看树莓派的IP地址。 2. 在电脑上打开SSH客户端,如SecureCRT、Putty等。 3. 输入树莓派的IP地址和用户名、密码,即可在电脑上远程登录树莓派。 步骤4:开发环境搭建 1. 安装开发工具链,如gcc、g++等。 2. 安装调试工具,如gdb。 3. 安装版本控制工具,如git。 4. 安装构建工具,如make。 步骤5:开发应用程序 1. 创建一个简单的C程序,如Hello World。 2. 使用gcc编译程序,生成可执行文件。 3. 在树莓派上运行可执行文件,验证程序是否正常运行。 总结: 本教程介绍了Linux嵌入式开发的基础知识和实践。通过学习本教程,您可以了解Linux操作系统在嵌入式系统中的应用,学习如何使用树莓派进行开发,掌握基本的开发工具和技巧。希望本教程能够对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GaspardR

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

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

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

打赏作者

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

抵扣说明:

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

余额充值