2012-01-25 8 views
7

Sto provando a scrivere una funzione di creazione per toccare/creare un file vuoto e/o impostare permessi, utente e gruppo, dove possibile, o avvisare se non. Tuttavia, ogni controllo condizionale all'interno della mia funzione sembra essere vero.

Gli elementi essenziali della mia Makefile sono

INSTALL_USER := fileUser 
INSTALL_GROUP := fileGroup 

.PHONY: test 
test: 
    $(call touchFile,~/test.ini) 

define touchFile 
$(eval fileName := $(strip $(1))) 
-touch $(fileName) 
-chmod -c 664 $(fileName) 

$(info filename info $(fileName)) 
$(info $(shell stat -c "%a %U:%G" $(fileName))) 

$(if ifeq "foo" "bar", @echo match is broken, @echo match works) 
$(if ifneq "foo" "bar", @echo match works, @echo match is broken) 

$(if ifneq ($(shell stat -c %a $(fileName)),664), $(warning Error - $(fileName) does not have expected permissions of 664)) 
-chgrp -c $(INSTALL_GROUP) $(fileName) 
$(if ifneq ($(shell stat -c %G $(fileName)),$(INSTALL_GROUP)), $(warning Error - $(fileName) does not belong to $(INSTALL_GROUP) group)) 
-chown -c $(INSTALL_USER) $(fileName) 
$(if ifneq ($(shell stat -c %U $(fileName)),$(INSTALL_USER)), $(warning Error - $(fileName) does not belong to $(INSTALL_USER) user)) 
endef 

Esecuzione make test uscite

filename info ~/test.ini 
664 myUserName:myGroup 
Makefile:7: Error - ~/test.ini does not have expected permissions of 664 
Makefile:7: Error - ~/test.ini does not belong to common group 
Makefile:7: Error - ~/test.ini does not belong to netserve user 
touch ~/test.ini 
chmod -c 664 ~/test.ini 
match is broken 
match works 
chgrp -c fileGroup ~/test.ini 
changed group of `/home/myUserName/test.ini' to fileGroup 
chown -c fileUser ~/test.ini 
chown: changing ownership of `/home/myUserName/test.ini': Operation not permitted 
make: [test] Error 1 (ignored) 

Ho considerato/provato i seguenti:

  • $ (se ...) è valutato a "tempo di compilazione", prima che la funzione venga chiamata con un parametro. Ma il codice codificato ifeq "foo" "bar" fornisce anche un risultato non valido. Inoltre, $(info ...) valuta correttamente $(fileName) in "fase di compilazione".
  • Il documentation non fornisce effettivamente esempi, quindi oltre a $(if ifeq...), ho anche provato $(ifeq ...), che sembrava essere ignorato.
  • "Non funzionale" if (vale a dire, il ifeq senza il $(if...)) all'interno di una funzione dà /bin/sh: ifeq: command not found.

Qualcuno può aiutare a capire perché i miei condizionali non si comportano come mi aspetto (o perché mi aspetto la cosa sbagliata)?

Avvertenza: So che ci sono ancora bug da risolvere se il file non esiste, ma dovrebbe essere banale rispetto a questo ostacolo.

+1

Il sito Web GNU, sebbene sia bello, è così succinto da essere quasi inutile, non è così. Vi diranno che esiste una funzione, e quindi non vi fornirà alcun esempio su come usarlo, in modo da molestarvi con esso. – Xennex81

risposta

31

$(if ...) conditional function viene valutato come true quando il primo argomento passato ad esso non è vuoto. Nel tuo caso la condizione è letterale: ifeq "foo" "bar", che è, ovviamente, non vuoto.

ifeq/ifneq conditionals sono in realtà direttive, non funzioni. Non possono essere utilizzati all'interno della definizione di variabili e nelle funzioni.

Torna al tuo esempio, per stringa di prova per l'uguaglianza all'interno delle funzioni d'uso condizione come filter and findstring:

$(if $(filter foo,bar),@echo match is broken,@echo match works) 
$(if $(filter-out foo,bar),@echo match works,@echo match is broken) 

BTW questo potrebbe essere trasformato anche in una forma in linea per una migliore leggibilità:

@echo match $(if $(filter foo,bar),is broken,works) 
@echo match $(if $(filter-out foo,bar),works,is broken) 
+0

grande spiegazione – anoop

+0

@anoop grazie! –

1

Sembra che tu stia fraintendendo il modo in cui funziona $(if. Dalle make documenti info:

$ (se condizione, allora-PART [, ELSE-PART]) ' Il `se' la funzione fornisce il supporto per l'espansione condizionale in un contesto funzionale

La prima argomento, CONDITION, prima ha tutti i precedenti e spazio vuoto trascinato, quindi viene espanso. Se si espande a qualsiasi stringa non vuota, la condizione viene considerata vera. Se si espande su una stringa vuota, la condizione viene considerata come essere falsa.

In tutti i vostri esempi, la sua condizione è qualcosa di simile a ifeq SOMETHING OTHERTHING - che è una stringa non vuota (dal ifeq indipendentemente da ciò che le altre cose sono), e così viene considerato come vero.

4

Ho affrontato questo problema e ho scoperto che è possibile utilizzare il risultato della funzione "filtro" nella parte "condizione" della funzione "se". Ecco un esempio utile per l'apertura di un file PDF sia in Linux (con "Evince"), o in OSX con "aperto")

uname  :=$(shell uname -s) 
is_darwin :=$(filter Darwin,$(uname)) 
viewpdf :=$(if $(is_darwin), open, evince) 
+0

Grazie! Volevo un esempio più semplice per il mio strumento di creazione. – yoshi

0

se si desidera controllare che la versione del sistema operativo è Linux o altro e se si è Linux, allora si desidera stampare qualche messaggio allora la u può seguire questa procedura:

ifneq ($(TARGETOS), Linux) 
    target: server 
    @echo 
    @echo $(MSG) $(TARGETOS) 
else 
target: server 
    @echo $(MSG) $(TARGET) 
endif 

prima ho provato con ifeq ma ha stampata solo la parte altra cosa. il mio sistema operativo è Linux, ubuntu.

Se qualcuno ha trovato questa risposta dovrebbe essere modificata, in modo da poter dare una risposta migliore anche per questo.

Problemi correlati