2016-06-21 10 views
6

Die neueste Version von make hat eine Option --output-sync die Atom den STDOUT jedes Ziel machen kann, so dass Aussagen von mehreren Zielen verschachtelt sind, nicht bei der Verwendung von make --jobs=NGNU make 3.81 - wie zu tun ‚--output-sync = target‘

Leider muss ich make v 3.81 verwenden, denn das ist die, die mit unserem SDK kommt.

Um festzustellen, ob ich --output-sync brauchen, habe ich einige ‚guard Aussagen‘ um meine Ziele

all: $(patsubst %.cpp, %.o, $(wildcard *.cpp)) 


%.o: %.cpp 
    @echo BEFORE 
    @echo MAKEFLAGS=$(MAKEFLAGS) 
    qcc.exe $(CC_FLAGS) [email protected] $< 
    @echo AFTER 

Der Ausgang sehr verschachtelt wurde.

AFTER 
BEFOREAFTER 
AFTER 
AFTER 

Gibt es eine Möglichkeit, die --output-sync Funktionalität zu emulieren?

Ich verstehe, dass die Baugeschwindigkeit beeinträchtigt werden kann, wenn es zum Beispiel eine Möglichkeit gibt, das Vorrezept "STDOUT Mutex" zu sperren und nach dem Rezept freizugeben.

Mir geht es gut, jedes unserer Ziele zu modifizieren, wenn es das braucht.

+1

Verwenden Sie nicht die Option '-j'? Dadurch wird das Interleaving vermieden, und es ist trivial, das Makefile zu modifizieren, und es entspricht ungefähr allem, was Sie vorhaben, nur einfacher. Ist das Feature nur in GNU Make 4.2? Stellt GNU Make 4.2.1 das Problem, das Sie mit 4.2 haben, wieder her? –

+0

@ JonathanLeffler Ich muss '-j' verwenden, um parallele Builds zu erhalten. Ich werde den Beitrag bezüglich der 'make'-Version aktualisieren. – Adrian

Antwort

0

Sie könnten alle Ausgänge eines Rezepts in einer temporären Datei protokollieren und Katzen entfernen es am Ende:

%.o: %.cpp 
    @d=$$(mktemp) && \ 
    echo BEFORE >> $$d 2>&1 && \ 
    echo MAKEFLAGS=$(MAKEFLAGS) >> $$d 2>&1 && \ 
    qcc.exe $(CC_FLAGS) [email protected] $< >> $$d 2>&1 && \ 
    echo AFTER >> $$d 2>&1 && \ 
    cat $$d && \ 
    rm $$d 

Dies wird vollständig Verschachtelung nicht verhindern, weil mehrere cat Befehle parallel ausgeführt werden können, wenn Sie mehrere CPUs, aber es sollte die Wahrscheinlichkeit erheblich reduzieren. Wenn Sie Interleaving wirklich vollständig vermeiden möchten, müssen Sie einen Spin-Lock um die cat Befehle hinzufügen. Unter einem GNU/Linux-Betriebssystem können Sie einen Blick auf flock haben, zum Beispiel:

%.o: %.cpp 
    @d=$$(mktemp) && \ 
    echo BEFORE >> $$d 2>&1 && \ 
    echo MAKEFLAGS=$(MAKEFLAGS) >> $$d 2>&1 && \ 
    qcc.exe $(CC_FLAGS) [email protected] $< >> $$d 2>&1 && \ 
    echo AFTER >> $$d 2>&1 && \ 
    flock /tmp/my-lock-file cat $$d && \ 
    rm $$d 

Erläuterungen:

  • ich Ihr Rezept in einem einzigen Shell-Aufruf transformierte (jede Zeile in einem Make Rezepte wird in einer anderen Shell ausgeführt), so dass die d Shell-Variable in allen Befehlen in der Liste verfügbar ist.
  • Die Befehle werden mit dem Operator && verkettet: Wenn einer fehlschlägt, schlägt die gesamte Liste mit demselben Exit-Status fehl und make wird Ihnen das mitteilen.
  • Anstatt alle Befehle auf die selbe Zeile zu setzen, die schnell unlesbar wird, habe ich \ vor allen Zeilenenden eingefügt, aber die letzte Zeile. Besser lesbar, aber immer noch als eine einzige Zeile von make interpretiert.
  • Der erste Befehl in der Liste (mktemp) erstellt automatisch eine eindeutige temporäre Datei. Verwenden Sie ein in Ihrer Umgebung verfügbares Äquivalent. Beachten Sie die Doppel $ in d=$$(mktemp). Es ist erforderlich, die erste Erweiterung mit make zu übergeben und d=$(mktemp) zu werden, wenn es an die Shell übergeben wird. Gleiches gilt für die Shell-Erweiterung der Shell-Variablen d: $$d wird zunächst um make als $d erweitert, bevor sie an die Shell übergeben wird.
  • Die Umleitungen der Ausgaben der Befehle (>> $d 2>&1 nach der ersten Erweiterung durch make) leiten die Standardausgaben in die temporäre Datei im Append-Modus (>> $d) um und machen den Standardfehlerdeskriptor eine Kopie des Standardausgabedeskriptors (2>&1) mit der Effekt, dass die Standardfehler auch an dieselbe temporäre Datei angehängt werden.
+0

Um Verschleierungsrezepte zu vermeiden, würde ich ein Skript erstellen, das darauf achtet, die Ausgabe zu serialisieren, und das Skript in einem Makefile als ['SHELL'] verwenden (https://www.gnu.org/software/make/manual/). html_node/Wählen-der-Shell.html). In einigen Fällen kann auch ['.ONESHELL'] (https://www.gnu.org/software/make/manual/html_node/One-Shell.html) hilfreich sein. – Kuchara

+0

Ich kann nicht glauben, dass diese Frage so populär ist, da 'gnu make 3.81' wirklich alt ist! Sind so viele Entwickler noch dabei? – Adrian

+1

@Adrian Ja, es ist auf dem Cluster-System, das ich benutze und ich kann nichts dagegen tun. – mxmlnkn

Verwandte Themen