如何在多子模块Makefile项目中处理目录路径问题?
Makefile跨目录路径引用问题解决方案
问题根源
当子模块Makefile(如sub_dir2/sub_dir21/Makefile)包含通用build_makefile1.mk时,Make的工作目录是当前子目录,导致build_makefile1.mk中写的相对路径../common/other_dir/other_file1会被解析为相对于子目录的路径,而非build_helpers目录的路径,最终出现路径错误。
推荐解决方案:让通用Makefile自定位目录
只需修改common/build_helpers/build_makefile1.mk,让它自动获取自身所在的绝对目录,再基于该目录引用其他文件,无需修改任何子模块的Makefile:
# 获取当前Makefile的绝对路径,提取所在目录 BUILD_HELPERS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) # 基于build_helpers目录向上一级(common目录)引用other_file1 include $(BUILD_HELPERS_DIR)/../other_dir/other_file1
原理说明
$(lastword $(MAKEFILE_LIST)):获取当前正在处理的Makefile的完整路径(无论被哪个子目录包含)$(dir ...):提取路径中的目录部分$(abspath ...):将相对路径转换为绝对路径,彻底避免工作目录带来的路径歧义
备选方案:基于项目根目录的绝对路径
如果需要统一管理所有路径,可以在每个子模块的Makefile中先定义项目根目录,再引用通用Makefile:
- 修改子模块Makefile(如
sub_dir2/sub_dir21/Makefile):
# 定义项目根目录(从当前目录向上两级到proj_dir) PROJ_ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/../../) # 基于根目录引用通用Makefile include $(PROJ_ROOT)/common/build_helpers/build_makefile1.mk
- 修改
build_makefile1.mk:
# 基于项目根目录引用other_file1 include $(PROJ_ROOT)/common/other_dir/other_file1
该方案适合需要统一配置项目路径的场景,但需要逐个修改子模块的Makefile。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

