Entwickler-Ecke
Programmierwerkzeuge - MSBuild: Batchabbruch bei Fehler
Nersgatt - Di 08.07.14 10:35
Titel: MSBuild: Batchabbruch bei Fehler
Moin!
Ich verwende eine Batchdatei, um alle Projekte meiner Projektgruppe mit MSBuild zu erzeugen und im Anschluss ein Setup mit Innosetup auszuspucken.
Wenn nun beim Kompilieren einer Komponente etwas fehl schlägt, hätte ich gern, dass der gesamte Batchablauf abgebrochen wird. Jetzt wird einfach von MSBuild das nächste Projekt der Projektgruppe erzeugt und die eventuellen Fehlermeldungen verschwinden in der Konsole außerhalb des Sichtfeldes.
Ist es möglich, MSBuild irgendwie mitzuteilen, bei einem Fehler den Buildvorgang abzubrechen?
Danke!
Jens
Martok - Di 08.07.14 11:02
Meinst du auf der MSBuild-Seite oder im Batch?
Batchseitig wäre das "IF ERRORLEVEL 1" etc.
MSBuild hat da laut Tante Google wohl RunEachTargetSeparately="false" und StopOnFirstFailure="true" (so dass ein Fehler in einem Target alle abbricht), aber da kenn ich mich nicht aus. Makefiles haben das als Defaultverhalten ;)
Nersgatt - Di 08.07.14 11:17
Ich meine MSBuild-seitig.
Mit den Optionen komme ich nicht so recht weiter. Google spuckt nur Beiträge raus, wie diese Optionen in sln-Dateien eingebunden werden. Aber ich hab ja Delphi und nicht VS.
Mein Aufruf in der Batch sieht einfach so aus, dass ich die Projektgruppe übergebe: msbuild c:\Pfad\zur\Projektgruppe.groupproj /nologo /p:config=release
Ich hatte nun gehofft, dass man sowas wie StopOnFirstFailure als Parameter an msbuild übergeben kann. Aber in der Hilfe finde ich dazu nichts...
Martok - Di 08.07.14 11:29
So wie ich das lese ist das in Solutions sogar schwerer, die bauen davon immer erst Projekte. Dort dann als Attribute im MSBuild-Element des Targets. Keine Ahnung ob so eine Änderung Delphi laden+speichern überlebt...
Hast du mal eine Beispielprojektgruppendatei (was für ein Wort)?
Nersgatt - Di 08.07.14 11:49
Eine Projektgruppendatei sieht so aus:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <ProjectGuid>{7E408A96-2ED6-4B4F-A929-B212522A4284}</ProjectGuid> </PropertyGroup> <ItemGroup> <Projects Include="Project2.dproj"> <Dependencies/> </Projects> <Projects Include="Project3.dproj"> <Dependencies/> </Projects> </ItemGroup> <ProjectExtensions> <Borland.Personality>Default.Personality.12</Borland.Personality> <Borland.ProjectType/> <BorlandProject> <Default.Personality/> </BorlandProject> </ProjectExtensions> <Target Name="Project2"> <MSBuild Projects="Project2.dproj"/> </Target> <Target Name="Project2:Clean"> <MSBuild Projects="Project2.dproj" Targets="Clean"/> </Target> <Target Name="Project2:Make"> <MSBuild Projects="Project2.dproj" Targets="Make"/> </Target> <Target Name="Project3"> <MSBuild Projects="Project3.dproj"/> </Target> <Target Name="Project3:Clean"> <MSBuild Projects="Project3.dproj" Targets="Clean"/> </Target> <Target Name="Project3:Make"> <MSBuild Projects="Project3.dproj" Targets="Make"/> </Target> <Target Name="Build"> <CallTarget Targets="Project2;Project3"/> </Target> <Target Name="Clean"> <CallTarget Targets="Project2:Clean;Project3:Clean"/> </Target> <Target Name="Make"> <CallTarget Targets="Project2:Make;Project3:Make"/> </Target> <Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/> </Project> |
Ich hab mal versucht, hier die Optionen einzufügen:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9:
| <Target Name="Project2"> <MSBuild Projects="Project2.dproj" StopOnFirstFailure="true"/> </Target> <Target Name="Project2:Clean"> <MSBuild Projects="Project2.dproj" Targets="Clean" StopOnFirstFailure="true"/> </Target> <Target Name="Project2:Make"> <MSBuild Projects="Project2.dproj" Targets="Make" StopOnFirstFailure="true"/> </Target> |
Das hat sich aber überhaupt nicht auf das Verhalten von MSBuild ausgewirkt.
Martok - Di 08.07.14 12:56
So wie ich
das verstanden [
http://stackoverflow.com/a/5312401] hab, muss das da dran:
XML-Daten
1: 2: 3:
| <Target Name="Build" RunEachTargetSeparately="false"> <CallTarget Targets="Project2;Project3"/> </Target> |
Scheint das Makefile-Äquivalent von Abhängigkeiten vs. Direktaufruf zu sein.
Nersgatt - Di 08.07.14 13:02
Ne, nicht wirklich. Dann bricht MSBuild gleich mit einem Fehler ab:
Quelltext
1:
| error MSB4066: The attribute "RunEachTargetSeparately" in element <Target> is unrecognized. |
jaenicke - Di 08.07.14 13:09
Wir verwenden Jenkins und benutzen darin auch MSBuild um unsere Projekte zu erstellen. Wenn dort ein Fehler in einem Projekt der Projektgruppe auftritt, bricht der Build auch direkt ab.
Wie Jenkins das macht, weiß ich nicht, das habe ich mir nie angeschaut.
Die Projektdateien würde ich nicht manuell bearbeiten, da Delphi beim Auslesen und Ändern eher unvorhersehbare Ergebnisse liefert. Da dann jeweils mit Diffs herangehen zu müssen, nur weil man manuelle Änderungen drin hat, macht nur unnötig viel Arbeit.
Jenkins funktioniert sehr einfach und kümmert sich um den kompletten Build inkl. Fehleranalyse usw., wenn du das möchtest. Ich kann das nur empfehlen...
Nersgatt - Di 08.07.14 13:34
jaenicke hat folgendes geschrieben : |
Die Projektdateien würde ich nicht manuell bearbeiten, da Delphi beim Auslesen und Ändern eher unvorhersehbare Ergebnisse liefert. Da dann jeweils mit Diffs herangehen zu müssen, nur weil man manuelle Änderungen drin hat, macht nur unnötig viel Arbeit. |
Wenn das so geklappt hätte, ich mir kurz ein kleines Tools zusammengehackt, welches in einer Kopie der Projektdatei die nötigen Zeilen einfügt und damit dann MSBuild füttert.
Momentan behelfe ich mich halt damit, vorher die EXE-Dateien zu löschen. Dann schlägt spätestens der Innosetup-Compiler fehl, da er Dateien nicht findet, was ich dann mitbekomme.
Ralf Jansen - Di 08.07.14 13:52
Ich würde die bat Datei durch ein MSBuild proj Datei ersetzen. Wenn du dann dein ursprüngliches Project als BuildTarget hinzufügst solltest du dort dann StopOnFirstFailure einfach setzen können.
Zumindest mit einer Visual Studio Solution als Build Target funktioniert das.
In etwa
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build;Setup" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0"> <Target Name="Build"> <MSBuild Projects="DeineSolution.sln" Targets="Rebuild" Properties="DeineGewünschteKonfiguration" StopOnFirstFailure="true"/> </Target>
<Target Name="Setup"> <Exec Command=""$(MSBuildProgramFiles32)\Inno Setup 5\iscc.exe" deinLiebesInnoSetupSetup.iss" /> </Target> </Project> |
Nersgatt - Di 08.07.14 14:39
Ralf Jansen hat folgendes geschrieben : |
Ich würde die bat Datei durch ein MSBuild proj Datei ersetzen. Wenn du dann dein ursprüngliches Project als BuildTarget hinzufügst solltest du dort dann StopOnFirstFailure einfach setzen können. |
Oh, super, jetzt kommen wir der Sache näher. Diese Möglichkeit kannte ich nicht.
Es funktioniert jetzt, mit der Einschränkung, dass es nur dann geht, wenn ich in der .proj-Datei bei Projects=... alle Projekte einzeln angebe. Wenn ich die Projektgruppendatei angebe, macht er weiterhin bei einem Buildfehler eines einzelnen Projektes mit den anderen Projekten weiter.
Das sieht dann so aus:
Quelltext
1:
| <MSBuild Projects="./projekt1/projekt1.dproj;./projekt2/projekt2.dproj;./projekt3/projekt3.dproj" Properties="config=release" RunEachTargetSeparately="false" StopOnFirstFailure="true" ContinueOnError="false"/> |
Damit klappt es.
Ist zwar auch noch nicht schönste Lösung, aber schon nah dran. :zustimm:
jaenicke - Di 08.07.14 16:15
Wobei du dann immer noch das Auschecken usw. selber erledigen muss. Das alles würde dir Jenkins abnehmen. Zudem hättest du dann die Gewissheit, dass auch wirklich dein Stand im Repository so funktioniert und im Setup ist und du nicht lokal eine Datei vergessen hast einzuchecken usw. und Unittests kannst du z.B. auch automatisch vorher laufen lassen.
Denn das ggf. nicht saubere Projektverzeichnis ist bei der manuellen Lösung immer noch ein Problem, selbst wenn du einen Fehler beim Kompilieren dann am Ende mit den Änderungen siehst. Das ist genau der Grund weshalb ich meine Batch-Lösung nicht mehr weiterentwickelt habe.
Natürlich kann man das alles auch manuell in eine Batchdatei oder das MSBuild Projekt stecken... aber das ist finde ich unnötiger Aufwand und schlechter wartbar.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!