Makefile中在if-endif条件下执行mkdir的问题求助
Makefile问题分析与解决
第一个报错原因
你第一次写的Makefile报错recipe commences before first target,是因为mkdir -p $(OUTPUTDIR)直接写在了ifeq条件块里,没有归属任何目标。Makefile中,执行命令(recipe)必须依附于某个目标规则,不能单独出现在变量定义或条件判断区域。
第二次代码的问题
更新后的代码未成功创建目录,问题出在:
- 你把
target:目标定义放在了ifeq内部,这意味着只有当OUTPUTDIR为空时,这个目标才会存在,但all目标没有依赖它,执行make all时不会触发mkdir命令。 - 变量赋值
OUTPUTDIR := $(CURDIR)/tmp前的缩进是多余的,Makefile变量赋值不需要缩进,仅目标下的命令行需要用tab缩进。
正确写法示例
写法一:用默认值简化逻辑(推荐)
直接用?=给变量设置默认值,同时定义前置目标确保目录存在:
.PHONY: all prepare CP := /bin/cp ## Pass OUTPUTDIR from parent makefile OUTPUTDIR ?= $(CURDIR)/tmp # 确保输出目录存在 prepare: mkdir -p $(OUTPUTDIR) # 主目标依赖prepare,先创建目录再复制文件 all: prepare $(CP) -f test.txt $(OUTPUTDIR)/test.txt
写法二:保留ifeq判断
如果一定要用ifeq判断空值,需确保创建目录的命令被主目标触发:
.PHONY: all CP := /bin/cp ## Pass OUTPUTDIR from parent makefile OUTPUTDIR ?= ifeq ($(OUTPUTDIR),) OUTPUTDIR := $(CURDIR)/tmp endif all: # 先确保目录存在,再执行复制 mkdir -p $(OUTPUTDIR) $(CP) -f test.txt $(OUTPUTDIR)/test.txt
关键建议
- 优先用
VAR ?= DEFAULT的方式设置变量默认值,比ifeq更简洁直观。 - 创建目录这类前置操作,建议单独定义一个
prepare或dirs目标,让主目标(如all)依赖它,确保执行顺序正确。 - 不要把目标规则放在条件判断内部,避免因条件不满足导致依赖关系失效。
内容的提问来源于stack exchange,提问作者user3584600
相关产品推荐
相关产品推荐

