如何让Makefile解析外部依赖文件中的变量引用获取源文件依赖?
解决方案
方法1:利用Make的include特性(推荐)
将依赖列表改为Make格式的变量定义文件,让Make自动解析变量:
- 重命名
depsfromfile.list为deps.mk,内容修改为:
SOURCE_FILES += $(ROOT1)/a SOURCE_FILES += $(ROOT2)/b SOURCE_FILES += $(ROOT3)/c
- 修改Makefile:
ROOT1=$(shell realpath ./src1) ROOT2=$(shell realpath ./src2) ROOT3=$(shell realpath ./src3) # 引入依赖定义文件 include deps.mk .PHONY: compile compile: .xsim.timestamp @echo $(SOURCE_FILES) @echo "simulating..." .xsim.timestamp: $(SOURCE_FILES) @echo "compiling source files" @touch .xsim.timestamp .PHONY: clean clean: @rm -rf .*.timestamp
这种方式下,Make读取时会直接解析$(ROOT1)等变量,生成正确路径,同时能正常检测源文件的变更。
方法2:用Make的file+eval解析变量
如果必须保留.list格式,可通过Make函数手动解析变量:
修改Makefile中SOURCE_FILES的定义:
ROOT1=$(shell realpath ./src1) ROOT2=$(shell realpath ./src2) ROOT3=$(shell realpath ./src3) # 读取文件内容并强制Make解析其中的变量引用 SOURCE_FILES := $(eval TMP := $(file < depsfromfile.list))$(TMP) .PHONY: compile compile: .xsim.timestamp @echo $(SOURCE_FILES) @echo "simulating..." .xsim.timestamp: $(SOURCE_FILES) @echo "compiling source files" @touch .xsim.timestamp .PHONY: clean clean: @rm -rf .*.timestamp
$(file < depsfromfile.list)读取文件内容,eval指令让Make解析其中的变量,最终得到正确的文件路径,依赖检测功能正常。
方法3:用shell命令替换变量
通过sed命令手动替换文件中的变量占位符:
ROOT1=$(shell realpath ./src1) ROOT2=$(shell realpath ./src2) ROOT3=$(shell realpath ./src3) # 用sed替换文件中的变量占位符为实际路径 SOURCE_FILES = $(shell sed -e 's/$$(ROOT1)/$(ROOT1)/g' -e 's/$$(ROOT2)/$(ROOT2)/g' -e 's/$$(ROOT3)/$(ROOT3)/g' depsfromfile.list) .PHONY: compile compile: .xsim.timestamp @echo $(SOURCE_FILES) @echo "simulating..." .xsim.timestamp: $(SOURCE_FILES) @echo "compiling source files" @touch .xsim.timestamp .PHONY: clean clean: @rm -rf .*.timestamp
注意要将$转义为$$,避免Make提前解析sed命令中的占位符。
原方法失效原因
- 直接用
$(shell cat depsfromfile.list)得到的是纯文本字符串,Make不会自动解析其中的$(ROOT1)变量,会把$(ROOT1)/a当作目标文件名,导致找不到文件。 - 用
$($(SOURCE_FILES))是将每个字符串当作变量名取值,首次执行时变量未定义会展开为空,因此能运行,但依赖列表为空,无法检测源文件变更。
内容的提问来源于stack exchange,提问作者ubaabd
相关产品推荐
相关产品推荐

