2011-09-12 7 views
18

W moim Makefile, muszę sprawdzić, czy bieżący katalog jest repozytorium SVN, czy nie, a jeśli nie, chcę wskazać błąd za pomocą dyrektywy $ (błąd) w Makefile .Jak sprawdzić zwracaną wartość z dyrektywy powłoki

Tak więc planuję użyć zwracanej wartości $ (shell svn info.), Ale nie jestem pewien jak uzyskać tę wartość z pliku Makefile.

Uwaga: Nie próbuję uzyskać wartości zwracanej w recepturze, ale raczej w środku pliku Makefile.

Teraz robię coś takiego, który działa tylko dlatego, stdout jest puste, gdy jest błąd:

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

Chciałbym jeszcze się dowiedzieć, czy jest możliwe, aby uzyskać zwrot wartość zamiast w pliku Makefile.

+3

dziwne, nigdy nie był w stanie uzyskać GNU make-tych [ '.SHELLSTATUS' variable] (https://www.gnu.org/software/make/manual/html_node/Shell-Function.html), aby działał zgodnie z oczekiwaniami. Zawsze było puste. Musiałem użyć poniższych metod. – jww

Odpowiedz

11

To działało w porządku dla mnie - na podstawie @eriktous' odpowiedź z niewielką modyfikacją przekierowanie stdout również pominąć wyjście z informacją o poprawnym svn repo SVN.

+2

Myślę, że @eriktous prawdopodobnie powinien był otrzymać kredyt za odpowiedź. – jww

4

Może coś takiego?

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

Dzięki Roland - mam ogólny pomysł na moje ostateczne rozwiązanie od twoich i eriktous :) – Tuxdude

22

Co powiecie na użycie numeru $? w celu wyświetlenia kodu wyjścia ostatniego polecenia?

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

Dzięki @eriktous - Fajna sztuczka - nie pomyślałem o tym ... Musiałem zrobić kilka drobnych modyfikacji, żeby zadziałało - I 've zaksięgowałem moją odpowiedź na podstawie twojego wkładu :) – Tuxdude

+1

Czy jest jakiś sposób, aby to zrobić, zachowując wyjście, zamiast kierowania go do "/ dev/null"? Co jeśli chcę zadzwonić $ (błąd $ (SVN_INFO)), ale tylko wtedy, gdy kod powrotu ma wartość "1"? – jeremfg

2

Jeśli chcesz zachować oryginalne wyjście, musisz zrobić kilka lew. Jeśli masz szczęście mieć GNU Make 4.2 (wydany w dniu 2016-05-22) lub później do dyspozycji, możesz użyć zmiennej .SHELLSTATUS w następujący sposób.

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) 

Alternatywnie można użyć pliku tymczasowego lub grać z make na eval przechowywać ciąg i/lub kod wyjścia do zmiennej wykonania. Poniższy przykład robi to, ale z pewnością chciałbym zobaczyć lepszą implementację niż ta kłopotliwie skomplikowana wersja.

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

Kiedy próbuję użyć '$ (. SHELLSTATUS)' w GNUmake w systemie Solaris, jest puste. '$ (info" status: $ (. SHELLSTATUS) ")' nic nie wypisuje. – jww

+0

@jww: czy sprawdziłeś wersję? 4.2 jest stosunkowo nowy (do stabilnych dystrybucji) i może nie rozprzestrzeniać się tam, gdzie masz swoje :) 'make -v' Nie znam innych przyczyn niż twój problem. – stefanct

0

używam kilka uczynić funkcje:

# 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))) 

Można je wówczas nazywano tak:

$(call SHELL_CHECKED,some_command $(call OSHELL_CHECKED,other_command some_arg)) 
Powiązane problemy