makefile编译子目录
make子目录常用方法
一般是
SUB_DIR = lib_src service
.PHONY: subdirs $(SUB_DIR)
subdirs: $(SUB_DIR)
$(SUB_DIR):
@+make -C $@
foo: baz
或者
subdirs:
for dir in $(SUB_DIR); do \
@+make -C $$dir; \
done
使用循环的方式比较直观,但是会有这样的问题
- 当submake报错的时候不会停止,其他submake会继续执行
- 不能体验到make的并行编译 即-j选项
- 子目录之间的依赖不好表示
所以,一般来说会选择第一种来写.但是,当用第一种书写时,怎么表达make子命令(即:make install)呢?
make子命令书写
SUB_DIR_TEST = $(SUB_DIR:%=%_test)
test: $(SUB_DIR_TEST)
$(SUB_DIR_TEST):
@+make -C $(@:%_test=%) test
.PHONY: test subdirs $(SUB_DIR_TEST)
核心就是对子目录名字进行包裹一下,把包裹后的名字当作新的伪目标进行构建
实例
以下是我从工作项目中拷出来的
总共三个级别的目录
- 根目录
- lib_src service
- 实际编译目录:game gate
所以列举了3个makefile
项目目录大致结构
目录做了一些删减
bin输出目录:deploy/bin
├── deploy
│ └── bin
├── deps
│ └── tinyxml
│ ├── include
│ │ └── tinyxml
│ │ └── tinyxml.h
│ └── lib
│ └── libtinyxml.a
├── lib_src
│ ├── auth
│ │ ├── auth.cpp
│ │ └── auth.h
│ ├── common
│ │ ├── common.cpp
│ │ └── common.h
│ └── lib
└── service
├── game
│ └── game.cpp
└── gate
项目根目录下的Makefile
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
SUB_DIR = lib_src service
SUB_DIR_TEST := $(SUB_DIR:%=%_test)
SUB_DIR_CLEAN := $(SUB_DIR:%=%_clean)
all : $(SUB_DIR)
lib_src:
@+make -C $@
service:lib_src
@+make -C $@
clean:$(SUB_DIR_CLEAN)
#$(foreach N, $(SUB_DIR),make clean -C $(N);)
$(SUB_DIR_CLEAN):
@+make clean -C $(@:%_clean=%)
test:$(SUB_DIR_TEST)
@echo $(MKFILE_PATH)
$(SUB_DIR_TEST):
@+make test -C $(@:%_test=%)
.PHONY: all test clean $(SUB_DIR) $(SUB_DIR_TEST) $(SUB_DIR_CLEAN)
lib_src下的Makefile
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
SUB_DIR = auth common
SUB_DIR_CLEAN := $(SUB_DIR:%=%_clean)
SUB_DIR_TEST := $(SUB_DIR:%=%_test)
all : |mk_dir $(SUB_DIR)
$(SUB_DIR): mk_dir
@+make -C $@
mk_dir:
@mkdir -p bin
clean:$(SUB_DIR_CLEAN)
#$(foreach N, $(SUB_DIR),make clean -C $(N);)
$(SUB_DIR_CLEAN):
@+make clean -C $(@:%_clean=%)
test:$(SUB_DIR_TEST)
@echo $(MKFILE_PATH)
$(SUB_DIR_TEST):
@+make test -C $(@:%_test=%)
.PHONY: all test clean mk_dir $(SUB_DIR) $(SUB_DIR_TEST) $(SUB_DIR_CLEAN)
game下的Makefile
编译选项这些忽略吧
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
include ../../global.mk
TARGET := $(BIN_DIR)/game_svr$(BIN_TAG)
CUR_INC_FLAGS := -I$(FRAME_INC) -I./ -I$(MYSQL_INC)
CUR_LINK_FLAGS := $(LDFLAGS) -L$(MYSQL_LIB)
CUR_CPPFLAGS := $(CPPFLAGS) $(CUR_INC_FLAGS)
SUB_DIR := app bll dal db thread config
ALL_OBJS = $(wildcard $(OBJ_DIR)/*.o)
all : |$(OBJ_DIR) $(TARGET)
$(TARGET) : $(TARGET_OBJS) $(SUB_DIR)
$(CXX) -o $@ $(ALL_OBJS) $(CUR_LINK_FLAGS)
@echo "#### compile ok "$(TARGET) "####"
$(OBJ_DIR)/%.o : %.cpp
$(CXX) $(CUR_CPPFLAGS) -c $< -o $@
$(OBJ_DIR):
@mkdir $@
$(SUB_DIR):
@echo "#### compile sub dir start ####" $@
@+make -C $@
@echo "#### compile sub dir end ####" $@
clean:
@rm -f $(wildcard $(OBJ_DIR)/*.o) $(TARGET)
test:
@echo $(MKFILE_PATH)
.PHONY: all test clean
.PHONY: $(SUB_DIR)
简要语法说明
$(SUB_DIR:%=%_test)
表示文件名加后缀,结果为lib_src_test service_test
$(@:%_test=%)
表示去掉后缀,结果为lib_src service
=
在真正执行命令的时候才会对变量求值,所以变量值可能会在中间因为其他引用的其他变量被改变而不是预期的
=:
在赋值的时候直接对变量求值,以后如果不重新赋值是不会变化的
makefile编译子目录的更多相关文章
- live555学习(一)通读Makefile编译live555
live555学习(一)通读Makefile编译live555 live555 编译live555 学习开源 live555学习(一)通读Makefile编译live555 前言 live555简介 ...
- C++---初识《通过g++ / makefile 编译和调用动态库so文件》(ubuntu)
C++---初识<通过g++ / makefile 编译和调用动态库so文件>(ubuntu) ------------------------目录------------------- ...
- gcc与makefile编译 BY 四喜三顺
gcc编译控制过程:(假设源代码为a.c)(1)源文件到预处理文件: gcc -E -o a.cxx a.c a.cxx显示调用哪些头文件(2)生成汇编代码: g ...
- 【Linux学习】 写一个简单的Makefile编译源码获取当前系统时间
打算学习一下Linux,这两天先看了一下gcc的简单用法以及makefile的写法,今天是周末,天气闷热超市,早晨突然发现住处的冰箱可以用了,于是先出去吃了点东西,然后去超市买了一坨冰棍,老冰棍居多, ...
- Linux Makefile 编译速度的优化【转】
转自:https://blog.csdn.net/QQ1452008/article/details/51851801 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...
- makefile 编译指定目录
makefile 编译指定目录 sub1=test1 sub2=test2 subs = sub1 sub2 SUBDIRS =$(foreach i, $(subs), $($(i))) .PHON ...
- CMake 工程调用 Makefile 编译项目
本文主要介绍如何将一个依赖 Makefile 项目(MIDG)移植到 CMake 上. 首先介绍项目文件结构,文件主要由三个目录组成 3rdParty include src 其中,3rdParty ...
- 由于makefile编译所有子目录中 sed 's,/($*/)/.o[ :],/1.o $@ : ,g' <$@ > $@ 的解释
这个语句分为好几层,我们一层一层来看 1. sed 's,/($*/)/.o[ :],/1.o $@ : ,g' <$@ > $@ 首先看加粗这一层,$@表示目标参数中的.d文件, '&l ...
- Makefile编译库
funs.h: #ifndef __FUNS_H__ #define __FUNS_H__ void fun1(); #endif funs.c #include "funs.h" ...
随机推荐
- Abp vNext 番外篇-疑难杂症丨浅谈扩展属性与多用户设计
说明 Abp vNext基础篇的文章还差一个单元测试模块就基本上完成了我争取10.1放假之前给大家赶稿出来,后面我们会开始进阶篇,开始拆一些东西,具体要做的事我会单独开一个文章来讲 缘起 本篇文章缘起 ...
- 牛客练习赛89E-牛牛小数点【数论】
正题 题目链接:https://ac.nowcoder.com/acm/contest/11179/E 题目大意 定义\(f(x)\)表示\(\frac{1}{x}\)的混循环节长度(如果没有循环节就 ...
- es相关监控指标梳理
###################ElasticSearch监控指标梳理########################### #author:lugh1 # #date:2021-09-26 # ...
- 四种引用类型在Springboot中的使用
今天 4ye 来和小伙伴们聊聊这个 强引用,软引用,弱引用,幻象引用(虚引用)啦 嘿嘿,主要是最近读源码的时候经常看到,然后又想到自己第一次知道这个神奇的东西是在 2020-8-21 为啥记得这么清楚 ...
- Spring源码阅读一
引导: 众所周知,阅读spring源码最开始的就是去了解spring bean的生命周期:bean的生命周期是怎么样的呢,见图知意: 大致流程: 首先后通过BeanDefinitionReader读取 ...
- 阿里云函数计算发布新功能,支持容器镜像,加速应用 Serverless 进程
我们先通过一段视频来看看函数计算和容器相结合后,在视频转码场景下的优秀表现.点击观看视频 >> FaaS 的门槛 Serverless 形态的云服务帮助开发者承担了大量复杂的扩缩容.运维. ...
- 关于 Binomial Coefficient is Fun
题目传送门 Solution 应该这个做法不是很常见吧. 我们设 \(f_{i,j}\) 表示前面 \(i\) 个数,选出的数和为 \(j\) 的贡献之和.因为我们有以下式子: \[\sum_{i=a ...
- CF850E Random Elections 题解
题目传送门 题目大意 没法描述,过于繁杂. 思路 果然自己是个菜鸡,只能靠读题解读题,难受极了,其实不是很难自己应该做得出来的....哎.... 不难发现可以统计 \(A\) 获胜的情况乘上 \(3\ ...
- luogu1438无聊的数列(区间加等差数列,求一个数的和)
QAQ一道线段树好题 题目大意: 给定一个有n个数的数列,共m种操作,有两种操作 \(1\ l\ r\ k\ d\)表示将\(a[l]\)~\(a[r]\)的数加一个以k为首相,d为公差 \(2\ x ...
- Spring的JDK动态代理如何实现的(源码解析)
前言 上一篇文章中提到了SpringAOP是如何决断使用哪种动态代理方式的,本文接上文讲解SpringAOP的JDK动态代理是如何实现的.SpringAOP的实现其实也是使用了Proxy和Invoca ...