Вопрос

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

Это было полезно?

Решение

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

В наших проектах мы перемещаем скомпилированные библиотеки DLL в папки lib и размещаем файлы в соответствующих местах после завершения сборки.Для этого мы создали пользовательский файл build .target, который создает Target's, Property's, и 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 загрузить наш пользовательский скрипт сборки, затем добавляет скомпилированный файл в LibFiles ItemGroup и, наконец, связывает наши пользовательские цели сборки, DeleteLibFiles и CopyLibFiles, в процесс сборки.Мы настраиваем это для каждого проекта в нашем решении, поэтому удаляются / копируются только обновленные файлы, и каждый проект несет ответственность за свои собственные файлы (библиотеки DLL, изображения и т.д.).

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

Другие советы

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

Смотрели ли вы на события до и после сборки проекта?

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

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

Теперь, чтобы получить выходной путь для ссылки на него - к сожалению, когда вы добавляете строку типа "$(MySpecialPath)/Debug" в поле выходного пути и сохраняете проект, символы $ и () преобразуются в шестнадцатеричный, и ваш файл get помещается в каталог отладки под каталогом с именем "$(MySpecialPath)".Ааааа.Однако, если вы редактируете файл .csproj в текстовом редакторе, вы можете настроить это правильно, и, похоже, это работает до тех пор, пока тег <Import> отображается перед тегом <PropertyGroup> , содержащим путь вывода.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top