none
Gemeinsame Präprozessor-Direktiven RRS feed

  • Frage

  • Ich hahe eine Solution, in der sich ein ASP.NET und ein WinForms Projekt
    befinden, beides C#. Beide sollen in Abhängikeit von bestimmten
    #define's kompiliert werden, so dass sie nachher zusammen passen. Eine
    Änderung an einer zentralen Stelle soll sich konsistent auf beide
    auswirken. So wie man das in C/C++ per #include xyz.h machen würde.
     
    Jetzt ist die Frage, wo diese zentrale Stelle ist?
     
    TIA,
    Hajü
     
    Samstag, 19. Mai 2012 15:20

Antworten

  • Hallo Hajü,

    die gibt es in der Form nicht.
    #define gilt nur für die Quelldatei in der sie definiert wird.
    Zudem kann man je Projekt über Erstellen, Symbole für bedingte Kompilierung Direktiven für alle Dateien eines Projekts festlegen.
    (und dies kann man für alle Konfigurationen oder auch nur einzelne tun).
    Für eine Projektmappe (Solution) übergreifende Einträge gibt es nicht, da eine Projektmappe nur eine Zusammenfassung von Projekten darstellt.

    Gruß Elmar

    • Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
    Samstag, 19. Mai 2012 17:56
    Beantworter
  • Hallo Hajü,

    Das kannst  Du m.E. nur über MSBuild erreichen, und zwar über

    /p:DefineConstants=<DEFINE_SYMBOL>

    Das Gute daran, ist dass die so definierten "Symbole für bedingte Kompilierung" die in den einzelnen csproj-Dateien definierten Symbole überschreiben. Ein Beispiel für ein MSBuild-Skript, welches das Solution-Build ersetzt, findest Du hier.

    Gruß
    Marcel

    • Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
    Sonntag, 20. Mai 2012 05:57
    Moderator

Alle Antworten

  • Hallo Hajü,

    die gibt es in der Form nicht.
    #define gilt nur für die Quelldatei in der sie definiert wird.
    Zudem kann man je Projekt über Erstellen, Symbole für bedingte Kompilierung Direktiven für alle Dateien eines Projekts festlegen.
    (und dies kann man für alle Konfigurationen oder auch nur einzelne tun).
    Für eine Projektmappe (Solution) übergreifende Einträge gibt es nicht, da eine Projektmappe nur eine Zusammenfassung von Projekten darstellt.

    Gruß Elmar

    • Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
    Samstag, 19. Mai 2012 17:56
    Beantworter
  • Hallo Hajü,

    Das kannst  Du m.E. nur über MSBuild erreichen, und zwar über

    /p:DefineConstants=<DEFINE_SYMBOL>

    Das Gute daran, ist dass die so definierten "Symbole für bedingte Kompilierung" die in den einzelnen csproj-Dateien definierten Symbole überschreiben. Ein Beispiel für ein MSBuild-Skript, welches das Solution-Build ersetzt, findest Du hier.

    Gruß
    Marcel

    • Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
    Sonntag, 20. Mai 2012 05:57
    Moderator
  • Hallo Marcel,

    zum gleichen Resultat käme man über mehrere Build-Konfigurationen.
    Was vermutlich günstiger ist, da sich i. a. weitere Angaben ändern, wie z. B. Ausgabepfade.
    Siehe auch den letzten Absatz im verlinkten Blog Artikel

    Gruß Elmar

    Sonntag, 20. Mai 2012 08:42
    Beantworter
  • Hallo Elmar,

    Die Idee mit den mehrfachen Build-Konfigurationen finde ich gut. Wir beziehen uns auf den selben Autor, Sayed Ibrahim Hashimi, und auf dieselbe Technologie: MSBuild. Es gibt hier verschiedene Ansätze, und jeder Ansatz hat selbstredend seine Vor- und Nachteile. DefineConstants kann natürlich sowohl von der Befehlszeile als auch innerhalb des MSBuild-Skripts gesetzt werden, wichtig für mich war die Feststellung, dass es außerhalb der visuellen Projekt-Properties von Visual Studio eine Möglichkeit gibt, den Build von mehreren Projekten auf einfache Weise zu steuern. Auch Ausgabepfade können im MSBuild-Projekt in Abhängigkeit von Konstanten/Bedingungen gesetzt werden.

    Für die Leser unsers Threads erlaube ich mir noch zwei kleine Dokumentations-Hinweise zum Schluss (falls einer mal Lust auf mehr MSBuild hat):

    1. Thorsten Hans - MSBuild – Ein Überblick.
    2. Sayed Ibrahim Hashimi & William Bartholomew - Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build (2nd ed.), Microsoft Press 2010.

    Viele Grüße
    Marcel

    Sonntag, 20. Mai 2012 10:21
    Moderator
  • Danke für eure Antworten, auch an Elmar. Also. ich finde das schade dass das #include Konzept über Bord geflogen ist. Weiß jemand warum, das war doch so schön einfach und variabel? Die Erstzlösung finde ich etwas umständlich. Wobei bei mir das WinForms Projekt eh nur in der Entwicklungsphase als Kommunikationspartner zum Testen des ASP Projektes dient und früher oder später sowieso rausfliegt.

    Hajü

    Sonntag, 20. Mai 2012 14:04
  • Hallo Hajü,

    naja, einfach nur solange wie alles glatt läuft...
    Wenn man dann die Testmatrix für solchen Code betrachtet, ist schon nicht mehr so einfach.
    Und ohne diese hat es der Compiler leichter, z. B. Eric Lippert dazu:
    http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx

    In einer Objekt-orientierten Umgebung sollte man es nicht brauchen, auch wenn es Grenzfälle gibt -
    z. B. bei gemeinsamen Code für WPF / Silverlight oder Windows / Mono.

    Gruß Elmar

    Sonntag, 20. Mai 2012 14:57
    Beantworter
  • Hallo Hajü

    Dies war ein ein wesentliche Entscheidung im Sprachkonzept!
    Der Verzicht auf #include-Dateien (pus div preprocessor)
    ist IMHO sehr positiv zu werten. Lies folgende Blogs:


    why doesn’t C# need header files?
    http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx

    Why doesn't C# support #define macros?
    http://blogs.msdn.com/b/csharpfaq/archive/2004/03/09/why-doesn-t-c-support-define-macros.aspx


    C++
    Header files and the preprocessor - Can't Live With 'em, Can't Live Without 'em
    http://blogs.msdn.com/b/vcblog/archive/2007/04/19/header-files-and-the-preprocessor-can-t-live-with-em-can-t-live-without-em.aspx

    Stop writing header files
    http://blogs.msdn.com/b/devdev/archive/2005/08/19/453891.aspx


    PS
    evtl. eine Art Teilersatz wäre uU noch mit 'partial' machbar.

    Sonntag, 20. Mai 2012 14:59
  • Am 20.05.2012 16:59, schrieb Thomas Scheidegger Dev:
    > Der Verzicht auf #include-Dateien (pus div preprocessor)
    > ist IMHO sehr positiv zu werten. Lies folgende Blogs:
     
    Das ist alles diskutierbar. Ich glaube bei der Definition von C++ war
    die Abwärtskompatibilität zu C ein wesentlicher Faktor, während bei C#
    die OOP im Vordergrund stand. Und, wie Elmar sagte, es gibt immer
    Grenzfälle.
     
    Hajü
     
    Montag, 21. Mai 2012 05:31
  • Hallo Hajü,

    C# ist trotz dem großen C am Anfang keine Fortführung von C++, auch wenn einiges daran erinnert. C#  lebt in einem .NET-Biotop, dem die common language infrastructure zugrunde liegt. Es gehört zur Philosophie von C#, Abhängigkeiten zwischen Anwendungen auf der Symbolebene und nicht auf der Code-Ebene aufzulösen. Eines der Gründe dafür ist es, Barrieren zwischen Anwendungen aufzuheben, die in verschiedenen .NET-Sprachen geschrieben werden. Aus der C#-Spezifikation:

    The program does not use #include to import program text. Dependencies among programs are
    handled symbolically rather than textually. This approach eliminates barriers between applications
    written using multiple languages. For example, the Console class need not be written in C#.

    Es gibt wie immer ein für und wider, in den meisten Fällen dürfte man mit #if #else #endif bzw. mit ConditionalAttribute weiterkommen. Sonst bleibt noch die Wiederverwendbarkeit auf Symbolebene (IL-Ebene).

    Gruß
    Marcel

    Montag, 21. Mai 2012 05:56
    Moderator