Moin, größere Pakete (z.B den Kernel) übersetze ich in Linux mit make -j6, um alle Cores zu auszulasten. Hin und wieder bricht make jedoch mit einem Fehler ab (mit einer unverständlichen Fehlermeldung). Bei einem weiteren Aufruf macht make dann an dieser Stelle weiter, und fast immer läuft es dann durch. Wird nur ein Core verwendet, tritt der Fehler nicht auf. Das Problem tritt bei allen Versionen und Backends des gcc auf, die ich bisher verwendet habe. Ist kein Weltuntergang, nervt aber. Kennt jemand das Problem?
Vancouver schrieb: > (mit einer unverständlichen Fehlermeldung) mit der könnte man dir hier vll. helfen, aber so bleibt nur die Glaskugel...
Warum denn nicht einfach mal die Fehlermeldung hier posten?
proggen schrieb: > Vancouver schrieb: >> (mit einer unverständlichen Fehlermeldung) > > mit der könnte man dir hier vll. helfen, aber so bleibt nur die > Glaskugel... Ich bezweifle es. Das passiert hin und wieder, weiß auch nicht woran es liegt. Den QtWebKit-Build muss man auch grundsätzlich zweimal starten ...
Das Problem ist, dass schon ein Modul gebaut werden soll, wofuer die abhaengigkeit vielleicht noch gar nicht gebaut ist. Das kann bei -j1 nicht passieren. Beispiel: Du hast Modul A und Modul B. A braucht 30 Sekunden zum compilieren und B nur 10 Sekunden. B ist aber abhaengig von A. Bei -j1 wird brav Modul A gebaut und dann Modul B. Somit ist die Abhaengigkeit fuer B vorhanden. Bei -j6 ist das aber nicht mehr gegeben. Jetzt werden A und B gleichzeitig compiliert und das compilieren schlaegt natuerlich fehl, weil die abhaengigkeit fuer B noch nicht vorhanden ist. Ja, es gibt tatsaechlich faelle, wo sowas auftreten kann. Es gibt Pakete die mit -j1 gebaut werden muessen. Das kann z.B. auftreten, wenn Modul A zu einer Lib gebaut wird, und Modul B auf diese Lib zugreifen will. Ist die Lib nicht vorhanden kann es nicht compiliert werden.
Nachtrag: Deswegen geht es dann beim zweitenmal Compilieren, dann ist die Abhengigkeit vorhanden.
Das sollte dann aber zu aussagekräftigen Fehlermeldungen führen. Und eigentlich deutet sowas auf Fehler im makefile hin. Oliver
> mit der könnte man dir hier vll. helfen, aber so bleibt nur die > Glaskugel... Ja, da hast Du grundsätzlich recht. Aber ich habe die Fehlermeldung nicht parat, da müsste ich das ganze nochmal ausprobieren. Ich habe gehofft, das jemand das Problem kennt. @Kaj: Ich habe auch schon orakelt, dass es ein Dependency-Problem ist, aber eigentlich sollte make solche Abhängigkeiten doch auflösen. Also gut, dann eben Neustarten. Das geht immernoch schneller als Singlethreaded. Danke für Eure Hilfe!
Vancouver schrieb: > @Kaj: Ich habe auch schon orakelt, dass es ein Dependency-Problem ist, > aber eigentlich sollte make solche Abhängigkeiten doch auflösen. Aber nur, wenn diese im Makefile auch angegeben sind, stelle dir volgendes (ungetestetes) szenario vor:
1 | all: a b |
2 | cat a b > all |
3 | a: c |
4 | cat c > a |
5 | b: c |
6 | cat a c > b |
7 | c: |
8 | echo test > c |
In diesem Beispiel braucht b a, aber a ist nicht als dependency angegeben. "make all -j1" wird zuerst a und dann b erstellen, aber "make all -j2" wird es gleichzeitig versuchen, weil es von der Abhängigkeit, die nicht richtig angegeben wurde, nichts weiss.
Daniel A. schrieb: > In diesem Beispiel braucht b a, aber a ist nicht als dependency > angegeben. Oliver S. schrieb: > Und eigentlich deutet sowas auf Fehler im makefile hin. Qed Oliver
> Und eigentlich deutet sowas auf Fehler im makefile hin.
Ich würde das nicht einen Fehler nennen. Die Abhängigkeit ist implizit
gegeben durch die Reihenfolge der Regeln im Makefile. Eigentlich wäre es
die Aufgabe vom make, die Regeln beim Multithreading so zu schedulen,
dass bei -jN das Gleiche herauskommt wie bei -j1, aber dazu müsste make
die Regeln tiefer analysieren, sonst wäre alles wieder sequenziell. Das
ist vermutlich viel zu aufwändig, schließlich ist make kein
parallelisierender Compiler.
Vancouver schrieb: > Die Abhängigkeit ist implizit > gegeben durch die Reihenfolge der Regeln im Makefile. Eigentlich wäre es > die Aufgabe vom make, die Regeln beim Multithreading so zu schedulen, > dass bei -jN das Gleiche herauskommt wie bei -j1, Wie soll das denn gehen? Er muß ja dann die Reihenfolge einhalten, und damit geht nichts mehr parallel... Nein, patrallele Builds (das ist doch eher Multi-Processing als Multi-Threading, oder?) gehen nur problemlos mit komplett sauberen Abhängigkeiten. Ansonsten muß man halt restarten...
Bernhard M. schrieb: > Er muß ja dann die Reihenfolge einhalten, und damit geht nichts mehr > parallel... Das nicht, aber er muss die Abhängigkeiten selbst analysieren um herauszufinden, was parallel machbar ist. Parallelisierende Compiler tun genau das, aber make nicht, deswegen muss der Anwender die Abhängigkeiten explizit angeben. >(das ist doch eher Multi-Processing als Multi-Threading, oder?) Ja, richtig.
Kaj schrieb: > Das Problem ist, dass schon ein Modul gebaut werden soll, wofuer die > abhaengigkeit vielleicht noch gar nicht gebaut ist. > > Das kann bei -j1 nicht passieren. Ja, genau so ist es. Vancouver schrieb: >> Und eigentlich deutet sowas auf Fehler im makefile hin. > > Ich würde das nicht einen Fehler nennen. Die Abhängigkeit ist implizit > gegeben durch die Reihenfolge der Regeln im Makefile. Nein. Der ganze Sinn hinter einem Makefile ist, dass man ihm die Abhängigkeiten explizit nennt. Die Reihenfolge der Regeln ist dabei völlig egal. > Eigentlich wäre es die Aufgabe vom make, die Regeln beim Multithreading > so zu schedulen, dass bei -jN das Gleiche herauskommt wie bei -j1, aber > dazu müsste make die Regeln tiefer analysieren, sonst wäre alles wieder > sequenziell. Nein, die Regeln müssen korrekt angegeben sein. Wie soll make durch "tieferes Analysieren" der Regeln wissen, was wovon abhängig ist? Genau damit make das weiß, gibt man die Abhängigkeiten doch an. > Das ist vermutlich viel zu aufwändig, schließlich ist make kein > parallelisierender Compiler. Make kümmert sich vor allem nicht darum, was da überhaupt erzeugt wird. Man sagt ihm nur: "Ich will eine Datei x haben. Die wird von Kommando k erzeugt, und dafür muss Datei y schon vorhanden sein". Und das kann man dann wiederum rekursiv machen, um z.B. wiederum Datei y zu erzeugen, wenn dafür eine Regel vorhanden ist. Ob k jetzt ein C-Compiler oder ein xslt-Konverter oder ein mp3-Encoder ist und wie der Erzeugungsvorgang funktioniert, ist make dabei völlig wurscht. Dementsprechend kann es da auch nix analysieren, um auf magische Weise die Abhängigkeiten zu finden. Vancouver schrieb: >>(das ist doch eher Multi-Processing als Multi-Threading, oder?) > > Ja, richtig. Es ist ein "parallel build". Make führt einfach mehrere Regeln gleichzeitig aus, wenn die nicht von einander abhängen. Übrigens wirken sich solche fehlenden Abhängigkeiten nicht nur beim parallelen Bauen aus, sondern auch, wenn man was am Code ändert. Dann werden ggf. Teile nicht gebaut, weil make nicht weiß, dass die von der geänderten Datei abhängig sind.
:
Bearbeitet durch User
Rolf M. schrieb: > Nein. Der ganze Sinn hinter einem Makefile ist, dass man ihm die > Abhängigkeiten explizit nennt. Die Reihenfolge der Regeln ist dabei > völlig egal. Unabhängige Regeln werden bei -j1 in der Reihenfolge abgearbeitet, wie sie im Makefile stehen, richtig? Damit werden implizit Abhängigkeiten aufgelöst, wie im cat-Beispiel oben. Das ist nicht schön, aber erlaubt und es funktioniert zuverlässig bei Single-processing. > Wie soll make durch "tieferes Analysieren" der Regeln wissen, was wovon abhängig ist? make könnte sich diese Regel anschauen: b: c cat a c > b und erkennen, dass neben der expliziten Abhängigkeit von c offensichtlich auch noch a verwendet wird. make selbst kann übrigens selbst Dependencies erkennen, wenn man es ihm sagt, siehe http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ Oder viel einfacher, wenn eine Regel wegen einer fehlenden Abhängigkeit einen Fehler liefert, könnte man sie zu einem späteren Zeitpunkt wiederholen. Genau das tue ich, wenn ich einen abgebrochen make-Lauf neu starte. Erst wenn am Schluss noch Regeln übrigbleiben, die nicht bearbeitet werden können, gibt es wirklich einen Fehler. Auf diese Weise gehen viele andere Build-Tools vor, z.B. für FPGA-Synthese, die die gesamte Dependency-Analyse selbst duchführen. Mir ist (jetzt) schon klar, dass make explizite Abhängigkeiten braucht, um immer korrekt zu funktionieren. Aber leider ist das bei vielen großen Projekten nicht der Fall (Kernel, GNURadio, um nur zwei zu nennen), und ich verspüre relativ wenig Lust, hunderte verschachtelte Makefiles zu durchforsten.
Vancouver schrieb: > Das ist nicht schön, aber erlaubt > und es funktioniert zuverlässig bei Single-processing. und geht bei Multithreading halt in die Hose. Ist wie mit jedem Stück Software: nur, weil es unter ganz bestimmten Randbedingungen den Anschein hat, daß es tut, was es soll, ist es noch lange nicht fehlerfrei. Oliver
Vancouver schrieb: > make könnte sich diese Regel anschauen: > > b: c > cat a c > b > > und erkennen, dass neben der expliziten Abhängigkeit von c > offensichtlich auch noch a verwendet wird. Das ist einfach unrealistisch. Make würde dafür wissen müssen, was der Befehl tut. Wäre da z.B. echo stat cat, brauchte man weder a noch c. Make kann unmöglich jedes Kommando kennen. Vancouver schrieb: > make selbst kann übrigens > selbst Dependencies erkennen, wenn man es ihm sagt, siehe > http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ Die methode scheint mir eher alles komplizierter zu machen. Vancouver schrieb: > Oder viel einfacher, wenn eine Regel wegen einer fehlenden Abhängigkeit > einen Fehler liefert, könnte man sie zu einem späteren Zeitpunkt > wiederholen. Dazu müsste aber make von jeder Anwendung jede Fehlermeldung kennen, was nicht möglich ist, oder die Dateizugriffs syscalls abfangen, und einer Abhängigkeit zuordnen, was auch nicht möglich ist.
Daniel A. schrieb: > Die methode scheint mir eher alles komplizierter zu machen. Ist sie auch, das gibt die absolut kryptischen makefiles. Aber sie funktioniert. > Dazu müsste aber make von jeder Anwendung jede Fehlermeldung kennen, was Nein, wenn eine Regel irgendeinen Fehler liefert, wird sie später wiederholt. Wenn der Fehler nicht durch eine Dependency ausgelöst wurde, wird er dann wieder auftreten. Aber das wird jetzt alles sehr hypothetisch. Lassen wir make so wie es ist. Schönes Wochenende :-)
Vancouver schrieb: > Das > Problem tritt bei allen Versionen und Backends des gcc auf, die ich > bisher verwendet habe. Das hat nichts mit dem GCC/Compiler ansich zutun. Wo kommen die Makefiles her? Die sind offensichtlich nicht richtig konfiguriert.
Weshalb nimmst Du nicht cmake? Das baut Dir ein funktionierendes makefile mit allem drum und dran. Grüsse, René
Vancouver schrieb: >> Dazu müsste aber make von jeder Anwendung jede Fehlermeldung kennen, was > Nein, wenn eine Regel irgendeinen Fehler liefert, wird sie später > wiederholt. Make wiederholt nichts.
Rene H. schrieb: > Weshalb nimmst Du nicht cmake? Das baut Dir ein funktionierendes > makefile mit allem drum und dran. Weil cmake auch kein Selbstläufer ist und falsche nicht eingetragenen Abhängigkeiten (falsche Konfigurationen) führen auch hier zu Fehlern. ;-)
Daniel A. schrieb: > Vancouver schrieb: >> make selbst kann übrigens >> selbst Dependencies erkennen, wenn man es ihm sagt, siehe >> http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ > Die methode scheint mir eher alles komplizierter zu machen. Die Dependencies macht make da auch nicht. Das sind nur "clever" geschriebene Regeln, die bspw. auf sed oder gcc -M basieren, und so Dependencies "automatisch" erstellen. Bspw. durch Durchsuchen der C Files nach #includes, Schreiben einer neuen Datei mit den gefundenen Abhängigkeiten; und diese Datei wird wiederum vom Makefile geladen. Funktioniert. :-) Das hat aber nix mit speziellen Fähigkeiten von make zu tun, wie @Vancouver behauptet. Wie auch? Make ist einfach nur ein Regelwerk das nichts von C oder welcher Sprache auch immer weiß.
:
Bearbeitet durch User
Kann es eventuell sein daß das verwendete Dateisystem eine von einem Prozess neu erzeugte Datei für einem anderen Prozess erst mit etwas Verzögerung sichtbar werden lässt? Vielleicht kann man irgendwelche Speicherbarrieren in den mount options abschalten um es performanter zu machen, vielleicht ist das der Fall?
Vancouver schrieb: > Unabhängige Regeln werden bei -j1 in der Reihenfolge abgearbeitet, wie > sie im Makefile stehen, richtig? Nein. Sie werden in der Reihenfolge ausgeführt, in der sie benötigt werden. Die Reihenfolge im Makefile spielt wie schon gesagt keine Rolle. Ein Makefile definiert keinen Sequenziellen Ablauf, auch nicht bei -j1. Beispiel:
1 | a: b c |
2 | |
3 | b: d |
4 | |
5 | c: |
6 | @echo "c" |
7 | |
8 | d: |
9 | @echo "d" |
c und d sind nicht von einander abhängig. Die Ausgabe ist aber:
1 | d |
2 | c |
>> Wie soll make durch "tieferes Analysieren" der Regeln wissen, was wovon > abhängig ist? > > make könnte sich diese Regel anschauen: > > b: c > cat a c > b > > und erkennen, dass neben der expliziten Abhängigkeit von c > offensichtlich auch noch a verwendet wird. Dazu müßte es wissen, dass an dieser Stelle a ein Dateiname sein soll. Das heißt, es müsste wissen, was die Kommandozeilenparameter von cat bedeuten. Anderes sehr änliches Beispiel:
1 | b: c |
2 | grep a c > b |
hier ist a keine Datei, sondern das Pattern, nach dem mit grep gesucht werden soll. Also müßte make auch grep kennen. Als nächstes kommt dann:
1 | b: c |
2 | meintollestool a c > b |
Und jetzt? Was ist a? > Oder viel einfacher, wenn eine Regel wegen einer fehlenden Abhängigkeit > einen Fehler liefert, könnte man sie zu einem späteren Zeitpunkt > wiederholen. Das ist Murks. > Mir ist (jetzt) schon klar, dass make explizite Abhängigkeiten braucht, > um immer korrekt zu funktionieren. Aber leider ist das bei vielen großen > Projekten nicht der Fall (Kernel, GNURadio, um nur zwei zu nennen), und > ich verspüre relativ wenig Lust, hunderte verschachtelte Makefiles zu > durchforsten. Natürlich nicht. Aber es ist dennoch kein Fehler in make, sondern einer in den Makefiles des Projekts.
Rene H. schrieb: > Weshalb nimmst Du nicht cmake? Das baut Dir ein funktionierendes > makefile mit allem drum und dran. Und dann lässt du cmake am besten noch ein ninja file generieren statt make (-GNinja), dann ist make ganz raus und alles ein gutes Stück schneller ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.