2017-02-27 2 views
0

Ich sehe ein seltsames Verhalten von Scons 2.3.0. Vielleicht bin das ich es einfach falsch ™, aber dies scheint, wie sollte es vernünftig sein ...scons ignoriert den Dateizielpfad?

destinations = [base_dir+'lib/', base_dir+'tree/usr/local/lib/'] 
boost_ver = '1.63.0' 
boost_libs = (x for x in env['LIBS'] if 'boost_' in x) 
# eg. 'boost_thread', 'boost_system' 

for dest in destinations: 
    for lib_name in boost_libs: 
     lib_so = 'lib'+lib_name+'.so' 
     lib_so_ver = lib_so+'.'+boost_ver 

     env.Command(dest+lib_so_ver, libsrc+lib_so_ver, Copy("$TARGET","$SOURCE")) 
     env.Command(dest+lib_so, dest+lib_so_ver, SymLink) 

Der Punkt die genannten Bibliotheken und sie von libsrc zu jedem der destinations kopieren zu nehmen sein, die neu zu erstellen nicht versionierter Symlink, wie es geht. (base_dir und libsrc sind absolute Pfade, obwohl base_dir Punkte innerhalb des scons Ausgabebaum.)

Dies funktioniert gut für ein einzelnes Ziel, aber das Kopieren oder Verknüpfung tritt nie für andere Ziele. Ich habe versucht, explizite Abhängigkeiten mit env.Depends hinzuzufügen; Ich habe versucht, das Ergebnis Variablen zuzuordnen und später zu verwenden; nichts scheint zu funktionieren.

Wenn ich am Ausgang der --tree schauen, immer nur die Dateien in dem ersten Ziel aufgeführt sind; irgendwelche nachfolgenden sind nie. (Wenn ich die Reihenfolge sie aufgeführt in ändern, dann, was ist nun zunächst die einzige aufgeführt.)

Wenn ich ein Alias ​​Ziel für jedes Ziel hinzuzufügen, und es Depends auf dem Ergebnis der Befehle machen, dann Beide Alias-Ziele erscheinen in der Baumstruktur, aber nur die erste hat Unterelemente. der zweite erscheint immer ohne Kinder.

Auch wenn ich explizit das zweite Alias-Ziel auf der Befehlszeile angeben, tut es nichts und drucken keine Kinder im --tree. Nur wenn ich die Ziele neu anordne, kann ich alles erledigen - und dann hört natürlich der andere auf zu arbeiten.

Grundsätzlich scheint es so zu sein, als ob nur eine Aktion für eine gegebene Eingabedatei möglich ist, und ignoriert alle Versuche, eine Quelldatei mehrmals zu verwenden, ohne auch nur eine Warnung zu geben. Das scheint nur verrückt.

+0

Können Sie etwas mehr darüber erzählen, was das 'SymLink' Methode (?) Tut und warum es scheint keine Argumente zu müssen? Ich finde keine Methode/Fabrik mit diesem Namen in der UserGuide/Quellen ... weder für SCONs 2.3.0, noch für die neuesten 2.5.1. – dirkbaechle

+0

Es ist nur eine lokal definierte Python-Funktion ('def SymLink (Ziel, Quelle, env)'), die das tut, was es klingt. Es verwendet die Standard-Scons [Mechanismus für benutzerdefinierte Aktionserweiterungen] (http://scons.org/doc/2.3.0/HTML/scons-user.html#chap-builders-commands) und ist für dieses Problem nicht relevant. – Miral

+0

Um zu verdeutlichen: Sowohl die Kopie als auch der Symlink funktionieren für ein einzelnes Ziel. Weder die Kopie noch der Symlink funktionieren für zusätzliche Ziele, da scons das zusätzliche 'Command' zu ignorieren scheint. Die einzige Theorie, die ich habe, warum dies passiert, ist, dass die Quelle für den ersten Befehl in jedem Paar zwischen allen Zielen gleich ist. Aber das scheint ein dummer Grund dafür zu sein, zu versagen, wenn das tatsächlich der Grund ist. – Miral

Antwort

0

stellte sich heraus, das mit Scons war kein Problem, aber mit Python. Das eigentliche Problem ™ ist diese Definition:

boost_libs = (x for x in env['LIBS'] if 'boost_' in x) 

Aus irgendeinem Grund (klar meine Python-Fu ist nicht hoch genug) ergibt sich die innere for-Schleife oben nur einmal für das erste Ziel ausführt.

Die Lösung ist eckige Klammern zu verwenden, anstatt:

boost_libs = [x for x in env['LIBS'] if 'boost_' in x] 

Dies führt korrekt die innere Schleife für jedes Ziel.

+0

Als Referenz kenne ich jetzt den Grund - die Syntax in Klammern ist ein Generator, der nur einmal durchlaufen werden kann. Umgekehrt ist es mit eckigen Klammern eine Liste, die oft wiederholt werden kann. Um noch mehr Verwirrung zu stiften, können Tupel (die auch Klammern verwenden) oft wiederholt werden. – Miral

+0

(Das verwirrende an Tupeln war, dass der Code vorher '(' boost_thread ',' boost_system ')' gelesen hatte, und dies funktionierte wie erwartet - aber es gab einen Ausdruck, während die Klammern es durchbrachen weil man anscheinend nicht von Generatoren wusste, aber der vorherige Entwickler trug zur Verwirrung bei, indem er ein Tupel anstelle einer Liste verwendete.) – Miral