8

我有一个makefile,它可以创建通常的目录:

$(Release_target_OBJDIR)/%.o: %.cpp
     mkdir -p $(dir $@)
     $(COMPILE.cpp) $< $(CFLAGS) $(INCLUDES) -o $@

不幸的是,当我在scratchbox2 下运行它时,mkdir -p 命令总是默默地失败。

我尝试了以下不起作用的kludge:

$(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 $@
4

2 回答 2

4

你可以用这个替换你的森林mkdir

$(Release_target_OBJDIR)/%.o: %.cpp
    $(foreach d,$(subst /, ,${@D}),mkdir $d && cd $d && ):
    ∶

这将创建一个 shell 命令,如下所示:

mkdir projects && cd projects && mkdir htc && cd htc && mkdir arm && cd arm && :

这适用于每次编译。不是很优雅。您可以通过使用某种哨兵文件来优化它。例如:

$(Release_target_OBJDIR)/%.o: %.cpp ${Release_target_OBJDIR}/.sentinel
    ∶

%/.sentinel:
    $(foreach d,$(subst /, ,$*),mkdir $d && cd $d && ):
    touch $@

.sentinel在所有对象之前创建一次,并且是make -j友好的。实际上,即使mkdir -p对您有用,您也应该这样做(在这种情况下,您将使用mkdir -p而不是$(foreach) hack解决方案)。

于 2011-03-04T12:53:28.127 回答
2

您可以使用以下make命令忽略来自命令的任何失败返回代码-

$(Release_target_OBJDIR)/%.o: %.cpp
    -mkdir $(dir $(dir $(dir $@)))
    -mkdir $(dir $(dir $@))
    -mkdir $(dir $@)
    $(COMPILE.cpp) $< $(CFLAGS) $(INCLUDES) -o $@

(请注意,这并不能解决尾部斜杠问题。)

于 2011-03-04T12:02:32.240 回答