Conditional compilation symbol for a .NET Core class library

Gene S picture Gene S · Jun 26, 2016 · Viewed 12.5k times · Source

I have created a .NET Core R2 class library and have some common code that I use for several different platforms.

Some of the code is not valid in the .NET Core platform and so I wish to wrap it around a conditional compilation symbol. I first searched the Internet to see if I could find a built-in symbol (like SILVERLIGHT for Silverlight applications and WINFX_CORE for Windows 8 applications), but I was not able to find any information, so I decided to create my own symbol. This also does not seem to work.

From everything I read, adding and using a symbol should be easy. Just add a value to the conditional compilation symbols in the project properties → Build tab. I did that, but it does not seem to work. Here are a couple of screenshots...

Enter image description here

Enter image description here

Notice that I added a NET_CORE value in the conditional compilation symbol, but when I use it in code the code is not being ignored.

  1. Is there is a built-in symbol for the .NET Core platform (I am using R2)?

  2. If there is not one, what am I doing wrong creating my own symbol?

The .xproj file:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  </PropertyGroup>
  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
  <PropertyGroup Label="Globals">
    <ProjectGuid>253184d7-9b42-4233-a871-8cfa3ee9e83e</ProjectGuid>
    <RootNamespace>Linq2Db.NetCore</RootNamespace>
    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
  </PropertyGroup>
  <PropertyGroup>
    <SchemaVersion>2.0</SchemaVersion>
  </PropertyGroup>
  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

UPDATE: I was able to resolve this using the link in the provided answer. Here are the details...

Originally the project.json file looked like this...

{
  "dependencies": {
        "NETStandard.Library": "1.5.0-rc2-24027"
  },
  "frameworks": {
    "netstandard1.5": {
      "imports": "dnxcore50"
    }
  },
  "buildOptions": {
    "defines": [ "NET_CORE" ]
  }
}

I resolved the issue by changing it to this...

{
  "frameworks": {
    "netstandard1.5": {
      "imports": "dnxcore50",
      "dependencies": {
        "NETStandard.Library": "1.5.0-rc2-24027"
      },
      "buildOptions": {
        "define": [ "NET_CORE" ]
      }
    }
  }
}

Answer

Devon Burriss picture Devon Burriss · Aug 30, 2017

Since xproj was discontinued, here is how it is done in the new Visual Studio 2017 .csproj files.

<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' Or '$(TargetFramework)' == 'netstandard1.6' ">
    <DefineConstants>NET_CORE</DefineConstants>
</PropertyGroup>

Then instead of:

private TypeInfo GetTypeInfo(Type type)
{
    #if NETSTANDARD1_3 || NETSTANDARD1_6
        // Core
    #else
        // Full framework
    #endif
}

You can do:

private TypeInfo GetTypeInfo(Type type)
{
    #if NET_CORE
        // Core
    #else
        // Fullframework
    #endif
}

See here for more details on multi-targeting: Developing Libraries with Cross Platform Tools, How to Multitarget