如何在mkdir中创建makefile中的目录

我有一个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等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 $@

你可以用这个替换你的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) hacksolution)。


您可以使用- :来告诉make忽略来自命令的任何失败返回码。

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

(请注意,这不能解决斜线问题。)


有一种更简单的方法。 你可以像这样在shell函数内调用mkdir:

foobar:
        $(shell mkdir -p mydirectoryname)

gnu中的shell函数使shell执行shell命令后执行命令。

链接地址: http://www.djcxy.com/p/17517.html

上一篇: How to create a directory in a makefile when mkdir

下一篇: KornShell Boolean Conditional Logic