2008-08-28 2 views
4

Я только что закончил создание системы сборки на месте для существующего кода на C++, используя наследуемые листы свойств, которая, как представляется, специфична для продукта Visual C++. Для создания вне места требуется, чтобы многие параметры проекта были изменены, а наследуемые листы свойств позволили мне изменить все необходимые настройки, просто добавив лист свойств в проект. Я переношу нашу команду из C++/MFC для UI в C# и WPF, но мне нужно предоставить такую ​​же функциональность вне места, надеюсь, с таким же удобством. Я не могу найти способ сделать это с помощью проектов C#. Сначала я посмотрел, могу ли я ссылаться на файл целей MsBuild, но не смог найти способ сделать это. Я знаю, что могу просто использовать MsBuild для всего, но это кажется более сложным, чем необходимо. Есть ли способ определить макрос для каталога и использовать его в пути вывода, например?Нестандартные сборки с C#

ответ

3

Я не совсем уверен, что такое система сборки «вне места», но если вам просто нужна копия скомпилированных файлов (или других ресурсов) в другие каталоги, вы можете сделать это, привязавшись к цели сборки MSBuild.

В наших проектах мы перемещаем скомпилированные библиотеки DLL в папки lib и помещаем файлы в нужные места после завершения сборки. Для этого мы создали пользовательский файл сборки .target, который создает Target, Property и ItemGroup, которые мы затем используем для заполнения нашей внешней выходной папки.

Наш файл пользовательских целей выглядит как это:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
     <ProjectName>TheProject</ProjectName> 
     <ProjectDepthPath>..\..\</ProjectDepthPath> 
     <ProjectsLibFolder>..\..\lib\</ProjectsLibFolder> 

     <LibFolder>$(ProjectsLibFolder)$(ProjectName)\$(Configuration)\</LibFolder> 
    </PropertyGroup> 

    <Target Name="DeleteLibFiles"> 
     <Delete Files="@(LibFiles-> '$(ProjectDepthPath)$(LibFolder)%(filename)%(extension)')" TreatErrorsAsWarnings="true" /> 
    </Target> 
    <Target Name="CopyLibFiles"> 
     <Copy SourceFiles="@(LibFiles)" DestinationFolder="$(ProjectDepthPath)$(LibFolder)" SkipUnchangedFiles="True" /> 
    </Target> 

    <ItemGroup> 
     <LibFiles Include=" "> 
      <Visible>false</Visible> 
     </LibFiles> 
    </ItemGroup> 
</Project> 

Файл .csproj в Visual Studio, то интегрируется с этой системой пользовательского целевого файла:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="3.5" ... > 
    ... 
    <Import Project="..\..\..\..\build\OurBuildTargets.targets" /> 
     <ItemGroup> 
     <LibFiles Include="$(OutputPath)$(AssemblyName).dll"> 
      <Visible>false</Visible> 
     </LibFiles> 
     </ItemGroup> 
    <Target Name="BeforeClean" DependsOnTargets="DeleteLibFiles" /> 
    <Target Name="AfterBuild" DependsOnTargets="CopyLibFiles" /> 
</Project> 

В двух словах, это сценарий сборки сначала сообщает MSBuild загрузить наш скрипт пользовательской сборки, затем добавляет скомпилированный файл в ItemGroup LibFiles и, наконец, связывает наши пользовательские цели сборки, DeleteLibFiles и CopyLibFiles, в процесс сборки. Мы устанавливаем это для каждого проекта в нашем решении, поэтому только файлы, которые обновляются, удаляются/копируются, и каждый проект несет ответственность за свои собственные файлы (DLL, изображения и т. Д.).

Надеюсь, это поможет. Приносим извинения, если я неправильно понял, что вы подразумеваете под системой сборки вне места, и это совершенно бесполезно для вас!

0

Есть ли способ я могу определить макрос для каталога и использовать его в пути выхода

Вы смотрели на предварительной сборки и после сборки событий проекта?

0

Собственно, события предварительной сборки и пост-сборки, по-видимому, являются единственным местом для добавления команд типа пакетного файла. К сожалению, это не поможет мне создать стандартные каталоги сборки для наших проектов. И, имея эти события, создает пакетные файлы похоже на подход 1980-х годов для современного языка, такого как C#, IMO.

После того, как вы выкапываете еще несколько и экспериментируете, я обнаружил, что вы можете добавить директиву <Import> в ваш .csproj-файл. Когда вы это сделаете, в среде IDE появится диалоговое окно с предупреждением о том, что в вашем проекте есть небезопасная точка входа, но вы можете проигнорировать это, и вы можете сделать это вообще не отображающимся путем редактирования записи реестра. Таким образом, это даст мне способ получить переменные, содержащие пути к каталогам, которые мне нужны, в файл .csproj.

Теперь, чтобы получить ссылку на выход, к сожалению, когда вы добавляете строку «$ (MySpecialPath)/Debug» в поле «Выходной путь» и сохраняете проект, символы $ and() преобразуются в hex, и ваш файл get будет помещен в каталог Debug под каталогом «$ (MySpecialPath)». Arrgghh. Если вы отредактируете файл .csproj в текстовом редакторе, вы можете установить его правильно, но он, похоже, работает до тех пор, пока тег <Import> появится перед <PropertyGroup>, содержащим выходной путь.

Поэтому я считаю, что решение для меня будет состоять в том, чтобы создать стандартный файл OurTeam.targets MsBuild в стандартном расположении, добавить установщик для изменения реестра, чтобы он не отображал предупреждения, а затем создавать собственные шаблоны проектов, которые < Импортируйте файл >, а также установите путь вывода для использования свойств, определенных в файле OurTeam.targets. К сожалению, это больше работы и менее элегантное решение, чем механизм наследования свойств листа на C++.

Смежные вопросы