Эффективное использование свойств проекта Visual Studio для нескольких проектов и конфигураций - PullRequest
69 голосов
/ 17 августа 2010

Я всегда использовал Visual Studios, встроенную в поддержку графического интерфейса, для настройки своих проектов, часто используя таблицы свойств, чтобы несколько проектов использовали общий набор.

Один из моих главных недостатков - управление несколькими проектами, конфигурациями и платформами. Если вы просто делаете все с помощью основного графического интерфейса пользователя (щелкните правой кнопкой мыши проект -> свойства), он быстро становится беспорядочным, сложным в обслуживании и подверженным ошибкам (например, не удается правильно определить какой-либо макрос или использовать неправильную библиотеку времени выполнения и т. Д.). Имея дело с тем, что разные люди помещают туда библиотеки зависимостей в разных местах (например, мои все живут в "C: \ Libs \ [C, C ++] \ [lib-name] \"), а затем часто управляют разными версиями этих библиотек по-разному (выпуск, отладка, x86, x64 и т. д.) также представляет собой большую проблему, поскольку это значительно усложняет время для его установки в новой системе, а также возникают проблемы с управлением версиями и разделением путей каждого .. .

Листы свойств делают это немного лучше, но у меня не может быть одного листа с отдельными настройками для разных конфигураций и платформ (выпадающие списки выделены серым цветом), в результате чего у меня много листов, которые, если унаследованы в правильном порядке, делают то, что Я хочу ("x86", "x64", "debug", "release", "common", "directoryies" (имеет дело с ранее упомянутой проблемой зависимости путем определения пользовательских макросов, таких как BoostX86LibDir) и т. Д.), И если наследуется неправильно порядок (например, «общий» перед «x64» и «отладка») приводит к таким проблемам, как попытка связать неверную версию библиотеки или неправильное присвоение имени выходному результату ...

Мне нужен способ справиться со всеми этими разбросанными зависимостями и настроить набор «правил», которые используются всеми моими проектами в решении, например, назвать библиотеку вывода как «mylib- [vc90, vc100] - [x86, x64] [- d] .lib ", без необходимости делать все это для каждого отдельного проекта, конфигурации и комбинации платформы, а затем синхронизировать их все правильно.

Мне известно о переходе на совершенно другие системы, такие как CMake, которые создают необходимые файлы, однако это затем усложняет ситуацию в другом месте, делая даже такие простые задачи, как добавление нового файла в проект, в других местах, а это не требует дополнительных изменений в другом месте, чего не происходит. что-то, чем я полностью доволен, разве что есть некоторые с интеграцией VS2010, которые могут отслеживать изменения такого рода.

Ответы [ 6 ]

77 голосов
/ 17 августа 2010

Я только что узнал что-то, что, по моему мнению, было невозможно (оно не отображается в графическом интерфейсе), что помогает сделать список свойств гораздо более полезным. Атрибут «Condition» многих тегов в файлах свойств проекта, и его также можно использовать в файлах .props!

Я просто собрал следующее в качестве теста, и он отлично работал и выполнил задачу 5 (общие, x64, x86, отладка, выпуск) отдельных листов свойств!

<?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>

Единственная проблема заключается в том, что GUI свойств не может справиться с этим, проект, использующий приведенный выше лист свойств, просто сообщает по умолчанию унаследованные значения, такие как $ (ProjectName) для цели.

27 голосов
/ 04 февраля 2011

Я сделал некоторые улучшения, может быть кому-нибудь пригодится

<?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>

веселись!

11 голосов
/ 11 января 2011

Раньше у меня была такая же боль за продукт моей компании (более 200 проектов). Я решил, как построить хорошую иерархию списков свойств.

Проекты наследуют таблицу свойств по типу вывода, например, x64.Debug.Dynamic.Library.vsprops. Этот файл vsprops просто наследует другие листы свойств, используя атрибут InheritedPropertySheets

<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"
    >

Вы также можете использовать переменные (т. Е. UserMacro, чье значение может быть абсолютным или даже переменные окружения) в таблицах свойств, чтобы настроить множество вещей в зависимости от ваших потребностей. Например, определение переменной BIN в Debug.vsprops

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

затем, когда вы устанавливаете имя вывода в серии vsprops, скажем, Output.x64.Library.vsprops

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

Переменная $ (BIN) будет расширена до установленного значения (в данном случае Debug). Используя эту технику, вы можете легко построить хорошую иерархию списков свойств, чтобы удовлетворить ваши требования.

Теперь есть еще одна вещь, которую вы можете сделать: создать свои собственные шаблоны проектов, которые используют ваш набор свойств. Действительно сложная задача - обеспечить правильное использование шаблонов и таблиц свойств. Мой личный опыт показывает, что даже если все настроено, кто-то все равно забудет использовать шаблон для создания новых проектов ...

5 голосов
/ 16 апреля 2012

Можно создать отдельный лист свойств для каждой конфигурации. Для этого:

  1. Создание таблицы свойств для конкретной конфигурации
  2. Открыть менеджер по недвижимости
  3. Щелкните правой кнопкой мыши конфигурацию (не проект), которую вы хотите изменить
  4. Нажмите «Добавить существующий список свойств» и добавьте свой лист

Это освобождает вас от вставки условий в один лист для нескольких конфигураций. Если у вас есть общие атрибуты, которые вы хотели бы использовать в разных конфигурациях, создайте иерархию. Верхний лист можно использовать во всех конфигурациях, а вложенные листы будут содержать только атрибут, относящийся к конфигурации

4 голосов
/ 17 августа 2010

Что касается выходной библиотеки, вы можете выбрать все свои проекты, затем вызвать страницы свойств, выбрать Все конфигурации, Все платформы, а затем установить имя цели:

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

, который выдает вывод, подобный mylib-v100-x86-Debug.lib

Мы делаем нечто похожее на это и для каталогов дополнительных библиотек, используя $(PlatformName) и #(Configuration), чтобы выбратьправильные пути к библиотекам, хотя это означает, что нужно немного поработать с начальной настройкой библиотек.например, у нас есть boost, устанавливающий его библиотеки на boost/lib.Win32 или boost/lib.x64.


Что касается библиотек и людей, устанавливающих их в разных местах, есть несколько вариантов.Если у вас очень надежная система управления версиями, вы можете просто поместить все в систему управления версиями, находясь в папке libs рядом с вашим источником.Это, вероятно, не сработает, если вы используете более нескольких библиотек, или если они особенно велики.

Другой вариант, который приходит на ум, - это установить переменную окружения на каждой пользовательской машине, которая указывает накорневой каталог их библиотек, например, LIB_ROOT=c:\libraries, и вы можете получить к нему доступ в Visual Studio как $(LIB_ROOT).

0 голосов
/ 13 января 2011

Звучит так, как будто стоит проверить инструмент сборки - у меня дома мы используем специальный инструмент, который отслеживает изменения файлов и проектов и вычисляет зависимости и порядок компиляции.Добавление нового файла не представляет особой проблемы - компиляция выполняется с помощью msbuild.

Если бы мне пришлось компилировать больше, чем несколько проектов, я бы использовал что-то вроде nant: http://nant.sourceforge.net/

...