使用Mono和MonoDevelop对C#项目文件进行Mulitargeting

时间:2012-04-28 21:36:44

标签: msbuild mono monodevelop xbuild

我有一组csproj文件,它们都引用同一组源文件,但目标数据略有不同,因此我需要将项目文件分开。例如。有相同项目的WinPhone,XBox,桌面,MonoTouch变体。

对于真正重复的内容,比如要编译的.cs文件列表,我想将列表合并到一个文件中,这样我就不必确保所有变体都保持同步。我最初尝试通过从.csprojs中删除源并将它们放入由所有csprojs导入的.targets文件中来做到这一点,但这使得源文件从VS和MonoDevelop中消失。

我的第二次尝试是将桌面csproj文件作为主要文件,并让所有变体都使用某些条件逻辑导入csproj。这使得源文件可以从主csproj中编辑,并且它们构建成所有风格。现在,Visual Studio了解我尝试做的事情,但MonoDevelop无法构建它。在MonoDevelop解决方案中,核心DLL的iOS版本显示为灰色并显示“(未内置在活动配置中)”

我也试过xbuilding csproj和解决方案,它似乎已经解决了MonoDevelop所遇到的问题,但却解决了与解决monotouch程序集有关的其他问题。我原以为MonoDevelop使用的是xbuild,但也许没有?

由于这适用于Windows msbuild,因此它似乎是Mono中的错误或不受支持的功能。或者也许有更好的方法来解决整个场景...我想在这里问。

具体细节, 我的Core.iOS.csproj文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Project
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    DefaultTargets="Build"
    ToolsVersion="4.0" >
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>10.0.0</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AE37B15F-F4BE-48DE-9F20-F00A601EC89E}</ProjectGuid>
    <ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <AssemblyName>Core.iOS</AssemblyName>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="monotouch" />
  </ItemGroup>
  <Import Project=".\Core.csproj" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

我的Core.csproj文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Project
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    DefaultTargets="Build"
    ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Core</RootNamespace>
  </PropertyGroup>
  <!-- Using AssemblyName's presence to check for whether this is imported. --> 
  <PropertyGroup Condition=" '$(AssemblyName)' == '' ">
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{FC495BD8-11B1-46B0-A9DE-F245A0CBEE94}</ProjectGuid>
    <AssemblyName>Core</AssemblyName>
    <SignManifests>false</SignManifests>
  </PropertyGroup>

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <!-- properties similar to Debug -->
  </PropertyGroup>
  <ItemGroup Condition=" '$(Platform)' == 'AnyCPU' ">
    <Reference Include="System" />
    <Reference Include="System.Core" />
  </ItemGroup>
  <Import Condition=" '$(AssemblyName)' == 'Core' " Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <ItemGroup>
    <Compile Include="[...]" />
    <Compile Include="[...]" />
  </Project>

而且,正如我所说,当使用VS Express for WinPhone和XBox360项目时,这种变体似乎正常工作。这应该有用吗?有更好的方法吗?

谢谢,

1 个答案:

答案 0 :(得分:9)

简短回答:

这不起作用,因为虽然MonoDevelop使用MSBuild文件格式,但它并没有对所有项目类型使用真正的MSBuild / xbuild引擎。我建议使用链接而不是包含。

完整背景:

MonoDevelop有一个旧的内部构建引擎,它源自SharpDevelop 1.0构建引擎,即它早于MSBuild的存在。我们正在迁移到MSBuild,但这已经过了几个阶段,还没有完成。

几年前,MonoDevelop将其项目文件格式切换为与Visual Studio兼容的MSBuild子集。这是通过将已知的MSBuild属性和项目序列化/反序列化为MD的内部项目模型,但使用旧的构建引擎进行构建来完成的。这意味着任何仅使用可从Visual Studio UI访问的功能的MSBuild项目都可以正常工作。但是,它不支持只能通过手动编辑MSBuild XML来访问的更高级的MSBuild功能。

后来MD获得了使用xbuild / MSBuild构建引擎的实验性支持,但当时xbuild还不成熟,并且它没有所有项目类型的MSBuild目标。它仍然是实验性的,并且使用MD内部构建引擎编写了新项目类型(MonoTouch等)的构建代码。

Android中需要支持Mono for Android,因此必须拥有MSBuild目标。我们完成了xbuild和MonoDevelop的MSBuild引擎集成,而不是编写和维护两个构建引擎的构建代码,因此它可以用于Android项目的Mono。但是,我们无法在MD中默认启用xbuild构建引擎,因为许多其他项目类型还没有xbuild目标。相反,我们允许项目插件强制在每个项目类型的基础上使用xbuild引擎。

这基本上是当前状态 - xbuild引擎用于Android项目的Mono,以及较新的项目类型,如iPhone绑定项目和PLP项目,建议用于新项目类型。但是,在撰写本文时,尚未迁移MonoTouch,MonoMac,ASP.NET等较旧的项目类型。