Effektive Verwendung der Visual Studio-Projekteigenschaften für mehrere Projekte und Konfigurationen


70

Ich habe immer Visual Studios mit integrierter GUI-Unterstützung für die Konfiguration meiner Projekte verwendet, häufig mithilfe von Eigenschaftenblättern, sodass mehrere Projekte einen gemeinsamen Satz verwenden.

Einer meiner Hauptgründe dabei ist die Verwaltung mehrerer Projekte, Konfigurationen und Plattformen. Wenn Sie einfach alles mit der Haupt-GUI machen (klicken Sie mit der rechten Maustaste auf das Projekt -> Eigenschaften), wird es schnell zu einem Chaos, das schwer zu warten und anfällig für Fehler ist (z. B. wenn Sie ein Makro nicht richtig definieren oder die falsche Laufzeitbibliothek verwenden usw.). Umgang mit der Tatsache, dass verschiedene Leute dort Abhängigkeitsbibliotheken an verschiedenen Orten ablegen (z. B. meine leben alle in "C: \ Libs \ [C, C ++] \ [lib-name] \") und dann häufig die verschiedenen Versionen dieser Bibliotheken verwalten Auch anders (Release, Debug, x86, x64 usw.) ist ein großes Problem, da es die Zeit für die Einrichtung auf einem neuen System erheblich verkürzt. Dann gibt es Probleme mit der Versionskontrolle und der Trennung aller Pfade. .

Eigenschaftenblätter machen dies ein bisschen besser, aber ich kann nicht haben, dass ein Blatt separate Einstellungen für verschiedene Konfigurationen und Plattformen hat (die Dropdown-Felder sind ausgegraut), was dazu führt, dass ich viele Blätter habe, die, wenn sie in der richtigen Reihenfolge geerbt werden, das tun, was ich will ( "x86", "x64", "debug", "release", "common", "verzeichnisse" (behandelt das zuvor erwähnte Abhängigkeitsproblem durch Definieren von Benutzermakros wie BoostX86LibDir) usw.) und wenn in der falschen Reihenfolge geerbt (z "common" vor "x64" und "debug") führen zu Problemen wie dem Versuch, eine falsche Bibliotheksversion zu verknüpfen oder die Ausgabe falsch zu benennen ...

Was ich möchte, ist eine Möglichkeit, mit all diesen verstreuten Abhängigkeiten umzugehen und eine Reihe von "Regeln" einzurichten, die von allen meinen Projekten in der Lösung verwendet werden, beispielsweise die Benennung einer Ausgabebibliothek als "mylib- [vc90, vc100] - [x86" , x64] [- d] .lib ", ohne dies alles für jede einzelne Projekt-, Konfigurations- und Plattformkombination tun zu müssen, und halten Sie sie dann alle korrekt synchron.

Ich bin mir bewusst, dass ich auf völlig andere Systeme wie CMake umsteige, die die erforderlichen Dateien erstellen. Dies erschwert jedoch die Dinge an anderer Stelle, da selbst einfache Aufgaben wie das Hinzufügen einer neuen Datei zum Projekt zusätzliche Änderungen an anderer Stelle erfordern, was ich nicht bin Ich bin mit beiden völlig zufrieden, es sei denn, es gibt einige mit VS2010-Integration, die diese Art von Änderungen verfolgen können.


1
Ich fühle Ihren Schmerz: Wir haben über 600 vcprojs in unserem Produkt bei der Arbeit. :(
C Johnson

Antworten:


79

Ich habe gerade etwas herausgefunden, das ich nicht für möglich gehalten habe (es wird von der GUI nicht angezeigt), was dazu beiträgt, das Eigenschaftenblatt weitaus nützlicher zu machen. Das Attribut "Bedingung" vieler Tags in den Projekteigenschaftendateien kann auch in den .props-Dateien verwendet werden!

Ich habe gerade das Folgende als Test zusammengestellt und es hat großartig funktioniert und die Aufgabe von 5 (Common, x64, x86, Debug, Release) separaten Eigenschaftenblättern erledigt!

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="UserMacros">
    <!--debug suffix-->
    <DebugSuffix Condition="'$(Configuration)'=='Debug'">-d</DebugSuffix>
    <DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
    <!--platform-->
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform>
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform>
    <!--toolset-->
    <Toolset Condition="'$(PlatformToolset)' == 'v90'">vc90</Toolset>
    <Toolset Condition="'$(PlatformToolset)' == 'v100'">vc100</Toolset>
  </PropertyGroup>
  <!--target-->
  <PropertyGroup>
    <TargetName>$(ProjectName)-$(Toolset)-$(ShortPlatform)$(DebugSuffix)</TargetName>
  </PropertyGroup>
</Project>

Das einzige Problem ist, dass die Eigenschaften-GUI nicht damit umgehen kann. Ein Projekt, das das obige Eigenschaftenblatt verwendet, meldet nur geerbte Standardwerte wie "$ (ProjectName)" für das Ziel.


Ja, Eigenschaftenblätter sind in VS2k10 weitaus leistungsfähiger. Nur schade, dass nichts davon durch die IDE entlarvt wird. Ich habe etwas Ähnliches gemacht und es vereinfacht die Dinge wirklich.
Jalf

4
Wenn Sie erweiterte String-Funktionen benötigen, können Sie die System.String-Methoden verwenden: msdn.microsoft.com/en-us/library/… Beispiel: `<ShortHasRelPos> $ (Configuration.ToLower (). LastIndexOf ('rel') ) </ ShortHasRelPos>
Oliver Zendel

Wie kann ich diese Lösung anwenden? Wo soll ich es ablegen und wie kann ich Visual Studio mitteilen, dass ich es standardmäßig verwenden möchte?
user2023370

1
Ich habe es nie als "globalen Standard" ausgeführt, da es möglicherweise Probleme mit Projekten hat, die nicht meine eigenen sind (z. B. Bibliotheken von Drittanbietern und Beispielprojekte), obwohl die Standardeigenschaftsblätter irgendwo gespeichert sind (vergessen), die Sie bearbeiten können. Als solches habe ich sie einfach in mein Lösungsverzeichnis gestellt und dann im Visual Studio-Fenster "Property Manager" einfach "Vorhandenes Eigenschaftenblatt hinzufügen" verwendet (Sie können dort auch neue erstellen, aber die GUI bietet noch keine Möglichkeit, dies zu tun Grundlegende Plattform- / Konfigurationsbedingungen auf Eigenschaftenblättern). Dies funktioniert auch mit mehreren Entwicklern / Quellcodeverwaltung korrekt.
Fire Lancer

28

Ich habe einige Verbesserungen vorgenommen, kann für jemanden nützlich sein

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="UserMacros">
    <!--IsDebug: search for 'Debug' in Configuration-->
    <IsDebug>$([System.Convert]::ToString( $([System.Text.RegularExpressions.Regex]::IsMatch($(Configuration), '[Dd]ebug'))))</IsDebug>

    <!--ShortPlatform-->
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform>
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform>

    <!--build parameters-->
    <BUILD_DIR>$(registry:HKEY_CURRENT_USER\Software\MyCompany\@BUILD_DIR)</BUILD_DIR>
  </PropertyGroup>

  <Choose>
    <When Condition="$([System.Convert]::ToBoolean($(IsDebug)))">
      <!-- debug macroses -->
      <PropertyGroup Label="UserMacros">
        <MyOutDirBase>Debug</MyOutDirBase>
        <DebugSuffix>-d</DebugSuffix>
      </PropertyGroup>
    </When>
    <Otherwise>
      <!-- other/release macroses -->
      <PropertyGroup Label="UserMacros">
        <MyOutDirBase>Release</MyOutDirBase>
        <DebugSuffix></DebugSuffix>
      </PropertyGroup>
    </Otherwise>
  </Choose>

  <Choose>
    <When Condition="Exists($(BUILD_DIR))">
      <PropertyGroup Label="UserMacros">
        <MyOutDir>$(BUILD_DIR)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir>
        <MyIntDir>$(BUILD_DIR)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup Label="UserMacros">
        <MyOutDir>$(SolutionDir)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir>
        <MyIntDir>$(SolutionDir)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir>
      </PropertyGroup>
    </Otherwise>
  </Choose>

  <PropertyGroup>
    <OutDir>$(MyOutDir)</OutDir>
    <IntDir>$(MyIntDir)</IntDir>
<!-- some common for projects
    <CharacterSet>Unicode</CharacterSet>
    <LinkIncremental>false</LinkIncremental>
--> 
  </PropertyGroup>
</Project>

habe Spaß!


Wann wird dies ausgewertet? Beim Laden des Projekts? Ich möchte einem Eigenschaftenblatt benutzerdefinierte Kopierregeln nach dem Erstellen hinzufügen, um nur DLLs zu kopieren, die tatsächlich mit dem Projekt verknüpft wurden. Glaubst du, das wäre möglich?
Bim

Bim, ich denke, es wird vor dem Build ausgewertet, da es Variablen aus der Registrierung liest (siehe $ (Registrierung: Schlüssel)).
Lunicon

12

Ich hatte zuvor die gleichen Schmerzen für das Produkt meiner Firma (über 200 Projekte). Die Art und Weise, wie ich es gelöst habe, besteht darin, eine schöne Hierarchie der Eigenschaftenblätter zu erstellen.

Das Projekt erbt das Eigenschaftenblatt anhand seines Ausgabetyps, z. B. x64.Debug.Dynamic.Library.vsprops. Diese vsprops-Datei erbt einfach andere Eigenschaftenblätter mithilfe des InheritedPropertySheets-Attributs

<VisualStudioPropertySheet
    ProjectType="Visual C++"
    Version="8.00"
    Name="x64.Debug.Dynamic.Binary"
    InheritedPropertySheets=".\Common.vsprops;.\x64.vsprops;.\Debug.vsprops;.\Runtime.Debug.Dynamic.vsprops;.\Output.x64.Library.vsprops"
    >

Sie können auch Variablen (dh UserMacro, dessen Wert absolute oder sogar Umgebungsvariablen sein können) in Eigenschaftenblättern verwenden, um viele Dinge an Ihre Bedürfnisse anzupassen. Beispiel: Definieren einer BIN-Variablen in Debug.vsprops

<UserMacro name="BIN" Value="Debug" />

Wenn Sie dann den Ausgabenamen in der Reihe der vsprops festlegen, z. B. Output.x64.Library.vsprops

<VisualStudioPropertySheet
    ProjectType="Visual C++"
    Version="8.00"
    OutputDirectory="$(BIN)"
>

Die Variable $ (BIN) wird auf den festgelegten Wert erweitert (in diesem Fall Debug). Mit dieser Technik können Sie leicht eine schöne Hierarchie von Eigenschaftenblättern erstellen, um Ihre Anforderungen zu erfüllen.

Jetzt möchten Sie vielleicht noch etwas tun: Erstellen Sie Ihre eigenen Projektvorlagen, die Ihren Eigenschaftenblattsatz verwenden. Der wirklich schwierige Teil besteht darin, die ordnungsgemäße Verwendung der Vorlagen und Eigenschaftenblätter zu erzwingen. Meine persönliche Erfahrung ist, dass selbst wenn alles eingerichtet ist, jemand vergisst, die Vorlage zum Erstellen neuer Projekte zu verwenden ...


5

Es ist möglich, für jede Konfiguration ein separates Eigenschaftenblatt zu erstellen. Um dies zu tun:

  1. Erstellen Sie ein konfigurationsspezifisches Eigenschaftenblatt
  2. Öffnen Sie den Property Manager
  3. Klicken Sie mit der rechten Maustaste auf die Konfiguration (nicht auf das Projekt), die Sie ändern möchten
  4. Klicken Sie auf "Vorhandenes Eigenschaftenblatt hinzufügen" und fügen Sie Ihr Blatt hinzu

Dies erleichtert Ihnen das Einfügen von Bedingungen in ein einzelnes Blatt für mehrere Konfigurationen. Wenn Sie einige gemeinsame Attribute haben, die Sie zwischen Konfigurationen teilen möchten, erstellen Sie eine Hierarchie. Das oberste Blatt kann in allen Konfigurationen verwendet werden, und die verschachtelten Blätter enthalten nur das konfigurationsspezifische Attribut


PERFEKT! Vielen Dank. So können Sie auch in jedem Konfigurationsknoten neue Seiten erstellen. Es ist einfach, in die Falle zu geraten, die freigegebene Seite zu bearbeiten, was sich auf alle Konfigurationen auswirkt, obwohl auf sie unter jedem Konfigurationsknoten zugegriffen wird.
Justin

4

In Bezug auf die Ausgabebibliothek können Sie alle Ihre Projekte auswählen, dann die Eigenschaftenseiten aufrufen, Alle Konfigurationen, Alle Plattformen auswählen und dann den Zielnamen auf Folgendes festlegen:

$(ProjectName)-$(PlatformToolset)-$(PlatformShortName)-$(Configuration)

Dies würde eine Ausgabe wie mylib-v100-x86-Debug.lib ergeben

Ähnliches tun wir auch für zusätzliche Bibliotheksverzeichnisse, indem wir die richtigen Bibliothekspfade verwenden $(PlatformName)und #(Configuration)auswählen, obwohl dies ein gewisses Durcheinander bei der Ersteinrichtung der Bibliotheken bedeutet. zB haben wir Boost installiert seine Bibliotheken auf boost/lib.Win32oder boost/lib.x64.


In Bezug auf Bibliotheken und Personen, die sie an verschiedenen Orten installieren, gibt es mehrere Optionen. Wenn Sie über ein sehr robustes Versionsverwaltungssystem verfügen, können Sie einfach alles in die Versionsverwaltung einfügen und sich in einem libs-Ordner neben Ihrer Quelle befinden. Das wird wahrscheinlich nicht funktionieren, wenn Sie mehr als ein paar Bibliotheken verwenden oder wenn sie besonders groß sind.

Die andere Option, die LIB_ROOT=c:\librariesIhnen in den Sinn kommt, besteht darin, auf jedem Benutzercomputer eine Umgebungsvariable festzulegen, die beispielsweise auf das Stammverzeichnis des Bibliotheksordners verweist , und auf die Sie dann in Visual Studio als zugreifen können$(LIB_ROOT) .


Ich habe schon einige Dinge wie diese ein bisschen gemacht, aber dann gibt es Bibliotheken, die etwas anderes in ihren Namen verwenden (z. B. opt anstelle von release, -d anstelle von -Debug) usw., was immer noch viele spezielle Regeln erfordert (mein Debug .props und release.props richten Benutzermakros ein, um dies zu unterstützen, wobei common.props tatsächlich die include / lib-Pfade festlegt. Hatte es nicht mit Boost in Betracht gezogen, gute Idee (sei noch schöner, wenn die automatische Verknüpfung nicht die gleichen Namen für x86- und x64-Builds verwendet, aber die Boost.build-Leute scheinen nicht zu glauben, dass es ein Problem ist)
Fire Lancer

Ich denke, Ihr PlatformShortName stammt von x86.props und x64.props, die korrekt vererbt werden müssen oder so, oder ist es nur undokumentiert?
Fire Lancer

@ Fire Lancer: Um ehrlich zu sein, bin ich mir nicht sicher, woher PlatformShortName kommt. Ich denke, es muss ein eingebautes sein, weil wir nichts Besonderes in unseren Immobilienblättern haben.
Ngoozeff

1
@FireLancer: Wir haben das Boost-Build-Skript gehackt, um die Plattform in den lib-Namen aufzunehmen. Es erfordert zwar eine benutzerdefinierte, boost_version.haber die automatische Verknüpfung funktioniert wie ein Zauber. Wir müssen nur die boost.propsDatei zu einem Projekt hinzufügen und können loslegen. Natürlich hatten wir über Bedingungen in Requisiten-Dateien gewusst, die ein besserer Weg gewesen sein könnten. Auf jeden Fall weniger schmerzhaft.
Andreas Magnusson

0

Es hört sich so an, als ob es sich lohnen könnte, ein Build-Tool auszuprobieren. Bei mir verwenden wir ein maßgeschneidertes Tool, das Dateien und Projekte auf Änderungen überwacht und die Abhängigkeiten und die Kompilierungsreihenfolge berechnet. Das Hinzufügen einer neuen Datei ist keine große Sache - die Kompilierung erfolgt mit msbuild.

Wenn ich mehr als eine Reihe von Projekten kompilieren müsste, würde ich so etwas wie nant verwenden: http://nant.sourceforge.net/

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.