2009-12-10 8 views
5

Ich habe kürzlich Scons zur Implementierung eines Multi-Plattform-Build-Frameworks für ein mittelgroßes C++ - Projekt ausgewählt. Der Build generiert eine Reihe von Komponententests, die am Ende von allem aufgerufen werden sollten. Wie erreicht man so etwas?scons - wie man etwas ausführt/nachdem/alle Ziele wurden gebaut

Zum Beispiel in meinem Top-Level-SConstruct, ich habe

subdirs=['list', 'of', 'my', 'subprojects'] 
for subdir in subdirs: 
    SConscript(dirs=subdir, exports='env', name='sconscript', 
     variant_dir=subdir+os.sep+'build'+os.sep+mode, duplicate=0) 

Jede der subdir seine Einheit-Tests hat jedoch, da es Abhängigkeiten zwischen den DLLs und ausführbaren Dateien in sie gebaut - ich mag halten das Ausführen von Tests, bis alle Unterverzeichnisse erstellt und installiert wurden (ich meine, mit env.Install).

Wo soll ich die Schleife schreiben, um durch die gebauten Tests zu iterieren und sie auszuführen? Ich habe versucht, es direkt nach dieser Schleife zu setzen - aber da scons Sie nicht die Reihenfolge der Ausführung steuern lässt - wird es ausgeführt, bevor ich es möchte.

Bitte helfen Sie einem SCON-Neuling. :)

Dank,

Antwort

0

In Bezug auf den Abhängigkeiten, was Sie wollen, ist für alle Tests Aktionen auf alle Programm gebaute Aktionen abhängen. Eine Möglichkeit besteht darin, ein Dummy-Ziel in allen Konsignationsdateien der Unterverzeichnisse zu erstellen und zu exportieren, und in den sconscript-Dateien das Dummy-Ziel Depends auf den Hauptzielen zu setzen und die Testziele Depends auf dem Dummy-Ziel zu haben .

Ich bin ein wenig Mühe, herauszufinden, wie das Dummy-Ziel einzurichten, aber das funktioniert im Grunde:

(in der obersten Ebene SConstruct)

dummy = env.Command('.all_built', 'SConstruct', 'echo Targets built. > $TARGET') 
Export('dummy') 

(in jeder Sub- Verzeichnis des SConscript)

Import('dummy') 
for target in target_list: 
    Depends(dummy, targe) 
for test in test_list: 
    Depends(test, dummy) 

ich bin sicher, dass weitere Verfeinerungen möglich sind, aber vielleicht wird dies Ihnen den Start.

EDIT: auch erwähnenswert this page zum Thema.

5

SCons, wie Make, verwenden eine deklarative Methode, um das Build-Problem zu lösen. Sie wollen SCons nicht sagen, wie es seinen Job macht. Sie möchten alle Abhängigkeiten dokumentieren und dann SCOs lösen lassen, wie alles aufgebaut wird.

Wenn etwas vor etwas anderem ausgeführt wird, müssen Sie Abhängigkeiten erstellen und verknüpfen.

Wenn Sie dmy Touch-Dateien erstellen möchten, können Sie einen benutzerdefinierten Builder wie erstellen:

import time 

def action(target, source, env): 
    os.system('echo here I am running other build') 
    dmy_fh = open('dmy_file','w') 
    dmy_fh.write('Dummy dependency file created at %4d.%02d.%02d %02dh%02dm%02ds\n'%time.localtime()[0:6]) 
    dmy_fh.close() 

bldr = Builder(action=action) 
env.Append(BUILDERS = {'SubBuild' : bldr }) 

env.SubBuild(srcs,tgts) 

Es ist sehr wichtig, den Zeitstempel in die Dummy-Datei zu setzen, weil scons md5 Hashes verwendet. Wenn Sie eine leere Datei haben, ist der md5 immer derselbe und es könnte entscheiden, nachfolgende Build-Schritte nicht durchzuführen. Wenn Sie verschiedene Optimierungen für einen Basisbefehl generieren müssen, können Sie Funktionsfactorys zum Ändern einer Vorlage verwenden. z.B.

def gen_a_echo_cmd_func(echo_str): 
    def cmd_func(target,source,env): 
     cmd = 'echo %s'%echo_str 
     print cmd 
     os.system(cmd) 
    return cmd_fun 

bldr = Builder(action = gen_a_echo_cmd_func('hi')) 
env.Append(BUILDERS = {'Hi': bldr}) 
env.Hi(srcs,tgts) 

bldr = Builder(action = gen_a_echo_cmd_func('bye')) 
env.Append(BUILDERS = {'Bye': bldr}) 
env.Bye(srcs,tgts) 

Wenn Sie etwas, das Sie wollen automatisch injizieren in die scons Fluss bauen (zum Beispiel etwas, das Ihr alle Build komprimiert Protokolldateien nach der alles andere ausgeführt wurde), siehe my question here.

2

Die Lösung sollte so einfach sein.

Machen Sie das Ergebnis der Prüfung Bauer hängen vom Ergebnis der Erbauer Installieren

In pseudo:

test = Test(dlls) 
result = Install(dlls) 
Depends(test,result) 

Der beste Weg wäre, wenn der Test-Generator tatsächlich für Sie die DLL-Abhängigkeiten ausgearbeitet , aber es kann alle möglichen Gründe geben, warum es das nicht tut.

0

Haben Sie einfach SConscript geben Sie einen Wert, auf dem Sie Abhängigkeiten erstellen.

SConscript Datei:

test = debug_environment.Program('myTest', src_files) 
Return('test') 

SConstruct Datei:

dep1 = SConscript([...]) 
dep2 = SConscript([...]) 
Depends(dep1, dep2) 

Jetzt dep1 Build wird abgeschlossen, nachdem dep2 Build abgeschlossen hat.