MSBuild - как преобразовать% (Compile.Identity) в имя файла с другим расширением? - PullRequest
0 голосов
/ 10 мая 2018

Я вроде изучаю MsBuild. В качестве практической работы я подготовил файл * .proj для создания простого приложения C ++ «здравствуй, мир». Все шло хорошо, но потом я потерпел неудачу после того, как я добавил одну строку в цель «Компилировать» - я не могу найти, как заставить ее подготовить список файлов * .obj для использования компоновщиком.

Примечание: * Microsoft (R) Build Engine версии 4.7.2558.0 (это просто MsBuild.exe из каталога "C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319").

Вот мой * .proj файл:

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">

        <PropertyGroup>
            <SourceDir>D:\BuildProc\cpp1</SourceDir>

            <OutputPath>$(MSBuildProjectDirectory)\Bin\</OutputPath>
            <ExecutableName>MyCppSample</ExecutableName>
            [...]       
        </PropertyGroup>

        <ItemGroup>
            <Compile Include="hello.cpp"/>
            <Compile Include="main.cpp"/>
        </ItemGroup>

        <Target Name="Build" DependsOnTargets="CopyFiles;Compile;Link"
            Inputs="@(Compile)" 
            Outputs="$(OutputPath)$(ExecutableName).exe">

            <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
        </Target>

        <Target Name="CopyFiles" 
            Inputs="@(Compile->'$(SourceDir)\%(Filename)%(Extension)')" 
            Outputs="@(Compile->'$(OutputPath)\%(Filename)%(Extension)')">

            <Copy SourceFiles="@(Compile->'$(SourceDir)\%(Filename)%(Extension)')" DestinationFolder="$(OutputPath)" />
        </Target>

        <Target Name="Compile" 
            Inputs="@(Compile->'$(OutputPath)\%(Filename)%(Extension)')" 
            Outputs="@(Compile->'$(OutputPath)\%(Filename).obj')">

            <Exec Command="@echo === %(Compile.Identity)" />
            <ExecEx Filename="cl" Arguments="%(Compile.Identity) $(CLOptions) -I$(SourceDir)" WorkingDir="bin" />

            <!-- here it fail! :-( -->
            <Exec Command="echo %(Compile.Identity->'%(Filename).obj') >> $(OutputPath)\$(ExecutableName).link " />

        </Target>

        <Target Name="Link" 
            Inputs="@(Compile->'$(OutputPath)\%(Filename).obj')" 
            Outputs="$(OutputPath)\$(ExecutableName).exe">      

            <Exec Command="@echo === Linking..." />
            <ExecEx Filename="link" Arguments="$(LibPath) $(Libs) $(LinkOptions) @$(ExecutableName).link" WorkingDir="bin" />
        </Target>

    </Project>

Примечание: - это простая задача MsBuild, разработанная мной. Это простая оболочка для классов .NET ProcessStartInfo и Process. Работает нормально.

Цели чистые, CopeFiles работают нормально. Target Compile также работал нормально, прежде чем я добавил команду echo с перенаправлением в файл * .link.

Проблема в том, что он начинает сообщать об ошибке в цели компиляции после того, как я добавил echo в * .link файл:

Сообщение об ошибке:

D: \ BuildProc \ msbld06 \ build06.proj (73,9): ошибка MSB4095: на метаданные элемента% (имя файла) ссылаются без имени элемента. Укажите th Имя элемента, используя% (itemname.Filename).

А в моем файле * .proj есть строка, которая приводит к упомянутой ошибке:

<Exec Command="echo %(Compile.Identity->'%(Filename).obj') >> $(OutputPath)\$(ExecutableName).link " />

Итак, мне нужно как-то вывести {filename} .obj в файл $ (OutputPath) \ $ (ExecutableName) .link, а затем использовать этот файл в качестве @ -параметра для компоновщика. Я пытался использовать другие формы, но все не удалось. Итак, в поисках подсказки ...

В этом случае для меня гораздо важнее понять - как добиться этого с преобразованием точно из% (Compile.Identity), если это вообще возможно. И только в качестве второго шага, возможно, вы можете порекомендовать другой способ сделать то же самое (моя идея не в том, чтобы использовать Microsoft.Cpp.targets или другие включаемые файлы, я хочу сделать это только с пустой / чистой установкой MsBuild).

Спасибо.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Самый простой способ выполнить то, что вы хотите сделать, это использовать задачу WriteLinesToFile :

<WriteLinesToFile Lines="@(Compile->'%(Filename).obj')" File="$(OutputPath)$(ExecutableName).link" Overwrite="true" />
0 голосов
/ 10 мая 2018

Компиляция - это ItemGroup, поэтому вы должны ссылаться на нее @, а не%.Попробуйте следовать

<Exec Command="echo @(Compile)->%(Filename).obj >> $(OutputPath)$(ExecutableName).link" />
...