IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++进阶:Makefile基础用法 -> 正文阅读

[C++知识库]C++进阶:Makefile基础用法

1. Makefile基本语法与执行

作用:
Makefile 文件告诉 Make 怎样编译和连接成一个程序

可用命令 dnf install make 安装make功能

格式:
按如下格式编写 Makefile

目标(target): 依赖(prerequiries)...
		命令(command)

注意:每个命令行前面必须是一个Tab字符,即命令行第一个字符是Tab

实验:
vim Makefile 编辑文件:

simpletest:simple.o simpletest.o
        g++ simple.o simpletest.o -o simpletest
simple.o:simple.cpp
        g++ -c simple.cpp -o simple.o
simpletest.o:simpletest.cpp
        g++ -c simpletest.cpp -o simpletest.o

结果为:

[root@foundation1 shishi]# make
g++ -c simple.cpp -o simple.o
g++ -c simpletest.cpp -o simpletest.o
g++ simple.o simpletest.o -o simpletest

命令上下是有顺序的,上一行对下一行具有依赖关系

如果文件夹中已经有.o文件,make后会提示已经生成,需要删除.o文件后再make

clean的作用: 被指定时会删除对应.o文件,避免上述情况

simpletest:simple.o simpletest.o
        g++ simple.o simpletest.o -o simpletest
simple.o:simple.cpp
        g++ -c simple.cpp -o simple.o
simpletest.o:simpletest.cpp
        g++ -c simpletest.cpp -o simpletest.o
clean:
        rm simpletest simple.o simpletest.o

结果为:

[root@foundation1 shishi]# make clean 
rm simpletest simple.o simpletest.o
[root@foundation1 shishi]# make
g++ -c simple.cpp -o simple.o
g++ -c simpletest.cpp -o simpletest.o
g++ simple.o simpletest.o -o simpletest

2. Makefile简化过程

使用变量: 如果调用某个文件用的次数较多,可以使用变量代替,变量可以直接替换

变量定义: 变量 = 字符串
变量使用: $(变量名)

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o simpletest.o

$(TARGET):$(OBJS)
        g++ $(OBJS) -o $(TARGET)
simple.o:simple.cpp
        g++ -c simple.cpp -o simple.o
simpletest.o:simpletest.cpp
        g++ -c simpletest.cpp -o simpletest.o
clean:
        rm $(TARGET) $(OBJS)

命令自动推导: 我们可以发现,由于 .cpp 文件都是生成对应的 .o 文件,所以 makefile 文件是可以自动识别的

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o simpletest.o

$(TARGET):$(OBJS)
        g++ $(OBJS) -o $(TARGET)
simple.o:simple.cpp
simpletest.o:simpletest.cpp
clean:
        rm $(TARGET) $(OBJS)

预定义变量: 系统中自己也定义了一些变量

变量程序默认值
CCC语言编译程序cc
CXXC++编译程序g++
ARC++打包程序ar
CPP带有标准输出的C语言预处理程序$(CC) -E
RM删除命令rm

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o simpletest.o

$(TARGET):$(OBJS)
        $(CXX) $(OBJS) -o $(TARGET)
simple.o:simple.cpp
simpletest.o:simpletest.cpp
clean:
        $(RM) $(TARGET) $(OBJS)

假想目标: 如果文件夹中有clean文件,那么make clean就不能使用,需要使用假想目标,可以在执行命令时不查看文件夹里面的文件,直接生效

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o simpletest.o

.PHONY: clean

$(TARGET):$(OBJS)
        $(CXX) $(OBJS) -o $(TARGET)
simple.o:simple.cpp
simpletest.o:simpletest.cpp
clean:
        $(RM) $(TARGET) $(OBJS)

建议不生成目标文件的命令都设为假想目标

3. Makefile生成并使用库

3.1 动态库的建立与使用

vim Makefile 编辑文件:

TARGET = simpletest
OBJS = simple.o
LIB = libsimple.so
CXXFLAGS = -c -fPIC

.PHONY: clean

$(TARGET):$(LIB) simpletest.o
        $(CXX) simpletest.o -o $(TARGET) -L. -lsimple
$(LIB):$(OBJS)
        $(CXX) -shared $(OBJS) -o $(LIB)
simple.o:simple.cpp
        $(CXX) $(CXXFLAGS) simple.cpp -o $(OBJS)
simpletest.o:simpletest.cpp
        $(CXX) $(CXXFLAGS) simpletest.cpp -o simpletest.o
clean:
        $(RM) $(TARGET) $(OBJS) $(LIB)

结果为:

[root@foundation1 shishi]# make clean 
rm -f simpletest simple.o libsimple.so
[root@foundation1 shishi]# make
g++ -c -fPIC simple.cpp -o simple.o
g++ -shared simple.o -o libsimple.so
g++ -c -fPIC simpletest.cpp -o simpletest.o
g++ simpletest.o -o simpletest -L. -lsimple

预定义变量:
还是需要在前面定义

变量程序参数
CFLAGS用于C编译器的额外标志
CXXFLAGS用于C++编译器的额外标志
ARFLAGS用于C/C++打包器的额外标志
LDFLAGS链接库路径-L
LDLIBS链接库-l

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o
LIB = libsimple.so
CXXFLAGS = -c -fPIC
LDFLAGS = -L.
LDLIBS = -lsimple

.PHONY: clean

$(TARGET):$(LIB) simpletest.o
        $(CXX) simpletest.o -o $(TARGET) $(LDFLAGS) $(LDLIBS)
$(LIB):$(OBJS)
        $(CXX) -shared $(OBJS) -o $(LIB)
simple.o:simple.cpp
        $(CXX) $(CXXFLAGS) simple.cpp -o $(OBJS)
simpletest.o:simpletest.cpp
        $(CXX) $(CXXFLAGS) simpletest.cpp -o simpletest.o
clean:
        $(RM) $(TARGET) $(OBJS) $(LIB)

自动变量:
自动变量是在规则每次执行时都基于目标和依赖产生新值的变量

自动变量含义
$<表示第一个匹配的依赖
$@表示目标
$^所有依赖
$?所有依赖中更新的文件
$+所有依赖文件不去重
$(@D)目标文件路径
$(@F)目标文件名称

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o
LIB = libsimple.so
CXXFLAGS = -c -fPIC
LDFLAGS = -L.
LDLIBS = -lsimple

.PHONY: clean

$(TARGET):simpletest.o $(LIB)
        $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS)
$(LIB):$(OBJS)
        $(CXX) -shared $^ -o $@
simple.o:simple.cpp
        $(CXX) $(CXXFLAGS) $< -o $@
simpletest.o:simpletest.cpp
        $(CXX) $(CXXFLAGS) $< -o $@
clean:
        $(RM) $(TARGET) $(OBJS) $(LIB)

自动匹配:
通配符主要用于匹配文件名,makefile中使用%作为通配符。从匹配目标格式的目标名中依据通配符抽取部分字符串,再按照抽取字符串分配到每一个依赖格式中产生依赖名。例如,使用%.o:%.cpp

可以让重复的语句合为一句

makefile 文件可改为:

TARGET = simpletest
OBJS = simple.o
LIB = libsimple.so
CXXFLAGS = -c -fPIC
LDFLAGS = -L.
LDLIBS = -lsimple
TESTOBJ = simpletest.o

.PHONY: clean

$(TARGET):$(TESTOBJ) $(LIB)
        $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS)

$(LIB):$(OBJS)
        $(CXX) -shared $^ -o $@

$(TESTOBJ) $(OBJS):%.o:%.cpp
        $(CXX) $(CXXFLAGS) $< -o $@

clean:
        $(RM) $(TARGET) $(OBJS) $(LIB) $(TESTOBJ)

在这里插入图片描述

3.2 动态加载库的建立与使用

TARGET = simpletest2
OBJS = simple.o
LIB = libsimple.so
CXXFLAGS = -c -fPIC
LDLIBS = -ldl
TESTOBJ = simpletest2.o

.PHONY: clean

# 生成可执行文件
$(TARGET):$(TESTOBJ) $(LIB)
        $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS)

# 生成库
$(LIB):$(OBJS)
        $(CXX) -shared $^ -o $@

# 生成目标文件
$(TESTOBJ) $(OBJS):%.o:%.cpp
        $(CXX) $(CXXFLAGS) $< -o $@

clean:
        $(RM) $(TARGET) $(OBJS) $(LIB) $(TESTOBJ)

结果为:

[root@foundation1 C++7.4]# make clean 
rm -f simpletest2 simple.o libsimple.so simpletest2.o
[root@foundation1 C++7.4]# make
g++ -c -fPIC simpletest2.cpp -o simpletest2.o
g++ -c -fPIC simple.cpp -o simple.o
g++ -shared simple.o -o libsimple.so
g++ simpletest2.o -o simpletest2  -ldl
[root@foundation1 C++7.4]# ./simpletest2
Simple()
Test()
~Simple()
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-10 14:21:50  更:2021-07-10 14:21:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 2:40:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码