Makefile文件

Makefile简介

Makefile作用

Makefile是一个用于自动构建过程的文件,常用于在Uinx/Linux环境下管理编译和链接源代码的步骤。它是Make工具的输入文件,定义了如何从源文件生成目标文件(例如可执行文件或库),以及清理构建目录等任务。通过Makefile,可以简化和自动化编译过程,避免手动输入繁琐的编译命令。

自动化构建过程

定义构建规则和依赖关系,自动化执行编译和链接步骤。
通过一条简单的命令(通常是 make),完成从源代码到可执行文件的构建。

依赖管理

追踪文件之间的依赖关系,只重新编译那些发生改变的文件,节省编译时间。
通过检查文件的时间戳,确保所有依赖关系都得到满足。

提高效率

减少重复工作,避免手动输入多个编译命令。
提供一种一致且可重复的构建方法,降低出错的可能性。

灵活性和可扩展性

可以通过变量和条件判断增加灵活性,适应不同的构建环境和配置。
支持自定义规则和目标,可以扩展构建过程,例如生成文档、运行测试等

Makefile 的基本结构

变量定义

  • 用于简化命令和路径的管理,例如源文件列表,编译器选项等
CC = gcc
CFLAGS = -Wall -g -O2
SRCS = main.c utils.c
OBJS = $(SRCS:.c=.o)

规则定义

  • 每个规则定义了如何从一组依赖文件生成目标文件。规则由目标(target)、依赖(dependencies)和命令(commands)组成。
target: dependencies
    command
  • 示例
all: my_program

my_program: main.o utils.o
    $(CC) -o my_program main.o utils.o $(CFLAGS)

main.o: main.c
    $(CC) -c main.c $(CFLAGS)

utils.o: utils.c
    $(CC) -c utils.c $(CFLAGS)

自动变量
  • 在规则的命令部分使用的特殊变量,例如:
    $@:目标文件名。
    $<:第一个依赖文件名。
    $^:所有依赖文件名
main.o: main.c
    $(CC) -c $< -o $@ $(CFLAGS)

伪目标

  • 不生成文件的目标,用于定义一些常见任务,如清理构建目录。
.PHONY: clean
clean:
    rm -f my_program *.o

示例

CC = gcc
CFLAGS = -Wall -g -O2
SRCS = main.c utils.c
OBJS = $(SRCS:.c=.o)
TARGET = my_program

all: $(TARGET)

$(TARGET): $(OBJS)
    $(CC) -o $@ $^ $(CFLAGS)

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

.PHONY: clean
clean:
    rm -f $(TARGET) $(OBJS)

在这个例子中:

  • CC 定义了编译器。
  • CFLAGS 定义了编译器选项。
  • SRCS 列出了源文件。
  • OBJS 将源文件名转换为对象文件名。
  • TARGET 定义了目标可执行文件的名称。
  • all 是默认目标,用于构建整个项目。
  • $(TARGET)依赖于所有对象文件,描述了如何链接这些对象文件生成可执行文件
  • %.o: %.c 是一个模式规则,用于描述如何从源文件生成对象文件。
  • clean 是一个伪目标,用于清理构建生成的文件。

Makefile各种文件说明和关系

源文件

  • 定义:源文件是用编程语言(如C、C++)编写的文本文件,包含程序的代码和逻辑
  • 扩展名:通常以 .c、.cpp、.h 等为扩展名。
  • 作用:源文件是编译器的输入,编译器将源文件转换为目标文件。

目标文件

  • 定义:目标文件是编译器将源文件编译后的中间文件,包含机器代码和数据,但还未链接成可执行文件。
  • 扩展名:通常以 .o 或 .obj为扩展名。
  • 作用:目标文件是链接器的输入,链接器将多个目标文件和库文件链接成可执行文件

依赖文件

  • 定义:依赖文件描述了源文件之间的依赖关系,通常由编译器生成,用于确定哪些文件需要重新编译。
  • 扩展名:通常以 .d 为扩展名。
  • 作用:依赖文件用于构建系统(如 Makefile)来管理源文件的编译过程,确保当源文件改变时,相关的目标文件能够被重新编译。

静态库文件

  • 定义:静态库文件是多个目标文件的集合,打包成一个归档文件,可以在链接时被包含到可执行文件中。
  • 扩展名:通常以 .a为扩展名(在Windows上为 .lib)。
  • 作用:静态库文件用于代码重用和模块化,可以被多个项目共享和链接。

文件之间的关系和编译流程

  • 源文件到目标文件:编译器将源文件(如 main.c)编译成目标文件(如 main.o)。
  • 目标文件和依赖文件:编译过程中生成依赖文件(如 main.d),用于跟踪文件依赖关系。
  • 目标文件到可执行文件:链接器将多个目标文件(如 main.o、utils.o)和静态库(libmylib.a)链接成可执行文件(如 my_program)。
  • 静态库的使用:静态库(如libmylib.a)是多个目标文件的集合,可以在链接时被包含到可执行文件中,提供所需的功能和代码。

具体Makefile文件解析

#-----------------------------------变量定义-------------------------------#
#使用wildcard函数来获取符合路径模式的所有.c文件,包括./phy目录下的二级和三级子目录中的.c文件,以及./l1c目录下的所有子目录中的.c文件
PHY_LIB = $(wildcard ./phy/*/*/*.c) $(wildcard ./phy/*/*.c) $(wildcard ./l1c/*/*.c)
#包含所有的源文件,即前面定义的PHY_LIB和当前目录下的rrm_meas_test.c文件。
SRCS =  $(PHY_LIB) rrm_meas_test.c
#将所有的.c文件扩展名替换为.o,生成对象文件列表
OBJS = $(SRCS:.c=.o)
#定义编译器为icc
CC = icc
# 定义链接时需要的库,包括数学库、线程库、MKL(Intel Math Kernel Library)、OpenMP库、实时库和NLopt优化库
LIBS = -lm -lpthread -lmkl_rt -mkl=sequential -fopenmp -lrt -lnlopt
#定义编译选项
CCFLAGS = -Wall -g -O3 -march=core-avx2 -std=c99 -m64 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D_LARGE_FILE_SOURCE -MMD #附加参数
#定义生成的可执行文件名为rrm_meas_test
OUTPUT = rrm_meas_test

#-----------------------------------规则定义---------------------------------#
#默认目标是生成$(OUTPUT)
all: $(OUTPUT)
#依赖所有对象文件$(OBJS)。使用Intel编译器将这些对象文件链接成可执行文件,并添加指定的库和-pg(生成用于gprof的分析信息)选项
$(OUTPUT): $(OBJS)
	$(CC) $^ -o $@ $(LIBS) -pg
#包括所有的依赖文件(.d文件),这些文件由编译器生成,用于描述各源文件的依赖关系。-include表示即使这些文件不存在,Make也不会报错
-include *.d
-include ./phy/*/*.d
-include ./phy/*/*/*.d
-include ./l1c/*/*.d
#任何.c文件对应的.o文件,使用Intel编译器进行编译。$<代表依赖文件(.c文件),$@代表目标文件(.o文件),使用$(CCFLAGS)作为编译选项
%.o: %.c
	$(CC) -c $< -o $@ $(CCFLAGS)
#没有命令,这个目标仅仅用于依赖可执行文件。
run: $(OUTPUT)
#依赖可执行文件,使用valgrind进行内存泄漏检查,输出详细的内存泄漏信息和错误来源。
memcheck: $(OUTPUT)
	valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./$(OUTPUT)

#-----------------------------------伪目标--------------------------------------#
#声明为伪目标。clean是一个伪目标,用于清理构建生成的文件
.PHONY: clean
#删除所有生成的目标文件(.o)、依赖文件(.d)和可执行文件(rrm_meas_test),包括不同目录下的文件。
clean:
	rm -rf reg_rw *.o *.d *.bin rrm_meas_test
	rm -rf ./phy/*/*.o
	rm -rf ./phy/*/*.d
	rm -rf ./phy/*/*/*.o
	rm -rf ./phy/*/*/*.d
	rm -rf ./l1c/*/*.o
	rm -rf ./l1c/*/*.d
Makefile是一个自动化编译的工具,它通过一个名为make的程序来使用,通常在Unix-like操作系统中使用,也可以在Windows上使用。Makefile定义了一系列的规则来说明如何编译和链接程序。在Makefile文件中,可以指定需要编译的源文件和编译后生成的目标文件,并且可以设置编译过程中的依赖关系。当一个或多个源文件被修改时,make命令可以自动决定需要重新编译的程序部分,这样可以节省大量重新编译整个程序的时间。 Makefile主要由三个部分组成:规则(Rules)、变量定义(Variable Definitions)、指令(Directives)。规则部分描述了如何构建目标文件以及它们之间的依赖关系;变量定义用于存储文件路径、编译选项等信息,以简化Makefile的编写;指令则是make执行的命令,如条件判断和循环等。 一个简单的Makefile的例子如下: ```makefile # 定义编译器 CC=gcc # 定义编译选项 CFLAGS=-Wall -g # 定义目标文件 TARGET=hello # 定义依赖关系 hello.o: hello.c $(CC) -c $(CFLAGS) hello.c # 定义最终目标 hello: hello.o $(CC) -o $(TARGET) hello.o # 清理编译生成的文件 clean: rm -f $(TARGET) *.o ``` 在这个Makefile中,定义了一个名为`hello`的目标,它依赖于`hello.o`。当执行`make hello`命令时,会首先检查`hello.o`是否比`hello.c`新,如果是,则编译生成`hello.o`,然后链接生成最终的可执行文件`hello`。执行`make clean`则会删除所有编译生成的文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值