2011-09-12 10 views
18

私のMakefileでは、現在のディレクトリがSVNリポジトリかどうかをテストする必要があります。もしそうでなければ、Makefileの$(error)ディレクティブを使ってエラーを表示したい。シェルディレクティブから戻り値を確認する方法

私は$(shell svn info。)の戻り値を使用する予定ですが、Makefile内からこの値を取得する方法がわかりません。

注:私はレシピで戻り値を取得しようとしているのではなく、Makefileの途中にあります。リターンを得ることが可能であるならば、私はまだ知りたいのですが

SVN_INFO := $(shell svn info . 2> /dev/null) 
ifeq ($(SVN_INFO),) 
    $(error "Not an SVN repo...") 
endif 

:それは誤りであるとき

右は今、私はstdoutが空白であるという理由だけで動作します。このようなことを、やっています値をMakefileの代わりに使用します。

+3

は奇妙なことに、私はGNU makeの[ '.SHELLSTATUS'を得ることができませんでした変数](https://www.gnu.org/software/make/manual/html_node/Shell-Function.html)を期待どおりに動作させることができます。それは常に空だった。私は以下の方法を使用しなければならなかった。 – jww

答えて

11

これは私のためにうまく働いた - 有効なのsvnレポのSVN情報からの出力をスキップするだけでなく標準出力をリダイレクトするの軽微な変更を加えた@eriktous'回答に基づいて。

+2

@eriktousはおそらく答えのクレジットを受け取ったはずだと思います。 – jww

4

多分このような何か?

IS_SVN_CHECKED_OUT := $(shell svn info . 1>/dev/null 2>&1 && echo "yes" || echo "no") 
ifne ($(IS_SVN_CHECKED_OUT),yes) 
    $(error "The current directory must be checked out from SVN.") 
endif 
+0

ありがとうRoland - 私はあなたとエリクツの両方から私の最終的な解決策の一般的なアイデアを得ました:) – Tuxdude

22

$?を使用して最後のコマンドの終了ステータスをエコーするのはどうですか?

 
SVN_INFO := $(shell svn info . 2> /dev/null; echo $$?) 
ifeq ($(SVN_INFO),1) 
    $(error "Not an SVN repo...") 
endif 
+0

ありがとう@eriktous - クールなトリック - それを考えることはできませんでした。あなたの入力に基づいて私の答えを掲載しました:) – Tuxdude

+1

これを行う方法はありますか?出力を '/ dev/null'にするのではなく、そのままにしておきますか? $(エラー$(SVN_INFO))を呼び出すとしたら、リターンコードが "1"の場合のみですか? – jeremfg

2

元の出力を保持したい場合は、いくつかのトリックを行う必要があります。あなたが自由に使えるGNU Make 4.2(2016-05-22にリリースされたもの)を持つことができるほど幸運な場合は、.SHELLSTATUS変数を次のように使用できます。

var := $(shell echo "blabla" ; false) 

ifneq ($(.SHELLSTATUS),0) 
    $(error shell command failed! output was $(var)) 
endif 

all: 
    @echo Never reached but output would have been $(var) 

別の方法としては、一時ファイルを使用するか、メイク変数に文字列および/または終了コードを格納するためのメイクのevalで遊ぶことができます。以下の例ではこれを実現していますが、私は確かにこの恥ずかしく複雑なバージョンよりも優れた実装を見たいと思います。私はカップルを使用

ret := $(shell echo "blabla"; false; echo " $$?") 
rc := $(lastword $(ret)) 
# Remove the last word by calculating <word count - 1> and 
# using it as the second parameter of wordlist. 
string:=$(wordlist 1,$(shell echo $$(($(words $(ret))-1))),$(ret)) 

ifneq ($(rc),0) 
    $(error shell command failed with $(rc)! output was "$(string)") 
endif 

all: 
    @echo Never reached but output would have been \"$(string)\" 
+0

Solaris上でGNUmakeで '$(.SHELLSTATUS)'を使用しようとすると、空です。 '$(info" status:$(。SHELLSTATUS) ")'は何も印刷しません。 – jww

+0

@jww:バージョンを確認しましたか? 4。2は比較的新しい(安定したディストリビューションへの)新しいもので、どこにいても伝播していない可能性があります:) 'make -v'私はあなたの問題のために他の理由を知らない。 – stefanct

0

機能します

# This function works almost exactly like the builtin shell command, except it 
# stops everything with an error if the shell command given as its argument 
# returns non-zero when executed. The other difference is that the output 
# is passed through the strip make function (the shell function strips only 
# the last trailing newline). In practice this doesn't matter much since 
# the output is usually collapsed by the surroundeing make context to the 
# same result produced by strip. WARNING: don't try to nest calls to this 
# function, take a look at OSHELL_CHECKED instead. 
SHELL_CHECKED =              \ 
    $(strip               \ 
    $(if $(shell (($1) 1>/tmp/SC_so) || echo nonempty),    \ 
     $(error shell command '$1' failed. Its stderr should be above \ 
       somewhere. Its stdout is in '/tmp/SC_so'),   \ 
     $(shell cat /tmp/SC_so))) 

# "Other" SHELL_CHECKED. Like SHELL_CHECKED, but uses different file names 
# and so may be used with arguments that themselves use SHELL_CHECKED 
# or vice versa. In other words, a hack to allow two-level nesting of 
# checked shell calls by hardwiring the call points involved to not both 
# use SHELL_CHECKED or OSHELL_CHECKED. 
OSHELL_CHECKED =              \ 
    $(strip               \ 
    $(if $(shell (($1) 1>/tmp/OSC_so) || echo nonempty),    \ 
     $(error shell command '$1' failed. Its stderr should be above \ 
       somewhere. Its stdout is in '/tmp/OSC_so'),   \ 
     $(shell cat /tmp/OSC_so))) 

はこれらのそのようにのように呼び出すことができます。

$(call SHELL_CHECKED,some_command $(call OSHELL_CHECKED,other_command some_arg)) 
関連する問題