2010-08-13 9 views
7

tengo una regla que crea un directorioreprimir maquillaje salida de error regla

bin: 
    -mkdir [email protected] 

Sin embargo después de la primera vez que el directorio se ha generado, que recibe esta salida:

mkdir bin 
mkdir: cannot create directory `bin': File exists 
make: [bin] Error 1 (ignored) 

¿Hay alguna manera Solo puedo ejecutar la regla si el directorio no existe o suprimir la salida cuando el directorio ya existe.

+0

Casi duplicado: http://stackoverflow.com/questions/3477292/what-do-and-do-as-prefixes-to-recipe-lines-in-make – reinierpost

Respuesta

8

La forma tradicional de manejar la creación del directorio es el uso de un archivo de sello que se dependía y crea el directorio como un efecto secundario. Quitar el archivo de sello de la hora de tomar distclean o lo que su "muy limpia" objetivo:

bin/.dirstamp: 
    mkdir -p $(DIRS) 
    touch [email protected] 

bin/foo: bin/.dirstamp 
    $(MKFOO) -o [email protected] 

distclean: 
    rm -rf bin 

La razón de esto es la siguiente: cada vez que se crea un archivo en bin/eliminado, el mtime del directorio que contiene se actualiza . Si un objetivo depende de bin, la próxima vez que se ejecute make, se volverán a crear los archivos que no es necesario.

+0

¿El dir dep va en todos los archivos generados en esa ubicación? –

+0

Todos los archivos creados en ese directorio necesitarían depender, directa o indirectamente, del archivo de sello para asegurarse de que se creó antes del uso. –

7

El error ya ha sido ignorado por el '-' en la línea de comando. Si realmente quiere perder los mensajes de error de mkdir, yo uso/redirección O:

bin: 
    -mkdir bin 2> /dev/null 

seguirá recibiendo el 'ignorado' advertencia de make, sin embargo, por lo que podría ser mejor usar la opción de mkdir que no causa que falle cuando el destino ya existe, que es la opción -p:

MKDIR_P = mkdir -p 

bin: 
    ${MKDIR_P} [email protected] 

la opción -p realidad crea todos los directorios que faltan en los caminos indicados, por lo que puede generar número de AA directorios en una invocación, pero como ide-effect es que no genera un error para los directorios ya existentes. Esto supone una implementación POSIX-ish de mkdir; las máquinas más antiguas pueden no ser compatibles (aunque ya es estándar desde hace mucho tiempo).

+0

¿por qué tal redireccionamiento '2> & 1' ayuda? Yo entendería '2>/dev/null' para enviar stderr al olvido pero enviándolo a stdout .....? – humanityANDpeace

+0

@humanityANDpeace: Tienes razón, un pensador en el 2010. Lo arreglé. Gracias. –

0

Su regla no debe ejecutarse a menos que su destino no exista o esté desactualizado debido a sus dependencias. En otras palabras, nunca deberías encontrar este error.

[Ejemplo Agregado]

[[email protected] tmp]$ ls -la 
total 20 
drwxr-xr-x. 2 max users 4096 Aug 14 21:11 . 
drwx------. 80 max max 4096 Aug 14 18:25 .. 
-rw-rw-r-- 1 max max  38 Aug 14 21:11 Makefile 
[[email protected] tmp]$ cat Makefile 
.PHONY: all 
all: bin 

bin: 
    mkdir [email protected] 

[[email protected] tmp]$ make 
mkdir bin 
[[email protected] tmp]$ ls -la 
total 24 
drwxr-xr-x. 3 max users 4096 Aug 14 21:11 . 
drwx------. 80 max max 4096 Aug 14 18:25 .. 
drwxrwxr-x 2 max max 4096 Aug 14 21:11 bin 
-rw-rw-r-- 1 max max  38 Aug 14 21:11 Makefile 
[[email protected] tmp]$ make 
make: Nothing to be done for `all'. 
[[email protected] tmp]$ make 
make: Nothing to be done for `all'. 

¿Su carpeta depende de nada? ¿Tu carpeta es un objetivo falso?

+0

No. Siempre está desactualizado, lo que ves en el PO es lo que tengo. –

0

Bueno, terminó con esta construcción, tal vez alguien le resultará útil o puede hacer comentarios al respecto:

BINDIR = . 
TMPDIR = tmp 
OUTDIRS = $(BINDIR) $(TMPDIR) 
$(OUTDIRS): 
    @test -d [email protected] || mkdir [email protected] 
+0

Make hace 'test' para usted de todos modos, por lo que termina stat'ing el directorio dos veces. Esto simplemente oculta el problema de que el objetivo predeterminado es. (Punto). –

0

Hacer asume el primer objetivo es el destino predeterminado. Si ese es su archivo MAKE completo, entonces siempre debe tratar de rehacer el objetivo predeterminado, que es bin. Inserte las siguientes líneas a la parte superior de su archivo MAKE:

all: bin 
.PHONY: all 
12

Otra forma de suprimir la salida make: error ... (ignored) es agregar || true a un comando que podría fallar.Ejemplo con grep que comprueba si hay errores en un archivo de registro de LaTeX:

undefined: 
    @grep -i undefined *.log || true 

Sin la || true, hacen que se queja cuando grep no encuentra ninguna coincidencia.

Esto funciona para todos los comandos, no solo mkdir; es por eso que agregué esta respuesta.

+0

daniel, el carácter de prefijo '-' a un comando en una regla de hacer hace lo mismo aunque sin requerir que el shell lo maneje. Esto es probablemente más rápido y menos probable que sea contraproducente. –

+7

El prefijo '-' hace que se genere el molesto resultado" error ignorado ", que mi solución no. Entonces, no, los dos no hacen lo mismo. –

+0

Llamada justa. Gracias –

Cuestiones relacionadas