Makefile简介及如何指定头文件和库文件

Makefile简介及如何指定头文件和库文件

Makefile简介及如何指定头文件和库文件

原创

已于 2023-05-28 12:58:06 修改

·

1.3w 阅读

·

8

·

54

·

CC 4.0 BY-SA版权

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

文章标签:

#ubuntu

#linux

#运维

于 2023-02-19 13:23:34 首次发布

开发语言

同时被 2 个专栏收录

63 篇文章

订阅专栏

cmake

8 篇文章

订阅专栏

Makefile是用于自动化编译的工具,当C/C++项目源文件较多时,通过编写Makefile预设编译规则,执行make命令即可批量编译。相对于直接使用命令行,Makefile节省时间,尤其是大型项目。文章介绍了Makefile的基本语法,包括目标、依赖和规则命令,并通过不同版本的示例展示其使用,包括如何简化Makefile、处理源文件变化以及添加新文件的情况。此外,还提及了cmake作为更现代的替代选择。

Makefile简介

初学C/C++时,我们编译源文件时,通常直接敲命令去进行编译。但在实际项目中,源文件非常多,直接敲命令编译就不现实了,这时候就需要用到Makefile,Makefile是一个文本文件,我们只需要提前在Makefile中写好源文件的编译规则,然后直接执行make命令,就可以自动编译。现在使用cmake的比较多,cmake相比于makefile,语法更加简洁,学习门槛更低,实现相同的编译功能,Makefile可能需要几十行脚本来完成,cmake只需要几行脚本就可以搞定。但鉴于可能有些老项目或者部分公司依旧使用makefile,所以我们还是得对此熟悉。

Makefile语法

Makefile有三大要素:目标、依赖、规则命令

目标:我们要生成的最终文件依赖:生成目标文件要依赖的文件规则命令:要生成目标文件所执行的命令

语法

目标:依赖

规则命令

注:规则命令前面必须要有Tab键

简单使用

目前有以下源文件

├── main.cpp

├── Makefile

├── myadd.cpp

├── myadd.h

├── myminus.cpp

└── myminus.h

版本一

# 生成最终可执行文件的文件名和需要的依赖文件

res:main.o myadd.o myminus.o

# 生成最终可执行文件需要执行的命令

g++ main.o myadd.o myminus.o -o res

# 生成中间文件main.o需要的源文件

main.o:main.cpp

# 生成中间文件main.o需要执行的命令

g++ -c main.cpp

myadd.o:myadd.cpp

g++ -c myadd.cpp

myminus.o:myminus.cpp

g++ -c myminus.cpp

# 执行清理操作

clean:

rm *.o

直接执行make命令就可以生成最终可执行文件res

root@ubuntu:/home/lng/makefiledir# make

g++ -c main.cpp

g++ -c myadd.cpp

g++ -c myminus.cpp

g++ main.o myadd.o myminus.o -o res

root@ubuntu:/home/lng/makefiledir# ls

main.cpp main.o Makefile myadd.cpp myadd.h myadd.o myminus.cpp myminus.h myminus.o res

root@ubuntu:/home/lng/makefiledir#

一般*.o文件是不需要的,可以执行make clean命令来清除*.o文件

root@ubuntu:/home/lng/makefiledir# make clean

rm *.o

root@ubuntu:/home/lng/makefiledir# ls

main.cpp Makefile myadd.cpp myadd.h myminus.cpp myminus.h res

root@ubuntu:/home/lng/makefiledir#

备注

可能有人会有疑问,为什么一定要生成中间文件*.o, 我们平常使用命令编译时,都是直接用源文件生成可执行文件。当然可以不用生成*.o文件,使用以下命令,直接用源文件生成可执行文件

res:main.cpp myadd.cpp myminus.cpp

g++ main.cpp myadd.cpp myminus.cpp -o res

但这样就会存在一个问题,一旦我们修改任何一个源文件,所有的文件都重新编译。在一些大型项目中,编译是非常耗时的,每修改一个源文件,都去重新编译,这将大大降低工作效率。因此我们通常都是先生成中间文件*.o, 当我们修改其中一个源文件时,只需要编译修改的文件,其他文件都不需要重新编译。

版本二

在makefile中允许我们使用变量,可以对Makefile内容进行简化

# 对变量赋值

Target=res

Objs=main.o myadd.o myminus.o

Src=main.cpp myadd.cpp myminus.cpp

# 取出变量中的值

$(Target):$(Objs)

g++ $(Objs) -o $(Target)

$(Objs):$(Src)

g++ -c $(Src)

clean:

rm *.o

这个版本的Makefile与版本一的效果完全一样,但代码量更少,也更简洁。

版本三

目前还存在一个问题,就是我们一旦要添加新的源文件,必须修改Makefile,有没有一种写法,在添加源文件时不需要修改Makefile?当然也有。首先需要介绍两个函数和四个变量函数

wildcard:进行文件匹配patsubst:内容替换

变量

$@ : 目标$^ : 全部依赖$< : 第一个依赖$? : 第一个变化的

Target=res

# 获取当前目录下所有源文件

Src:=$(wildcard *.cpp)

# 将所有*.cpp文件替换为*.o文件。Objs变量中就保存了所有*.o文件名

Objs:=$(patsubst %.cpp,%.o, $(Src))

$(Target):$(Objs)

g++ $(Objs) -o $(Target)

*.o:*.cpp

# 相当于 g++ -c *.cpp -o *.o

g++ -c $< -o $@

clean:

rm *.o

通过变量和函数我们就可以自动获取文件名,不用再去手动进行赋值。

指定头文件和库文件

目录结构如下

├── include

│ ├── myadd.h

│ ├── myminus.h

│ └── mymult.h

├── lib

│ └── libmymult.so

├── Makefile

└── src

├── main.cpp

├── myadd.cpp

└── myminus.cpp

Makefile

# 指定编译器

CC=g++

#指定编译选项

CFLAGS=-Wall -g

Target=res

Src:=$(wildcard ./src/*.cpp)

Objs:=$(patsubst %.cpp,%.o, $(Src))

#指定头文件位置

INCLUDES = -I ./include

#指定库文件

LIBS=-L ./lib -lmymult

$(Target):$(Objs)

echo $(Objs)

@mkdir -p output

$(CC) $(Objs) $(LIBS) -o output/$(Target)

%.o:%.cpp

$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@

clean:

rm $(Objs)

相关推荐

Windows控制面板使用指南:打开方法与常见设置详解
求正规英国365网址

Windows控制面板使用指南:打开方法与常见设置详解

📅 11-15 👁️ 7779
金融掮客自述:大型企业是如何倒闭的?
365bet中文官方网站

金融掮客自述:大型企业是如何倒闭的?

📅 08-04 👁️ 6416
国际友谊赛对足球世界杯的备战与战术调整影响分析
手机营业厅流量共享怎么查剩余流量
365bet中文官方网站

手机营业厅流量共享怎么查剩余流量

📅 07-08 👁️ 8290
适合表白的歌曲有哪些,这些歌曲助你表白成功
365bet中文官方网站

适合表白的歌曲有哪些,这些歌曲助你表白成功

📅 10-25 👁️ 4031
特斯拉准备交付后多久可以提车
be七365官网

特斯拉准备交付后多久可以提车

📅 11-05 👁️ 9752