2009-04-01 12 views
5

Chcę wstrzyknąć cel "Oczyszczanie", który zależy od wielu innych obiektów docelowych kończących się przed wygaśnięciem i plików dziennika gzip. Ważne jest, aby nie gzip wcześnie, ponieważ może to spowodować awarię niektórych narzędzi.W scons, w jaki sposób mogę wstrzyknąć cel do zbudowania?

W jaki sposób mogę wprowadzić cel oczyszczania, aby Scons został wykonany?

np. Mam cele foo i bar. Chcę wprowadzić nowy cel niestandardowej nazwie „czyszczenia”, który zależy od foo i bar i biegnie po obaj zrobione bez użytkownik posiadający określenie

% scons foo cleanup 

chcę, żeby wpisać:

% scons foo 

ale mają scons wykonać tak, jakby użytkownik miał wpisane

% scons foo cleanup 

próbowałem tworzenia cel oczyszczania i dołączanie do sys.argv, ale wydaje się, że scons już przetwarzane przez sys.argv czas dostanie się do mojego kodu, więc nie przetwarza celu "czyszczenia", który ręcznie dołączam do sys.argv.

Odpowiedz

1

W wersji 1.1.0.d20081104 z SCons, można korzystać z prywatnej metody wewnętrznych SCons:

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

Jeśli użytkownik wpisze:

% scons foo bar 

powyższy kod urywek spowodują SCons zachowywać się tak, jakby użytkownik miał wpisane:

% scons foo bar MY_INJECTED_TARGET 
+1

Nieudokumentowane funkcje FTW! :-) Zdarza mi się, że często kończę szukać źródła dla SCons, kiedy trafiam w te "nierozwiązywalne" problemy ... – richq

+0

Czy to się psuje, gdy używana jest flaga --random? Kolejność, w jakiej są tworzone cele dostarczone przez użytkownika, jest nieokreślona, ​​o ile wiem. – BenG

+1

Wstrzykuję cel, ale mam zależności od innych celów, więc pasuje idealnie do wykresu. Nawet jeśli użyjesz '' -random'', będzie to tylko randomizacja równoczesnych kroków - a nie kroków, które mają wzajemne zależności. Zależności są zawsze spełnione, zanim rozpocznie się wykonywanie polecenia zależnego budowania celu. –

2

Jednym ze sposobów jest uzależnienie narzędzia gzip od danych wyjściowych plików dziennika. Na przykład, jeśli mamy ten plik C „hello.c”:

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

i ten plik 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) 

następnie uruchomić „scons porządki” potrwa niezbędnych czynności w odpowiedniej kolejności :

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

to nie jest całkiem co podałeś, ale jedyna różnica między tym przykładem i zapotrzebowania jest to, że „czyszczenie” jest krokiem, który rzeczywiście tworzy plik zip, dzięki czemu jest to krok, który trzeba biegać. Jego zależności (uruchamianie programu generującego dziennik, tworzenie tego programu) są obliczane automatycznie. Teraz można dodać alias „foo” w następujący sposób, aby uzyskać pożądany wynik:

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

Dzięki za pomysły. Chodzi o to, że robię przepływ budowania, który ma części, których nie kontroluję całkowicie, więc nie mogę wstępnie rejestrować plików dziennika, które mają być spakowane, ponieważ nie znam wszystkich tworzonych plików dziennika. –

12

nie należy używać _Add_Targets lub nieudokumentowane funkcje, można po prostu dodaj swój cel oczyszczania do BUILD_TARGETS:

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

jeśli używasz tego udokumentowaną listę celów, zamiast funkcji nieudokumentowanych, scons nie będzie zdezorientowany podczas wykonywania księgowości.Ten komentarz blok można znaleźć w 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. 

więc myślę, że jest on przeznaczony do zmiany BUILD_TARGETS zamiast wywoływania wewnętrznych funkcji pomocnika

+0

Działa to świetnie! Kolejnym pytaniem będzie - jak to zrobić, gdy cel, który chcę dodać, pochodzi ze skanera? To znaczy. jest produkowany w czasie wykonywania. Próbowałem dodać do BUILD_TARGETS, ale to nie miało żadnego efektu. Najprawdopodobniej SCons nie sprawdza tej listy po rozpoczęciu budowy. –