2012-01-25 17 views
7

Estoy tratando de escribir una función make para tocar/crear un archivo vacío y/o configurar los permisos, usuario y grupo, donde sea posible, o advierta si no. Sin embargo, cada comprobación condicional dentro de mi función parece evaluar a verdadera.

Lo esencial de mi Makefile son

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 

Correr make test salidas

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) 

he considerado/probado los siguientes:

  • $ (si ...) se evaluado en "tiempo de compilación", antes de llamar a la función con un parámetro. Sin embargo, el código ifeq "foo" "bar" codificado también da un resultado inválido. Además, $(info ...) evalúa correctamente $(fileName) en "tiempo de compilación".
  • El documentation en realidad no da ejemplos, por lo que además de $(if ifeq...), también intenté $(ifeq ...), que parecía ser ignorado.
  • "No funcional" if (es decir, el ifeq sin el $(if...)) dentro de una función da /bin/sh: ifeq: command not found.

¿Alguien puede ayudar a identificar por qué mis condicionales no se comportan como esperaba (o por qué estoy esperando algo equivocado)?

Advertencia: Sé que todavía hay errores por resolver si el archivo no existe, pero eso debería ser trivial en comparación con este obstáculo.

+1

El sitio web de GNU, aunque se ve bien, es tan breve que casi no tiene sentido, ¿verdad? Ellos le dirán que existe una función, y luego no le darán ningún ejemplo sobre cómo usarla, para hostigarlo con ella. – Xennex81

Respuesta

31

$(if ...) conditional function evalúa a true cuando el primer argumento que se le pasa es que no esté vacía. En su caso, la condición es texto literal: ifeq "foo" "bar", que obviamente no está vacío.

ifeq/ifneq conditionals son de hecho directivas, no funciones. No se pueden usar dentro de la definición de variable y en funciones.

Volver a su ejemplo, a cadena de prueba por la igualdad dentro de las funciones de uso perfectas condiciones 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) 

Por cierto que esto podría ser también se convirtió en una forma en línea para una mejor legibilidad:

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

gran explicación – anoop

+0

@anoop ¡gracias! –

1

Parece que estás malinterpretando el funcionamiento de $(if. De los INFORMACIÓN Hacer docs:

$ (si condición, entonces-PART [, parte else]) ' El `si' función proporciona apoyo a la expansión condicional en un contexto funcional

La primera argumento, CONDITION, primero tiene todos los anteriores y espacios en blanco al final eliminados, luego se expande. Si se expande a cualquier cadena no vacía, entonces la condición se considera verdadera. Si se expande a una cadena vacía, la condición se considera sea falsa.

En todos los ejemplos, su condición es algo así como ifeq SOMETHING OTHERTHING - que es una cadena no vacía (del ifeq independientemente de lo que las otras cosas son), y por lo tanto se trata como verdadera.

4

Me enfrenté a este problema y encontré que puede usar el resultado de la función "filtro" en la parte "condición" de la función "si". Este es un ejemplo útil para abrir un pdf ya sea en Linux (con "evince"), o en OSX con "abrir")

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

¡Gracias! Quería un ejemplo más simple para mi propia herramienta de creación. – yoshi

0

si desea comprobar que su versión del sistema operativo es Linux u otro y si Linux es entonces que desea imprimir algún mensaje entonces u puede seguir los siguientes pasos:

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

antes de que intentara con ifeq pero se ha impreso la parte persona solamente. mi sistema operativo es Linux, ubuntu.

Si alguien encuentra esta respuesta debe ser modificada, para que puedan dar una mejor respuesta para esto también.

Cuestiones relacionadas