简体   繁体   中英

.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?

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

For people who've stumbled across this question looking for help, follow Adam Sitnik's answer. For the vast majority of use cases, the solution is just to switch from csproj to xproj, so your project.json file can target multiple frameworks.

Alas, for my situation (which was to use Windows Runtime APIs from my library), that unfortunately wasn't possible, since project.json has no built-in ways to access the WinRT APIs even when you are compiling for their target framework. For example, if you do this:

"frameworks": {
    ".NETPortable,Version=v4.6,Profile32": {
        "frameworkAssemblies": {
            "Windows": { "type": "build" }
        }
    }
}

it won't compile, although the compiler will happily find assemblies like System.Runtime or System.Linq for you.

I ended up raising an issue about this on the CoreFX repo here . It seems that the way the CoreFX team does this (for example you will find multiple project.jsons in a project like this ) is by creating a custom MSBuild task that allows them to override the project.json, which they store the code for in their buildtools repo.

I wasn't really up to creating my own MSBuild task nor using the .NET build tools to build my own repo, so I ended up just creating multiple csproj files the old-fashioned way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM