8

通常のディレクトリ作成を行うメイクファイルがあります。

$(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関数が最後のディレクトリを希望どおりに削除するのを防ぎます。

「-p」機能を複製するスクリプトまたは小さな C アプリを作成する以外に、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

mkdirs のフォレストを次のように置き換えることができます。

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

これにより、次のようなシェル コマンドが作成されます。

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)

于 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 に答える