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

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

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

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

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

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

Ответ 1

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

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

<?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, проект, который использует вышеприведенный лист свойств, просто передает по умолчанию унаследованные значения, такие как "$ (имя_проекта)" для цели.

Ответ 2

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

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

получайте удовольствие!

Ответ 3

У меня была такая же боль для продукта моей компании (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). Используйте эту технику, вы можете легко построить красивую иерархию листов свойств для удовлетворения вашего спроса.

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

Ответ 4

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

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

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

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


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

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

Ответ 5

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

  • Создать спецификацию свойств конфигурации
  • Откройте диспетчер свойств
  • Щелкните правой кнопкой мыши конфигурацию (а не проект), которую вы хотите изменить
  • Нажмите "Добавить существующий лист свойств" и добавьте свой лист

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

Ответ 6

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

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