项目实用makefile

2023-05-16

       
        在上一篇文章“小项目实用makefile”中,已经说明了单个makefile管理层次目录的局限性。本文,主要总结一下项目中的一种实用makefile树写法,为10来个人协作的中小型项目makefile编写,提供参考。
       
        1. 需求
        从实用角度,makefile树应该达到以下需求:
        1)自动加入编译系统。新增目录、文件后,能够自动添加(理想),或只需少许修改,就能添加到整个项目编译中。
        2)可读性好,易于添加。新增目录、文件,linux新人能自己看懂添加(理想),或只需口头10s描述就能很好完成。
        3)模块化。新增目录、文件后的makefile,和其他目录完全没有关系(理想),或只需与最邻近的前、后有关系。
     

        2. 实现
        2.1 自动加入编译系统
        使用makefile递归执行,能够解决此问题。以下脚本,能够执行SUBDIRS指定的子目录内的makefile。

makefile。
SUBDIRS	= modual-a modual-b	modual-c
   
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
	$(MAKE) -C $@

        说明:
        1)变量SUBDIRS,指定当前目录下,要递归编译的子目录。
        2).PHONY及subdirs目标结构,能保证递归到子目录中。
           
        2.2 可读性好,易于添加;模块化
        使用makefile的变量定义,其位置前后不敏感特性可以做到。示例脚本如下:

SUBDIRS	= modual-a modual-b	modual-c
OBJECTS	= x.o y.o z.o

all:subdirs ${OBJECTS}

clean:cleansubdirs
	rm ${OBJECTS}

        说明:
        1)变量OBJECTS,指定当前目录的目标文件。新增一个文件z.cpp,在变量OBJECTS中,增加z.o即可。
        2)新增一个目录dir-c,在变量SUBDIRS中,增加dir-c。然后参考本目录中的makfile,在dir-c中,建立一个类似makfile即可。
        
        2.3 减少重复脚本
        实现中,将makefile中的共用变量,转移到文件中,使用include包含,能够达到函数效果,减少重复脚本,容易改变。

        
       
3. 实例
        示例项目目录如下所示(点击下载示例项目

project-test
  +-- makeconfig
  |     +-- make.global
  +-- src
  |     +-- module-a
  |     |     +-- test.cpp
  |     |     +-- Makefile
  |     +-- module-b
  |     |     +-- test.cpp
  |     |     +-- Makefile
  |     +-- main.cpp
  |     +-- Makefile
  +-- Makefile

        说明:
        1)project-test/makeconfig/make.global,要包含的makefile共用变量。
        2)project-test/Makefile,顶层makefile,指定可执行目标,及源码目录。
        3)project-test/src/Makefile,子目录的makeflile。目录module-a、module-b的类似,每个目录一个。
        
        3.1 project-test/makeconfig/make.global
        如下所示:

# compile macro
CC		= g++
CFLAGS		= -O2 -Wall
LDFLAGS	= -lm 
INCLUDES	= -I/usr/local/include


# recursive make
.PHONY: subdirs ${SUBDIRS} cleansubdirs
subdirs: ${SUBDIRS}
${SUBDIRS}:
	${MAKE} -C $@ all

	
# recursive make clean
cleansubdirs:
	@for dir in ${SUBDIRS}; do \
		${MAKE} -C $$dir clean; \
	done

	
# dependence
%.o: %.cpp
	${CC} ${CFLAGS} ${INCLUDES} -c $< -o $@
%.o: %.cc
	${CC} ${CFLAGS} ${INCLUDES} -c $< -o $@	

        说明:
        1)包含4个区域,共用变量,递归make,递归makeclean,依赖关系。
        2)递归makeclean,使用了不打印的shell语法。原因是,如果和递归一样写,会造成目标重载警告。
       
        3.2 project-test/Makefile
        如下所示: 

# target, subdir, objects in current dir
TARGET		= test
SUBDIRS	= src
OBJECTS	= 


all:subdirs ${OBJECTS}
	${CC} -o ${TARGET} $$(find ./${SUBDIRS} -name '*.o') ${LDFLAGS} ${INCLUDES}


clean:cleansubdirs
	rm -f ${TARGET} ${OBJECTS}


# path of "make global scripts"
# NOTE, use absolute path. export once, use in all subdirs
export PROJECTPATH=${PWD}
export MAKEINCLUDE=${PROJECTPATH}/makeconfig/make.global

# include "make global scripts"
include ${MAKEINCLUDE}

        说明:
        1)使用shell语法,搜索出指定目录的所有.o,链接为执行目标文件。
        2)使用export,指定项目绝对路径,指定共用变量,包含所有目录共用的makefile变量。
        3)每个目标使用一个顶层的makefile,来执行make和makeclean的递归入口,共用makefile。
       
        3.3 project-test/src/Makefile
        如下所示:

# subdir and objects in current dir
SUBDIRS	= module-a module-b
OBJECTS	= main.o


all:subdirs ${OBJECTS}

	
clean:cleansubdirs
	rm -f ${OBJECTS}
	
include ${MAKEINCLUDE}

        说明:
        1)增加目录,只用修改子目录变量SUBDIRS;增加文件,修改当前目标文件变量OBJECTS。
        2)不同目录下,源码相同名字,但类、函数不相同,可以正常编译。        
        
       
4. 专业makefile树
        以上,只是一个项目最最普通的makefile树。一个实现文件一个.o文件,不考虑库生成,不考虑功能配置项,不考虑平台兼容性。
        一些开源项目,考虑了各种平台兼容性,及功能特性,通常使用了autoconf和automake,自动生成特殊头文件和宏定义,来达到效果。使用以下3条命令,向用户提供配置项设置,编译,库、头文件、或目标文件安装路径。在复杂兼容项目中,非常实用。
        ./configure
        make
        make install
        还在继续学习中。
        
        参考资料:
        1. GNU Make Manual:
http://www.gnu.org/software/make/manual/
        2. 同事J的makefile树。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

项目实用makefile 的相关文章

随机推荐

  • C在字符串后面加/0和0

    使用复制字符串时 xff0c 经常会遇到字符串后面跟着一大堆莫名其妙的字符串 xff0c 例如屯屯屯 之类的东西 xff0c 这是因为在使用字符串时没有在字符串结尾加 0或0 通常分配一块内存到堆上或栈上时 xff0c 内存区域可能会有之前
  • 基于k8s+prometheus实现双vip可监控Web高可用集群

    目录 一 规划整个项目的拓扑结构和项目的思维导图 二 修改好各个主机的主机名 xff0c 并配置好每台机器的ip地址 网关和dns等 2 1修改每个主机的ip地址和主机名 2 2 关闭firewalld和selinux 三 使用k8s实现W
  • PX4源码开发人员文档(一)——软件架构

    软件架构 PX4 在广播消息网络内 xff0c 按照一组节点 xff08 nodes xff09 的形式进行组织 xff0c 网络之间使用像如 姿态 和 位置 之类的语义通道来传递系统状态 软件的堆栈结构主要分为四层 应用程序接口 提供给a
  • ardupilot线程理解

    对于apm和pixhawk一直存在疑惑 xff0c 到现在还不是特别清楚 今天在http dev ardupilot com 看到下面的说明 xff0c 感觉很有用 xff0c 对于整体理解amp代码很有帮助 xff0c 所以记下来 转载请
  • Pixhawk源码笔记三:串行接口UART和Console

    这里 xff0c 我们对 APM UART Console 接口进行讲解 如有问题 xff0c 可以交流30175224 64 qq com 新浪 64 WalkAnt xff0c 转载本博客文章 xff0c 请注明出处 xff0c 以便更
  • C/C++中二维数组和指针关系分析

    在C c 43 43 中 xff0c 数组和指针有着密切的关系 xff0c 有很多地方说数组就是指针式错误的一种说法 这两者是不同的数据结构 其实 xff0c 在C c 43 43 中没有所谓的二维数组 xff0c 书面表达就是数组的数组
  • 四叉树空间索引原理及其实现

    今天依然在放假中 xff0c 在此将以前在学校写的四叉树的东西拿出来和大家分享 四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构 它将已知范围的空间等分成四个相等的子空间 xff0c 如此递归下去 xff0c 直至树的层次达到一定
  • DirectXShaderCompiler mac编译

    Directxshader compiler mac编译 1 前置条件 Please make sure you have the following resources before building GitPython Version
  • intel -tbb 源码cmake构建

    cmake minimum required VERSION 3 0 0 FATAL ERROR set CMAKE CXX STANDARD 17 project tbb CXX add library tbb SHARED void c
  • 如何修改数据库密码

    多可文档管理系统是自带数据库的 xff0c 就是你在安装多可文档管理系统的同时 xff0c 数据库就已经自动安装上了 这个数据库有个默认密码 xff0c 为了数据库里的数据安全 xff0c 建议你安装完多可后 xff0c 就立刻修改数据库的
  • iOS编译openmp

    1 下载openmp源码 https github com llvm llvm project releases download llvmorg 14 0 6 openmp 14 0 6 src tar xz 2 下载ios toolch
  • 我的2013-从GIS学生到GIS职业人的飞跃

    我的 2013 从 GIS 学生GIS 职业人的飞跃 前言 xff1a 从末日中度过了 2012 年 xff0c 我们伟大的人类把这个世界末日的谎言给揭穿了 xff0c 但是不知不觉中 xff0c 2013 年又即将悄悄从我们身边溜走 xf
  • 矩阵的特征值和特征向量的雅克比算法C/C++实现

    矩阵的特征值和特征向量是线性代数以及矩阵论中非常重要的一个概念 在遥感领域也是经常用到 xff0c 比如多光谱以及高光谱图像的主成分分析要求解波段间协方差矩阵或者相关系数矩阵的特征值和特征向量 根据普通线性代数中的概念 xff0c 特征值和
  • windows多线程详解

    在一个牛人的博客上看到了这篇文章 xff0c 所以就转过来了 xff0c 地址是http blog csdn net morewindows article details 7421759 本文将带领你与多线程作第一次亲密接触 xff0c
  • tiff文件读取

    以下是VC下读取TIFF文件的代码 char szFileName 61 34 K 地图 fujian DEM fujian1 tif 34 TIFF tiff 61 TIFFOpen szFileName 34 r 34 打开Tiff文件
  • GIS开发人员需要掌握的知识和技能

    对于GIS行业 xff0c 可能很多人不是很了解 xff0c 对我来说也不是很了解 xff0c 在此呢 xff0c 我就我自己的看法发表一下简单的看法 xff0c 有什么不同的意见可以一起交流 GIS虽说是属于地理科学或者说测绘科学与技术的
  • GIS算法的一点理解

    在GIS这个专业也混了好几年了 xff0c 但是始终没有对GIS算法有过真正的研究 xff0c 可以说大部分不懂 目前关于GIS算法的书籍不是特别多 xff0c 数来数去也就那么几本 xff0c 南师大几个老师编写的地理信息系统算法基础 x
  • char*转LPCWSTR解决方案

    在Windows编程中 xff0c 经常会碰到字符串之间的转换 xff0c char 转LPCWSTR也是其中一个比较常见的转换 下面就列出几种比较常用的转换方法 1 通过MultiByteToWideChar函数转换 MultiByteT
  • 一阶互补滤波,二阶互补滤波,卡尔曼滤波

    一阶互补 a 61 tau tau 43 loop time newAngle 61 angle measured with atan2 using the accelerometer 加速度传感器输出值 newRate 61 angle
  • 项目实用makefile

    在上一篇文章 小项目实用makefile 中 xff0c 已经说明了单个makefile管理层次目录的局限性 本文 xff0c 主要总结一下项目中的一种实用makefile树写法 xff0c 为10来个人协作的中小型项目makefile编写