Msbuild解析对自定义项目类型的项目引用

时间:2013-03-15 16:24:57

标签: clojure msbuild

我为一种名为clojure的编程语言创建了一个自定义项目类型(cljproj而不是csproj)。当项目编译时,它会输出多个.dll文件以及一些相关的.clj文件。

这是通过覆盖cljproj文件中的默认CoreCompile目标来完成的。这基本上将需要编译的所有文件复制到bin目录,然后执行单独的应用程序来编译它们。

<Target Name="CoreCompile">
  <PropertyGroup>
    <ClojureNamespaces>@(Compile -> '%(RelativeDir)%(Filename)', ' ')</ClojureNamespaces>
  </PropertyGroup>
  <Copy SourceFiles="@(Compile)" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" DestinationFiles="@(Compile -> '$(OutDir)%(RelativeDir)%(Filename)%(Extension)')" />
  <Exec WorkingDirectory="$(OutDir)" Command="&quot;$(ClojureRuntimesDirectory)\$(ClojureVersion)\Clojure.Compile&quot; $(ClojureNamespaces.Replace('\', '.'))" />
</Target>

我已经从c#项目(csproj)添加了一个引用到我的clojure项目(cljproj)。

<ProjectReference Include="..\Clojure ASP.Net MVC Controller Library1\Clojure ASP.Net MVC Controller Library1.cljproj">
  <Project>{8fe1995b-4b6d-4911-b563-a759467fdf53}</Project>
  <Name>Clojure ASP.Net MVC Controller Library1</Name>
</ProjectReference>

默认情况下,Visual Studio无法正确解析项目引用,因为它假设只有一个输出,即Clojure ASP.Net MVC Controller Library1.dll。 实际输出文件的示例是MvcApplication1.Controllers.HomeController.dll和HomeController.clj

我想在不对C#.csproj文件进行任何更改的情况下完成这项工作,以便可以从任何.csproj文件中轻松引用.cljproj。

我尝试解决项目引用是通过覆盖GetTargetPath目标。

<Target Name="GetTargetPath" DependsOnTargets="$(GetTargetPathDependsOn)" Returns="@(TargetPath)">
  <ItemGroup>
    <TargetPath Include="$(TargetDir)\**\*.dll" />
    <!-- <TargetPath Include="$(TargetDir)\**\*.clj" /> -->
  </ItemGroup>
</Target>

如果我使用* .dll设置TargetPath,它将工作并将.dll文件复制到c#.csproj输出目录。它甚至将.pdb文件复制到该目录,尽管我没有将它们添加到TargetPath。但是,如果我取消注释* .clj TargetPath,CSC会抱怨.clj文件已损坏(可能是因为它们是纯文本,而不是.net程序集)。

我很高兴使用复制命令而不是覆盖TargetPath,但是我不确定将哪个变量用于目录输出,因为$(outdir)给了我自定义项目的bin(。 cljproj)不是试图解析项目引用(.csproj)的c#项目的bin。我不确定除了GetTargetPath之外还要覆盖哪个其他目标,因为在编译c#(。csjproj)项目时不会调用大多数clojure项目(.cljproj)目标,例如:.cljproj:仅在直接编译cljproj时调用AfterBuild,不是在编译.csproj时,它有一个项目引用.cljproj。

1 个答案:

答案 0 :(得分:2)

我可以通过覆盖GetCopyToOutputDirectoryItems目标来实现它。

<Target Name="GetCopyToOutputDirectoryItems" Returns="@(CopyToOutputDirectoryItemsWithTargetPath)">
  <ItemGroup>
    <CopyToOutputDirectoryItems Include="$(TargetDir)\**\*.clj">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </CopyToOutputDirectoryItems>
  </ItemGroup>
  <AssignTargetPath Files="@(CopyToOutputDirectoryItems)" RootFolder="$(TargetDir)">
    <Output TaskParameter="AssignedFiles" ItemName="CopyToOutputDirectoryItemsWithTargetPath" />
  </AssignTargetPath>
</Target>