Makefile常用模板「建议收藏」

Makefile常用模板「建议收藏」做开发的特别是C/C++开发者一般都会用到Makefile,然而多数时候在公司做项目都不需要自己去写Makefile,仅仅停留在能看懂的基础上。因为make命令编译实在是太方便了,所以自己写写小项目用一用还是挺好的。网上关于Makefile教程也很多,总结一下近几年用到的常用脚本,方便自己查阅,如果能帮到别人那便是极好的^_^。单文件项目其实一个文件的项目也没必要写Makefil…

大家好,又见面了,我是你们的朋友全栈君。

做开发的特别是C/C++开发者一般都会用到Makefile,然而多数时候在公司做项目都不需要自己去写Makefile,仅仅停留在能看懂的基础上。因为make命令编译实在是太方便了,所以自己写写小项目用一用还是挺好的。网上关于Makefile教程也很多,总结一下近几年用到的常用脚本,方便自己查阅,如果能帮到别人那便是极好的_

单文件项目

其实一个文件的项目也没必要写Makefile了,哈哈。便于理解就先从最基础的开始吧,Makefile实际上就是写有gcc等编译链接语句的脚本,加上一些可以缩写这些语句的规则。
假设有hello.c文件。

all: Hello
Hello:
	gcc -o Hello hello.c
clean:
	rm -rf Hello

多文件项目

假设一个工程下,有main.c和有多个.c源文件以及同名的.h头文件,虽然可以类似上述例子一样把每条gcc语句都写出来,但是这么就太啰嗦了。可以使用一些Makefile自带的规则简化着写。

# 方便起见一般都会先定义编译器链接器
CC = gcc 
LD = gcc

# 正则表达式表示目录下所有.c文件,相当于:SRCS = main.c a.c b.c
SRCS = $(wildcard *.c)

# OBJS表示SRCS中把列表中的.c全部替换为.o,相当于:OBJS = main.o a.o b.o
OBJS = $(patsubst %c, %o, $(SRCS))

# 可执行文件的名字
TARGET = Hello

# .PHONE伪目标,具体含义百度一下一大堆介绍
.PHONY:all clean

# 要生成的目标文件
all: $(TARGET)

# 第一行依赖关系:冒号后面为依赖的文件,相当于Hello: main.o a.o b.o
# 第二行规则:$@表示目标文件,$^表示所有依赖文件,$<表示第一个依赖文件
$(TARGET): $(OBJS)
	$(LD) -o $@ $^

# 上一句目标文件依赖一大堆.o文件,这句表示所有.o都由相应名字的.c文件自动生成
%.o:%.c
	$(CC) -c $^

# make clean删除所有.o和目标文件
clean:
	rm -f $(OBJS) $(TARGET)

多个文件,多个程序

这个用的比较少,网上的资料更少,当年我费了老大劲最终才找到这个方法。因为当时在一个目录下写了好多小程序,就是这个项目,可以点进去看一下。要把a.c/b.c/d.c都要编译成可执行文件a/b/c。

C_SRC = $(wildcard *.c)
C_OBJ = $(patsubst %c, %o, $(C_SRC))
# 目标文件也是多个
TARGETLIST = $(patsubst %.c, %, $(C_SRC))

.PHONY:all clean
# 这句不写规则的语句可以自动把相应的a.c b.c编译成a b,神奇~
all:${TARGETLIST}

clean:  
	rm -f ${TARGETLIST} *.o 

指定头文件目录,库文件及目录

这个工程为例,工程需要用到libs目录下的libtomcrypt.a静态库和include目录下libtom的头文件。

CC = cc
LD = cc
SRCS = $(wildcard *.cpp)
OBJS = $(patsubst %cpp, %o, $(SRCS))
# -I指定头文件目录
INCLUDE = -I./include
# -L指定库文件目录,-l指定静态库名字(去掉文件名中的lib前缀和.a后缀)
LIB = -L./libs -ltomcrypt
# 开启编译warning和设置优化等级
CFLAGS = -Wall -O2

TARGET = LibtomDemo

.PHONY:all clean

all: $(TARGET)
# 链接时候指定库文件目录及库文件名
$(TARGET): $(OBJS)
	$(LD) -o $@ $^ $(LIB)
 
# 编译时候指定头文件目录
%.o:%.cpp
	$(CC) -c $^ $(INCLUDE) $(CFLAGS) 

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

遍历执行子目录下的Makefile

有这么个应用场景,当前目录下有多个子目录,且每个子目录下都有独立的Makefile文件,相当于目录下有多个独立的工程,现在需要执行make把各个子目录下的工程全部编译。

.PHONY:all clean
# 排除目录
exclude_dirs := .git
# 显示深度为1的子目录
dirs := $(shell find . -type d -maxdepth 1)
# 去掉获取到目录名称前面的./
dirs := $(basename $(patsubst ./%, %, $(dirs)))
# 过滤指定目录
dirs := $(filter-out $(exclude_dirs), $(dirs))

all:
    $(foreach N,$(dirs),make -C $(N);)
clean:
    $(foreach N,$(dirs),make -C $(N) clean;)

注意事项

  1. 规则语句前面是制表符TAB,写成空格会出错!
  2. 赋值符号:=基本赋值,:=覆盖之前的指,?=如果没有值则赋值,+=继续添加后面的值。

暂时没了,想到时候再补充,有任何问题欢迎留言讨论。

大型项目手写Makefile有点繁琐,建议使用cmake,可以参考 cmake CMakeLists.txt 常用模板

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138517.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 网页返回顶部的几种方法

    网页返回顶部的几种方法

  • pytorch版本对应关系

    pytorch版本对应关系https://blog.csdn.net/baidu_20163013/article/details/105470332

  • keil5 debug调试_java怎么远程调试

    keil5 debug调试_java怎么远程调试文章目录前言一、进入调试二、介绍调试工具栏二、搜索寻找三、特殊的窗口1.命令输出窗口2.寄存器窗口3.汇编语言窗口4.变量查看窗口5.检测自己想要看的总结前言其实我经常用的调试方法是在指定行加Printf();通过串口查看打印的信息,就知道执行到哪一步。但是这是很麻烦的。程序由上而下的执行顺序不会变的。debug调试也是从主函数开始这样调试的。一步一步的运行调试程序检查错误,或者直接运行到某处,二话不多说,开整!一、进入调试二、介绍调试工具栏1.复位按钮:(类似于用复位按键..

    2022年10月15日
  • 2.5D RGBD 图像 深度学习

    2.5D RGBD 图像 深度学习RGBD=RGB+DepthMapRGB:RGB色彩模式是工业界的一种颜色标准,是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。DepthMap:在3D计算机图形中,DepthMap(深度图)是包含与视点的场景对象的表面的距离有关的信息的图像或图像通道。其中,DepthMap类似于灰度图像,只是它的每个像素值是传感器

  • SecureCRT 详细使用教程和技巧

    SecureCRT 详细使用教程和技巧

  • 通过C# 代码实现webservice 的调用

    通过C# 代码实现webservice 的调用

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号