Steven Steven - 18 days ago 12
C# Question

How do compiler directives work with project.json in Visual Studio 2015

I'm creating a reusable library that targets several platforms (.NET 4.0, .NET 4.5, .NETStandard1.0 and .NETStandard1.3). I used to maintain this library in 2 separate projects; one project compiled against .NET 4.0 and .NET 4.5 and a second project that compiled .NETStandard1.0. This practice however is very inconvenient, since it forced me to maintain two projects and link project files from one project to the other.

I'm now trying to integrate this into one single project, which should be easy because the new project.json structure allows us to specify

frameworks
with
buildOptions
. Unfortunately I get stuck and my project doesn't compile anymore. This leads me to believe that I have an incorrect view about how this build system works.

To demonstrate my problem, I reduced this to the following project.json:

{
"version": "1.0.0-*",

"frameworks": {
"net45": {
"buildOptions": {
"defines": [ "NET45" ]
}
},
"netstandard1.3": {
"buildOptions": {
"defines": [ "NETSTANDARD" ]
},
"dependencies": {
"NETStandard.Library": "1.6.0"
}
}
}
}


This project contains two frameworks: .NET 4.5 and .NETStandard 1.3, both with their own compiler directives
NET45
and
NETSTANDARD
. So far so good, but once I start using those compiler directives in my code, things stop working:

using System;

public class Foo
{
#if NET45
public const string Bar = "NET45";
#endif
#if NETSTANDARD
public const string Bar = "NETSTANDARD";
#endif

public Foo()
{
System.Console.WriteLine(Bar);
}
}


With the given configuration and class my observations are that:


  • The syntax highlighter in Visual Studio greys out both the
    public const string
    definitions.

  • Still the code seems to compile under the net45 framework, because the compile C# compiler error solely complaints about
    Bar
    being unavailable under
    .NETStandard,Version=1.3
    .

  • When looking in the bin\debug folder, there is a \net45 folder with the compiled .dll, but the \netstandard1.3 folder is empty.



With my limited knowledge and experience, I would expect the above setup to work, but unfortunately it doesn't. Why is this so, and what should be done to make it work?

Evk Evk
Answer

The option is named define, not defines. So to fix your issue, just do:

{
"version": "1.0.0-*",

"frameworks": {
  "net45": {
    "buildOptions": {
      "define": [ "NET45" ]
    }
  },
  "netstandard1.3": {
    "buildOptions": {
      "define": [ "NETSTANDARD" ]
    },
    "dependencies": {
    "NETStandard.Library": "1.6.0"
    }
  }
  }
}

BUT, you don't actually need to define those directives at all, because they are already defined for you (see here for a list). For NET 4.5 you already have directive named "NET45", and for another framework it is named "NETSTANDARD1_3".

Comments