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 常用模板

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 程序员如何学习量化交易,一文总结

    程序员如何学习量化交易,一文总结最近有位金融行业的朋友想把一个盈利能力很强的策略做成量化程序遇到问题,问题是这样的线程A在while(true)的循环里做条件判断,循环耗时1分钟。循环结束判断条件满足的时候调用交易接口下单建仓。想实现条件成立马上建仓,而不需要等待1分钟的循环。想通过多进程或者多线程方式,但两个线程不知道如何交互。对有经验的开发来说这样的逻辑很简单,只要通过线程通信的方式就可以实现。A线程判断到满足条件就发个消息给B线程,B线程while(true)等待消息就行。技术本身不复杂,只是没接触过编程的不知道还可以这么干

    2022年6月26日
    29
  • Java实现在线预览–openOffice实现[通俗易懂]

    Java实现在线预览–openOffice实现[通俗易懂]Java实现在线预览–openOffice实现

    2022年6月9日
    49
  • java web servlet基础(PS教程)

    JavaWeb——ServletTomcat工作机制动画演示(点击动图可全屏观看)什么是ServletServlet(ServerApplet),全称JavaServlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web…

    2022年4月10日
    29
  • 小白能读懂的 《手把手教你学DSP(TMS320X281X)》第二章(1) 2020-12-21[通俗易懂]

    小白能读懂的 《手把手教你学DSP(TMS320X281X)》第二章(1) 2020-12-21[通俗易懂]1声明由于本人也是小白,只是将所能查询到的资料进行汇总,水平有限,只能代表个人的理解,但所写文章也从小白视角出发,对小白友好,如果帮助到你,记得点赞收藏不迷路。如果文章有错误,请不吝赐教;待我查询后一定改正,这样你我教学相长,岂不美哉,当然有些错误待我多时之后也可能自己发现,到时候自己回来改正,不过有的可能遗忘,所以能提醒我最好,哈哈,谢谢。2概述首先dsp2812是32位的定点dsp。单片机中的32位是指cpu处理的数据的宽度,即参与运算的寄存器的数据长度。…

    2022年5月1日
    35
  • spring源码系列(二)——毁三观的spring自动注入

    spring源码系列(二)——毁三观的spring自动注入比如提到spring的自动注入作为一个java程序员肯定自信无比了解;但是笔者要说的自动注入可能会和你理解有很大出入。首先搞明白什么是自动注入,自动注入也可以叫做自动装配(springboot也有一个自动装配但是我认为翻译的不够准确,springboot的应该叫做自动配置和这里说的自动注入是两回事,笔者不是什么大牛或者权威;所以读者如果你坚持认为springboot也叫自动装配那也无可厚非,只…

    2022年10月31日
    0
  • hdu 3652 B-number(数字dp)

    hdu 3652 B-number(数字dp)

    2022年1月4日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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