2009-04-01 6 views
5

Je veux injecter une cible "Nettoyage" qui dépend d'un certain nombre d'autres cibles qui terminent avant qu'elle ne disparaisse et de certains fichiers journaux de gzip. Il est important que je ne gomme pas tôt car cela peut entraîner l'échec de certains outils.Dans Scons, comment puis-je injecter une cible à construire?

Comment puis-je injecter une cible de nettoyage pour l'exécution de Scons?

par exemple. J'ai des objectifs foo et bar. Je veux injecter une nouvelle cible personnalisée appelée « nettoyage » qui dépend de foo et bar et court après ils sont tous deux faits, sans que l'utilisateur ait à spécifier

% scons foo cleanup 

Je veux qu'ils tapent:

% scons foo 

mais ont scons exécutent comme si l'utilisateur avait tapé

% scons foo cleanup 

J'ai essayé de créer la cible de nettoyage et à annexant sys.argv, mais il semble que scons a déjà traité sys.argv par le temps qu'il arrive à mon code afin qu'il ne traite pas la cible de «nettoyage» que j'ajoute manuellement à sys.argv.

Répondre

1

Dans la version 1.1.0.d20081104 de SCons, vous pouvez utiliser la méthode SCons interne privée:

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

Si les types d'utilisateurs:

% scons foo bar 

l'extrait de code ci-dessus causera SCons à se comporter comme si l'utilisateur avait tapé:

% scons foo bar MY_INJECTED_TARGET 
+1

Fonctionnalités non documentées FTW! :-) Je trouve que je finis souvent par greber la source pour SCons lorsque je rencontre ces problèmes "insolubles" ... – richq

+0

Est-ce que cela se casse quand le drapeau --random est utilisé? L'ordre dans lequel les cibles fournies par l'utilisateur sont construites n'est pas défini, pour autant que je sache. – BenG

+1

J'injecte la cible mais ai des dépendances sur d'autres cibles, donc elle s'ajuste bien dans le graphe. Même si vous faites '' -random'', cela ne fera que randomiser les étapes concurrentes - pas les étapes qui ont des dépendances les unes sur les autres. Les dépendances sont toujours satisfaites avant que la commande de construction de la cible dépendante ne commence à s'exécuter. –

2

Une solution consiste à faire dépendre l'outil gzip de la sortie des fichiers journaux. Par exemple, si nous avons ce fichier C, 'hello.c':

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

Ce fichier 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) 

Ensuite, en cours d'exécution "scons nettoyage" se déroulera les étapes nécessaires dans l'ordre correct :

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

ce n'est pas tout à fait ce que vous avez spécifié, mais la seule différence entre cet exemple et votre exigence est que « nettoyage » est l'étape qui crée en fait le fichier zip, de sorte que est l'étape que vous avez courir. Ses dépendances (exécutant le programme qui génère le journal, créant ce programme) sont automatiquement calculées. Vous pouvez maintenant ajouter l'alias "foo" comme suit pour obtenir la sortie désirée:

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

Merci pour les idées. Le truc, c'est que je fais un flux de build qui contient des morceaux que je ne contrôle pas complètement, donc je ne peux pas pré-enregistrer les fichiers journaux à compresser car je ne connais pas tous les fichiers journaux en cours de création. –

12

vous ne devriez pas utiliser _Add_Targets ou fonctions non documentées, vous pouvez simplement ajouter votre cible de nettoyage à BUILD_TARGETS:

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

si vous utilisez cette liste documentée des cibles plutôt que des fonctions non documentées, scons ne sera pas confus en faisant sa comptabilité.Ce bloc de commentaire se trouve dans 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. 

donc je suppose qu'il est destiné à changer BUILD_TARGETS au lieu d'appeler des fonctions auxiliaires internes

+0

Cela fonctionne très bien! Mais une question de suivi serait - comment puis-je faire cela, lorsque la cible que je veux ajouter vient du scanner? C'est à dire. il est produit à l'exécution. J'ai essayé d'ajouter à BUILD_TARGETS, mais cela n'a eu aucun effet. Le plus probable SCons ne vérifie pas cette liste après avoir commencé à construire. –

Questions connexes