Search code examples
c#.netmsbuildasp.net-corednx

.NET Core + MSBuild: How to associate a csproj with multiple project.json files?


edit 3: Looks like what I'm trying to do isn't supported; it isn't actually possible to 'share' project.json files across configurations. I'm supplanting this question with How to point to a different project.json location in a .NET Core PCL?

edit 2: Yep, my suspicions were correct. ProjectJson and ProjectLockJson aren't actually special MSBuild properties, their values were being used in another imported MSBuild project to do the actual work. I'll post more on this (hopefully in the form of an answer) when I have an update.

edit: I've published the whole project to GitHub so you guys can get a repro. Just git clone the repository, open it up in VS, start building and you should hit the error.

Original Post

I'm trying to create a portable class library based on .NET Core. I'm having trouble associating multiple project.json files with my csproj. Here is my directory structure:

LibFoo
|
---- LibFoo.csproj
|
---- project.json
|
---- Platforms
     |
     ---- Net45
     |    |
     |    ---- project.json
     |
     ---- Profile32
          |
          ---- project.json

I have two MSBuild platforms (excluding AnyCPU), Net45 and Profile32. Basically, when it's set to .NET Framework 4.5, I want it to compile include the project.json in the root directory, and the project.json in Platforms/Net45. When it's set to Profile32, I want it to do that with the project.json in Platforms/Profile32.

My question is, how can I get this to work in MSBuild? Here's the relevant snippet of my csproj file:

<ItemGroup Condition=" '$(Platform)' == 'Net45' ">
  <!-- Target WPF apps -->
  <TargetPlatform Include=".NETFramework, Version=4.5" />
</ItemGroup>
<ItemGroup Condition=" '$(Platform)' == 'Profile32' ">
  <!-- Target Windows 8.1 Universal apps -->
  <TargetPlatform Include="Windows, Version=8.1" />
  <TargetPlatform Include="WindowsPhoneApp, Version=8.1" />
</ItemGroup>
<ItemGroup>
  <None Include="Platforms\Net45\project.json" />
  <None Include="Platforms\Profile32\project.json" />
</ItemGroup>
<PropertyGroup>
  <ProjectJsonRoot>Platforms\$(Platform)</ProjectJsonRoot>
  <ProjectJson>$(ProjectJsonRoot)\project.json</ProjectJson>
  <ProjectLockJson>$(ProjectJsonRoot)\project.lock.json</ProjectLockJson>
</PropertyGroup>
<ItemGroup>
  <!-- Include a common project.json for shared configs -->
  <None Include="project.json" />
</ItemGroup>

For some reason, the ProjectJson and ProjectLockJson parts don't seem to be working. I suspect they're the problem since I couldn't find any official docs for them on MSBuild, but CoreFX seems to be using it pretty successfully in their csproj files. Am I doing something wrong?


Solution

  • The thing is that you should just move from .csprojs to .xprojs. Then each .xproj can have single project.json that can target multiple frameworks.

    Great article: http://blog.marcgravell.com/2015/11/the-road-to-dnx-part-1.html

    Here is my sample: https://github.com/adamsitnik/BenchmarkDotNet