2009-04-01 16 views
5

Quiero inyectar un objetivo de "limpieza" que depende de una serie de otros objetivos que terminan antes de que se apague y gzip de algunos archivos de registro. Es importante que no ejecute gzip anticipadamente ya que esto puede causar que algunas de las herramientas fallen.En scons, ¿cómo puedo inyectar un objetivo para construir?

¿Cómo puedo inyectar un objetivo de limpieza para que se ejecute Scons?

p. Ej. Tengo objetivos foo y bar. Quiero inyectar una nueva diana personalizada llamada 'limpieza' que depende de foo y bar y corre tras los dos están hechas, y sin que el usuario tenga que especificar

% scons foo cleanup 

Quiero que tipo:

% scons foo 

pero tienen scons ejecutan como si el usuario hubiera tecleado

% scons foo cleanup 

he intentado crear el objetivo limpieza y añadiendo a sys.argv, pero parece que scons ya ha procesado por el sys.argv el tiempo llega a mi código, por lo que no procesa el objetivo de "limpieza" que añado de forma manual a sys.argv.

Respuesta

1

En la versión de 1.1.0.d20081104 SCons, puede utilizar el método SCons interna privada:

SCons.Script._Add_Targets([ 'MY_INJECTED_TARGET' ]) 

Si el usuario escribe:

% scons foo bar 

el fragmento de código anterior hará que SCons se comporten como si el usuario hubiera tecleado:

% scons foo bar MY_INJECTED_TARGET 
+1

Funciones no documentadas FTW! :-) Encuentro que a menudo acabo por agotar la fuente de SCons cuando llego a estos problemas "insolubles" ... – richq

+0

¿Esto se rompe cuando se usa la bandera --random? El orden en que se construyen los objetivos proporcionados por el usuario no está definido, hasta donde yo sé. – BenG

+1

Inyecto el objetivo pero tengo dependencias con otros objetivos, por lo que encaja cómodamente en el gráfico. Incluso si hace '' -random'', solo aleatorizará los pasos concurrentes, no los pasos que tienen dependencias entre sí. Las dependencias siempre se cumplen antes de que comience a ejecutarse el comando de compilación de destino dependiente. –

2

Una forma es hacer que la herramienta gzip dependa de la salida de los archivos de registro. Por ejemplo, si tenemos este archivo C, 'hola.c':

#include <stdio.h> 
int main() 
{ 
    printf("hello world\n"); 
    return 0; 
} 

Y este archivo SConstruct:

#!/usr/bin/python 
env = Environment() 
hello = env.Program('hello', 'hello.c') 
env.Default(hello) 
env.Append(BUILDERS={'CreateLog': 
    Builder(action='$SOURCE.abspath > $TARGET', suffix='.log')}) 
log = env.CreateLog('hello', hello) 
zipped_log = env.Zip('logs.zip', log) 
env.Alias('cleanup', zipped_log) 

A continuación, se ejecuta "scons limpieza" se ejecutará los pasos necesarios en el orden correcto :

gcc -o hello.o -c hello.c 
gcc -o hello hello.o 
./hello > hello.log 
zip(["logs.zip"], ["hello.log"]) 

esto no es exactamente lo que ha especificado, pero la única diferencia entre este ejemplo y el requisito es que la "limpieza" es el paso que en realidad crea el archivo zip, por lo que es el paso que tiene correr. Sus dependencias (ejecutando el programa que genera el registro, creando ese programa) se calculan automáticamente. Ahora puede agregar el alias de "foo" de la siguiente manera para obtener la salida deseada:

env.Alias('foo', zipped_log) 
+0

Gracias por las ideas. La cuestión es que estoy realizando un flujo de compilación que tiene piezas que no controlo completamente, por lo que no puedo pregrabar los archivos de registro para que se comprueben porque no conozco todos los archivos de registro que se están creando. –

12

no se debe utilizar _Add_Targets o indocumentados características, puede simplemente añada su objetivo limpieza para BUILD_TARGETS:

from SCons.Script import BUILD_TARGETS 
BUILD_TARGETS.append('cleanup') 

si se utiliza esta lista documentada de los objetivos en lugar de funciones no documentadas, scons no será confundido al hacer su contabilidad.Este bloque de comentarios se pueden encontrar en SCons/Script/__init__.py:

# BUILD_TARGETS can be modified in the SConscript files. If so, we 
# want to treat the modified BUILD_TARGETS list as if they specified 
# targets on the command line. To do that, though, we need to know if 
# BUILD_TARGETS was modified through "official" APIs or by hand. We do 
# this by updating two lists in parallel, the documented BUILD_TARGETS 
# list, above, and this internal _build_plus_default targets list which 
# should only have "official" API changes. Then Script/Main.py can 
# compare these two afterwards to figure out if the user added their 
# own targets to BUILD_TARGETS. 

así que supongo que está destinado a cambiar BUILD_TARGETS lugar de llamar a funciones de ayuda internas

+0

¡Esto funciona genial! Pero una pregunta de seguimiento sería: ¿cómo puedo hacer esto, cuando el objetivo que deseo agregar proviene del escáner? Es decir. se produce en el tiempo de ejecución. Intenté agregar BUILD_TARGETS, pero eso no tuvo ningún efecto. Lo más probable es que SCons no verifique esa lista una vez que comenzó a construir. –

Cuestiones relacionadas