makefile举例说明

文章目录

  • makefile文件
  • config.mk配置文件
  • common.mk文件

目录结构
在这里插入图片描述

makefile文件

include config.mk

导入config.mk的文件,通常包含项目的配置变量。

all:@for dir in $(BUILD_DIR); \do \make -C $$dir; \done

all是项目主目标,遍历BUILD_DIR变量每个子目录,并在每个子目录中运行make命令。

$$dir在Shell中被解释为$dir,因为Makefile中的Shell命令需要用 $$来转义$。

-C选项告诉make进入指定目录执行makefile。

clean:rm -rf app/link_obj app/dep nginxrm -rf signal/*.gch app/*.gch

clean目标用于清理文件。
rm -rf命令会强制删除列出的目录和文件,包括编译产生的目标文件、依赖文件、以及.gch预编译头文件。

如果子目录中的Makefile也有all和clean目标,它们应该被设计成可以被递归调用。

config.mk配置文件

定义环境变量,设置项目的编译环境和构建过程。

export BUILD_ROOT = $(shell pwd)

使用pwd命令动态获取当前工作目录,赋值给BUILD_ROOT变量。

通过export,这个变量将对所有被包含的Makefile文件可见,在子目录的Makefile中可以直接引用BUILD_ROOT

# 定义头文件的路径
export INCLUDE_PATH = $(BUILD_ROOT)/_include

INCLUDE_PATH变量指定项目中头文件的存放位置。
这对于编译器来说很重要,因为它需要知道去哪里查找.h等头文件。

# 定义编译目录
BUILD_DIR = $(BUILD_ROOT)/signal/ \$(BUILD_ROOT)/proc/   \$(BUILD_ROOT)/net/    \$(BUILD_ROOT)/misc/   \$(BUILD_ROOT)/logic/   \$(BUILD_ROOT)/app/

BUILD_DIR变量列出了需要编译的子目录。

# 编译时是否生成调试信息。GNU调试器可以利用该信息
# 很多调试工具,包括Valgrind工具集都会因为这个为true能够输出更多的调试信息;
export DEBUG = true

DEBUG变量设为true意味着编译时将包含调试信息。
这对于开发阶段非常有用,因为生成的可执行文件可以被调试器读取并提供详细的运行时信息。如果设置为false,则会生成优化过的二进制文件,但调试信息将不会包含在内。

export BUILD_ROOT = $(shell pwd)
export INCLUDE_PATH = $(BUILD_ROOT)/_include
BUILD_DIR = $(BUILD_ROOT)/signal/ \$(BUILD_ROOT)/proc/   \$(BUILD_ROOT)/net/    \$(BUILD_ROOT)/misc/   \$(BUILD_ROOT)/logic/   \$(BUILD_ROOT)/app/ 
export DEBUG = true

common.mk文件

这段Makefile代码定义了一个更复杂的构建流程,包括条件编译、源文件和目标文件的管理、依赖生成以及清理规则。

.PHONY: all clean

.PHONY指令确保allclean这两个目标不会被解释器误认为是文件,而是当作伪目标来处理。

ifeq ($(DEBUG),true)
CC = g++ -std=c++11 -g
VERSION = debug
else
CC = g++ -std=c++11
VERSION = release
endif

根据DEBUG变量的值选择编译器和编译选项。如果是true,则使用-g选项生成调试信息。

SRCS = $(wildcard *.cxx)
OBJS = $(SRCS:.cxx=.o)
DEPS = $(SRCS:.cxx=.d)

使用wildcard函数动态获取当前目录下的所有.cxx文件,并分别生成对应的.o.d文件列表。
.d文件是依赖关系文件,修改项目后能决定哪些文件需要重新编译。

LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
DEP_DIR = $(BUILD_ROOT)/app/dep

对象文件和依赖文件的输出目录。

OBJS := $(addprefix $(LINK_OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))

.o.d文件的路径前缀修改为相应的输出目录。

$(shell mkdir -p $(LINK_OBJ_DIR))
$(shell mkdir -p $(DEP_DIR))

创建目录,确保输出目录存在。

all: $(DEPS) $(OBJS) $(BIN)

主要构建目标all依赖于所有.d文件、.o文件和最终的二进制文件$(BIN)

ifneq ("$(wildcard $(DEPS))","")
include $(DEPS)
endif

如果.d文件存在,则包含它们,以便Makefile能够识别由.d文件定义的依赖关系。

$(BIN): $(LINK_OBJ)...$(CC) -o $@ $^ -lpthread

构建最终的可执行文件$(BIN),它依赖于所有.o文件,并链接线程库pthread

$(LINK_OBJ_DIR)/%.o: %.cxx$(CC) -I$(INCLUDE_PATH) -o $@ -c $(filter %.cxx,$^)

规则用于编译单个.cxx源文件到.o文件,使用-I选项指定头文件路径。

$(DEP_DIR)/%.d: %.cxxecho -n $(LINK_OBJ_DIR)/ > $@$(CC) -I$(INCLUDE_PATH) -MM $^ >> $@

生成依赖文件.d,它包含了每个.o文件对于.cxx.h文件的依赖。-MM选项生成Makemake风格的依赖文件。

clean:rm -f $(BIN) $(OBJS) $(DEPS) *.gch

清理规则用于删除构建产生的所有文件,包括二进制文件、对象文件、依赖文件和GCC优化文件。

整个Makefile设计了一套完整的自动化构建流程,包括源文件的编译、依赖文件的生成、最终可执行文件的链接以及清理操作。这种结构有助于大型项目的管理和维护。

.PHONY: all clean
ifeq ($(DEBUG),true)CC = g++ -std=c++11 -g 
VERSION = debug
else
CC = g++ -std=c++11
VERSION = release
endifSRCS = $(wildcard *.cxx)
OBJS = $(SRCS:.cxx=.o)
DEPS = $(SRCS:.cxx=.d)
BIN := $(addprefix $(BUILD_ROOT)/,$(BIN))
LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
DEP_DIR = $(BUILD_ROOT)/app/dep$(shell mkdir -p $(LINK_OBJ_DIR))
$(shell mkdir -p $(DEP_DIR))OBJS := $(addprefix $(LINK_OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ += $(OBJS)all:$(DEPS) $(OBJS) $(BIN)ifneq ("$(wildcard $(DEPS))","")  
include $(DEPS)  
endif$(BIN):$(LINK_OBJ)@echo "------------------------build $(VERSION) mode--------------------------------!!!"$(CC) -o $@ $^ -lpthread$(LINK_OBJ_DIR)/%.o:%.cxx$(CC) -I$(INCLUDE_PATH) -o $@ -c $(filter %.cxx,$^)$(DEP_DIR)/%.d:%.cxxecho -n $(LINK_OBJ_DIR)/ > $@$(CC) -I$(INCLUDE_PATH) -MM $^ >> $@

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393672.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue+uniapp的“口腔助手”小程序

开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…

Python开发: 飞机大战 小游戏

玩法 你可以控制飞机左右移动,躲避敌机子弹,同时发射自己的炮弹,将敌人击落! 部署方案: 1、代码如下图; 2、将代码保存到一个python中,比如planeFight.py; 3、在你的电脑中安装p…

为什么需要云仓?

云仓,即云端仓储管理,是指通过互联网技术整合和管理仓储资源,实现高效、低成本的库存管理和物流服务。随着电子商务的发展和企业供应链全球化的加剧,云仓成为现代企业管理的一种重要手段。 1、云仓可以显著提高仓储管理效率&#…

算法测试.

一.CodeForces 1829A 题意&#xff1a; 题目意思就是给你t个字符串&#xff0c;让你找出每个串与codeforces这个串有多少不同的字母&#xff1b; 题解&#xff1a; 定义一个变量循环比较字符串&#xff0c;不相同计数即可&#xff1b; 代码&#xff1a; #include <iost…

SQL二次注入

目录 1.什么是二次注入&#xff1f; 2.二次注入过程 2.1寻找注入点 2.2注册admin#用户 2.3修改密码 1.什么是二次注入&#xff1f; 当用户提交的恶意数据被存入数据库后&#xff0c;因为被过滤函数过滤掉了&#xff0c;所以无法生效&#xff0c;但应用程序在从数据库中拿…

TCP Analysis Flags 之 TCP Window Full

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

supermap制作发布二三维地图服务

一、下载安装 软件版本&#xff1a; SuperMap iDesktopX 11i(2023) SP1 for Windows SuperMap iServer 11i(2023) SP1 for Windows 下载地址&#xff1a; http://support.supermap.com.cn/DownloadCenter/ProductPlatform.aspx 二、运行 服务端&#xff1a;双击iserver的…

C# Unity 面向对象补全计划 设计者模式 之 单例模式

本文仅作学习笔记与交流&#xff0c;不作任何商业用途&#xff0c;作者能力有限&#xff0c;如有不足还请斧正 本系列作为七大原则和设计模式的进阶知识&#xff0c;看不懂没关系 了解我的专栏C#面向对象与进阶:http://t.csdnimg.cn/mIitr&#xff0c;尤其是关于类的那篇文章即…

Python(模块---pandas+matplotlib+pyecharts)

import pandas as pd import matplotlib.pyplot as plt dfpd.read_excel(简易数据.xlsx) # print(df) plt.rcParams[font.sans-serif][SimHei] #设置画布的大小 plt.figure(figsize(10,6)) labelsdf[电影中文名] ydf[国籍] # print(labels) # print(y)# import pandas as pd im…

在Stable Diffusion中驱动Tesla P40

一、安装P40显卡 在前面我的“在win10电脑上搭建python环境下的本地AI绘画工具Stable Diffusion”博文中&#xff0c;Stable Diffusion的运行完全依赖CPU和内存&#xff0c;因此每生成一次图片&#xff0c;需几小时之多&#xff0c;我常是在临下班时开始生成&#xff0c;到第二…

Go语言标准库中的双向链表的基本用法

什么是二分查找区间&#xff1f; 什么是链表&#xff1f; 链表节点的代码实现&#xff1a; 链表的遍历&#xff1a; 链表如何插入元素&#xff1f; go语言标准库的链表&#xff1a; 练习代码&#xff1a; package mainimport ("container/list""fm…

连接一切:Web3如何重塑物联网的未来

传统物联网的挑战 物联网&#xff08;IoT&#xff09;正在迅速改变我们的世界&#xff0c;通过将各种设备连接到互联网&#xff0c;它使得设备能够相互交流&#xff0c;提供智能化的服务和解决方案。然而&#xff0c;随着物联网的迅猛发展&#xff0c;安全性、隐私保护和设备互…

React 知识点(二)

文章目录 一、React 组件二、React 组件通信 - 父子通信三、React 组件通信 - 子父通信四、React 组件通信 - 兄弟通信五、React 组件通信 - 跨组件通信(祖先)六、结合组件通信案例七、props-children 属性八、props-类型校验九、React 生命周期十、setState 扩展 一、React 组…

MySQL的简单介绍

文章目录 数据库关系型数据库非关系型数据”数据库的概念和用途MySQL数据库服务器、数据库和表的关系数据库的创建和删除表创建表修改常见的数据类型和约束字符串类型日期和时间类型PRIMARY KEY使用AUTO_INCREMENT使用UNIQUE使用FOREIGN KEY使用 SQL语言基础SQL语言简介SQL分类…

C++入门基础知识

在之前我们学习了C语言和初阶数据结构的相关知识&#xff0c;现在已经有了一定的代码能力和对数据结构也有了基础的认识&#xff0c;接下来我们将进入到新的专题当中&#xff0c;这个专题就是C。在C中我们需要花费更大的精力和更长的时间去学习这门建立在C语言基础之上的计算机…

接了一个2000块的小活,大家进来看看值不值,附源码

如题&#xff0c;上周的一天&#xff0c;朋友圈的一个旧友找到了我&#xff0c;说让我帮他开发一个小工具&#xff0c;虽然活不大&#xff0c;但没个几年的全栈经验还不一定能接下来&#xff0c;因为麻雀虽小&#xff0c;涉及的内容可不少&#xff1a; 需求分析 原型设计 详细…

LSPatch制作内置模块应用软件无需root 教你制作内置应用

前言 LSPatch功能非常强大&#xff0c;它是一款基于LSPosed核心的免Root Xposed框架软件。这意味着用户无需进行手机root操作&#xff0c;即可轻松植入内置Xposed模块&#xff0c;享受更多定制化的功能和体验&#xff0c;比如微某内置模块版等&#xff0c;这为那些不想root手机…

vue项目部署在子路径中前端配置

vue.config.JS router/index.js或者是man.js

【开发踩坑】windows查看jvm gc信息

windows查看jvm gc信息 EZ 找出java进程PID 控制面板----搜索任务管理器---- 任务管理器----搜索 java----详细信息 这里PID是4856 cmd jstat gc面板 reference&#xff1a; jstat命令