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" ...
随机推荐
- java 小算法
//鸡兔同笼 20个头 58腿 for(int a=0;a<=20;a++) { int b = 20-a; if((2*b+4*a)==58) { System.out.println(a+& ...
- js正则常用方法
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>W3 ...
- 制作python程序windows安装包(飞机大战源码)
本文以飞机大战源码为例: 1.首先使用pyinstaller -w xxx.py打包 -w的意思是不显示命令行:飞机大战源码由多个.py文件以及一些图片,音乐文件组成,我们将main.py打包, ...
- [源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统
[源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统 目录 [源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统 0x00 摘要 0x01 分割小批次 ...
- Python3入门系列之-----内置的文件操作模块OS
前言 在自动化测试中,经常需要查找操作文件,比如说查找配置文件(从而读取配置文件的信息),查找测试报告(从而发送测试报告邮件),经常要对大量文件和大量路径进行操作,这个时候就需要用到os模块. 使用前 ...
- python OSError: [Errno 22] Invalid argument: '\u202aF://text
windows10 python3 读文件的时候报的错误 原因不明时好时坏很头疼但又没办法不知道怎么解决,网上的说法都不能解决,
- 使用VisualStudioCode开发Vue
前言 本文主要介绍在VisualStudioCode下开发Vue. Nodejs.Npm.Vue的项目搭建参考下面文章. 用后台开发的逻辑理念学习VUE 在Windows下学习Nodejs.Npm和V ...
- 2021.1.23--vj补题
B - B CodeForces - 879B n people are standing in a line to play table tennis. At first, the first tw ...
- Java 创建PDF打印小册子
概述 PDF打印小册子是指将PDF格式文档在打印成刊物前需要提前进行的页面排版,以便在打印后装订成册.下面以Java代码展示如何来实现.这里调用Free Spire.PDF for Java中的Pdf ...
- AOP的简单介绍
1.AOP简介 AOP面向切面编程,采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.安全检查.缓存) SpringAOP使用纯java实现,不需要专门的编译过程和类加载器,在运行期间以代 ...