我有一个Makefile,它会做通常的目录创建:
$(Release_target_OBJDIR)/%.o: %.cpp
mkdir -p $(dir $@)
$(COMPILE.cpp) $< $(CFLAGS) $(INCLUDES) -o $@
很不幸,当我在scratchbox2下运行时,mkdir -p命令总是悄无声息地失败。
我尝试了以下方法,但没有成功:
$(Release_target_OBJDIR)/%.o: %.cpp
mkdir $(dir $(dir $(dir $@)))
mkdir $(dir $(dir $@))
mkdir $(dir $@)
$(COMPILE.cpp) $< $(CFLAGS) $(INCLUDES) -o $@
这将输出:
mkdir -p /home/foo/projects/htc/arm/obj/cbar/release/
mkdir -p /home/foo/projects/htc/arm/obj/cbar/release/
mkdir -p /home/foo/projects/htc/arm/obj/cbar/release/
...在我想要的方式中,尾随斜杠防止dir函数剥离最后一个目录。
除了编写脚本或小型C应用程序来复制“-p”功能外,是否有任何想法可以在makefile中创建子目录?
如果没有“-p”选项,当makefile尝试创建已经存在的目录时,mkdir将会出现错误。我可以执行mkdir blah 2> /dev/null,但这样会有丢失其他错误消息的风险。
是否有人对为什么mkdir -p在scratchbox2下不起作用有想法?
编辑
根据bobbogo的建议,我整理了这个代码。它看起来相当复杂,但似乎工作正常,甚至在scratchbox2下也是如此。
# Generic variables for use in functions
comma:= ,
empty:=
space:= $(empty) $(empty)
# Make directory function
forlooprange = $(wordlist 1,$(words $1),1 2 3 4 5 6 7 8 9 10)
forloop = $(foreach n,$(call forlooprange,$1),$(call $2,$n,$3))
mkdirfunc0 = test -d $1 || mkdir $1;
mkdirfunc1 = $(call mkdirfunc0,/$(subst $(space),/,$(foreach n,$(wordlist 1,$1,$2),$n)))
mkdirfunc2 = $(call forloop,$1,mkdirfunc1,$1)
mkdirmain = $(call mkdirfunc2,$(subst /, ,$1))
.PRECIOUS: %/.sentinel
%/.sentinel:
$(call mkdirmain,$*)
touch $@
touch
,这样我就不会看起来太蠢了。TVM。 - bobbogo.PRECIOUS
和.SECONDARY
的组合。你也可以将哨兵模式规则转换为静态模式规则(耶!)。 - bobbogomake -j
会发生什么。你可能会同时运行许多mkdir
!糟糕,任何事情都可能发生。使用.sentinel
的方式,mkdir
最多只会运行一次。我说“最多”,因为一旦sentinal被创建,即使第二次运行,_make_也不会再次运行mkdir
。 - bobbogo