Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a single source project with full .net, PCL and dotnet core assemblies build from same C# source?

Update: This refers to an obsolete set of .net core tools built around project.json, this question and its answers are of very limited utility in current .net core toolsets like Visual Studio 2017+.

Using Visual Studio 2015, update 3, I am trying to find out the current limitations that exist that would prevent me from doing the following:

  1. For a single C# codebase, compile a full .net framework version and a PCL version, and a .net core class library from the same sources.

  2. Solution dir solutiondir\ will contain a src\ dir which contains a projectdir\ (Solutiondir\src\projectdir).

  3. Projectdir will contain a HelloWorldPCL class library which is built as a classic .net PCL project, and with other framework targets as well.

  4. From the same Projectdir the same HelloWorldPCL will also be compiled for .net 4.6 project.

  5. From the same Projectdir the same HelloWorldPCL will also be compiled for .net core.

  6. All of the output assemblies above will share access to a single set of C# code which may have some #if DOTNET and #if NET46 and #if PCL conditional defines to handle things which are not available in various frameworks/environments.

So far I can do most of the above, but when I try to have the Projectdir contain a .net core artifact like project.json or HelloWorldCore.xproj, the IDE gives me many errors if I try to create separate .csproj and .xproj projects in the same folder, so that appears not to be the right way to go.

With a working .csproj project when I introduce an .xproj and a project.json on disk, but we have not added these to the solution itself, they are just sitting there on the disk beside the Real Project Sources, I get a Nuget package restore error, which can only be made to go away by deleting the project.json file, so clearly it is not possible to have a .csproj in a project directory and also have a project.json folder. One must choose between project.json mode (.net core project style) and .csproj mode (classic C# project style).

I have built a "broken" codebase that demonstrates the impossibility of using a folder containing both a .csproj and a project.json and then trying to build the csproj and project.json project without them interfering:

https://bitbucket.org/wpostma/helloworldcoreandpcl

Question: is there ANY way to build a project from a single set of C# source files, and have as your targets, a full .net 4.6 assembly, and also a native .net core class library, and also a PCL assembly which might target any particular .net profile?

Objection: You may rightly ask "shouldn't you just use one PCL and have done with it, and forget targeting full .net or creating a separate .net core class library dll?". Maybe if the code could be built once, from a single source, without any conditional defines, and without any differences in functionality and if the limitations imposed by a lowest-common-denominator PCL "netstandard" profile approach were sufficient, you could. But what about the cases where that's not even possible?

Do we have to have some elaborate build process where we either copy project files or move source code around, in order to achieve single .cs source file target multiple .net profile nerdvana? Or am I overlooking alternative solutions?

Update: It appears there is a problem with the Visual Studio IDE that prevents you from directly adding a reference to a class library in your solution, when you build it with a project.json instead of using a .csproj. However the solution below specified by Jon indicates that you should build your project, then build a nuget package with dotnet pack. If you look at my modified demo here you can the pack.cmd file contains the steps I used to pack up a nuget package, and then locally "publish" it to a file (local directory) nuget feed for my own personal use.

like image 846
Warren P Avatar asked Jul 05 '16 14:07

Warren P


2 Answers

I would try to go for a pure project.json approach. For example, here's a project.json file which will build a single package which supports netstandard1.0, PCL profile 328, and .NET 4.6 - with each configuration defining its own symbols so you can have conditional code.

{
  "version": "1.0.0",

  "frameworks": {
    "net46": {
      "buildOptions": {
        "define": [ "NET46" ]
      }
    },

    "netstandard1.0": {
      "buildOptions": {
        "define": [ "CORE" ]
      },
      "dependencies": {
        "NETStandard.Library": "1.6.0"
      }
    },

    ".NETPortable,Version=v4.0,Profile=Profile328": {
      "buildOptions": {
        "define": [ "PCL" ]
      },
      "frameworkAssemblies": {
         "mscorlib": "",
         "System": "",
       }
    }
  }
}

Then just use dotnet pack to create the nuget package. (After adding in all the other metadata etc.)

like image 141
Jon Skeet Avatar answered Sep 22 '22 19:09

Jon Skeet


You can use xproj and csproj together with different project.json files. I did a blog post on the topic you should check out: http://stackify.com/using-both-xproj-and-csproj-with-net-core/

Essentially, you create a projectname.project.json that csproj picks up and then project.json that xproj uses. Seems to work!

like image 37
Matt Watson Avatar answered Sep 26 '22 19:09

Matt Watson