8

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

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

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

我也尝试过构建 csproj 和解决方案,这似乎解决了 MonoDevelop 遇到的问题,但在解决单点触控程序集相关的其他问题上遇到了麻烦。我曾以为 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 用于 WinPhone 和 XBox360 项目时,这种变化似乎可以正常工作。这是应该工作的东西吗?有一个更好的方法吗?

谢谢,

4

1 回答 1

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 目标。它仍然处于试验阶段,新项目类型(MonoTouch 等)的构建代码是使用 MD 内部构建引擎编写的。

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

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

于 2012-04-30T03:48:04.597 回答