BMAKE/GNUMake如何将变量定义延迟到依赖目标执行完成后?
问题核心原因
bmake的执行分为两个阶段:第一阶段是解析阶段,所有全局作用域的变量赋值、.for循环、!= shell展开逻辑都会在这个阶段完成;第二阶段才是目标执行阶段,按照依赖顺序执行各目标的recipe。你原来的变量查找逻辑写在全局作用域,会在prepareOther执行前就运行,自然找不到还未生成的文件。
你之前尝试的.if target(prepareNames)语法只判断该目标是否被显式指定为命令行参数,不会识别构建链路中隐含的目标调用,因此无法触发逻辑;同一目标重复定义recipe会触发duplicate script警告,属于make的标准语法限制。
解决方案1:利用包含文件自动重建特性(推荐,无额外逻辑改动)
该方案利用bmake的原生特性:如果Makefile中.include的文件存在对应的构建规则,bmake会先执行该文件的构建规则,再完成文件包含和内容解析,保证变量赋值时依赖文件已经生成。
- 把你原有的变量查找赋值逻辑单独保存为
project_vars.mk:
# project_vars.mk 内容,和你原有逻辑完全一致,无需修改 PROJECTS=proj1 proj2 RAWNAMES=fileA.cpp fileB.cpp .for proj in ${PROJECTS} . for file in ${RAWNAMES} THISFILENAME!= find ../${proj}/build/${proj} -maxdepth 1 -name '${proj}_${file}' -exec sh -c 'name="{}"; base=$$(basename $$name); echo "${proj}/$$base"' \; CPP_NAME_${proj}::+=${THISFILENAME} . endfor .endfor .for proj in ${PROJECTS} CPP_SRCS+=${CPP_NAME_${proj}} # 同步填充CPP_FLAGS的-I参数 CPP_FLAGS+=-I../${proj}/include .endfor
- 调整主Makefile结构:
# 主Makefile开头先声明包含变量文件 .include "project_vars.mk" # 给变量文件加依赖:必须先完成其他项目构建,再解析变量文件 project_vars.mk: prepareOther # 仅更新文件修改时间,触发bmake重新解析文件内容 @touch $@ prepareOther: cd otherProject && make prepareNames: # 无需额外逻辑,变量已在包含project_vars.mk时完成赋值 build: prepareNames ${CXX} ${CPP_FLAGS} ${CPP_SRCS} -o $@
解决方案2:递归调用bmake(无额外文件依赖)
该方案把构建拆成两个阶段:第一阶段先完成其他项目构建,第二阶段重新调用bmake执行实际构建,此时依赖文件已经存在,变量赋值逻辑可以正常运行。
# 第一阶段入口:先构建依赖项目 all: prepareOther # 递归调用bmake执行实际构建 @bmake real_build prepareOther: cd otherProject && make # 以下为你原有变量赋值逻辑,递归调用时才会正常执行 PROJECTS=proj1 proj2 RAWNAMES=fileA.cpp fileB.cpp .for proj in ${PROJECTS} . for file in ${RAWNAMES} THISFILENAME!= find ../${proj}/build/${proj} -maxdepth 1 -name '${proj}_${file}' -exec sh -c 'name="{}"; base=$$(basename $$name); echo "${proj}/$$base"' \; CPP_NAME_${proj}::+=${THISFILENAME} . endfor .endfor .for proj in ${PROJECTS} CPP_SRCS+=${CPP_NAME_${proj}} CPP_FLAGS+=-I../${proj}/include .endfor # 实际构建目标 real_build: ${CXX} ${CPP_FLAGS} ${CPP_SRCS} -o build
两种方案均为bmake原生语法实现,无需在recipe中写复杂的shell转义代码。
内容的提问来源于stack exchange,提问作者gone
相关产品推荐
相关产品推荐

