30

I am trying to use a preprocessor directive in .NET Core, but I can't determine the correct way to get the directive to be set:

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    #if MAC
    Console.WriteLine("MAC");
    #else
    Console.WriteLine("NOT MAC");
    #endif
}

I have tried various permutations from the command line to get this to work, but I seem to be missing something. Here is the shell output when I run various build and run commands:

cd ~/dev/Temp/DirectiveTests
dotnet msbuild /p:MAC=TRUE

Output:

Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.

  DirectiveTests -> /Users/me/dev/Temp/DirectiveTests/bin/Debug/netcoreapp1.1/DirectiveTests.dll

dotnet run /p:MAC=true

Output:

Hello World!
NOT MAC

dotnet run

Output:

Hello World!
NOT MAC

I am using the tooling version 1.0.1 according to dotnet --version.

How can I properly set the directives from the command line using .NET Core?

3 Answers 3

32

The thing you need to set is /p:DefineConstants=MAC note this will override constants set in the project like DEBUG or TRACE that may be set so the full version you would likely use would be

for a debug build

dotnet msbuild /p:DefineConstants=TRACE;DEBUG;NETCOREAPP1_1;MAC /p:Configuration=Debug

and for a release build

dotnet msbuild /p:DefineConstants=TRACE;NETCOREAPP1_1;MAC /p:Configuration=Release

An easier solution would create a configuration called Mac and in your csproj have

  <PropertyGroup Condition="'$(Configuration)'=='Mac'">
    <DefineConstants>TRACE;NETCOREAPP1_1;MAC</DefineConstants>
  </PropertyGroup>

Then from the command line you just need to do

dotnet msbuild /p:Configuration=Mac
Sign up to request clarification or add additional context in comments.

2 Comments

Hmm.. The DefineConstants doesn't seem to help. Also, when I put multiple in the value I get an error stating MSB1006 that the property is invalid.
Ok, I found that it does not like the quotes around the constants. If I don't use the quotes, then the DefineConstants works.
18

If you want custom configuration switches that do not impact other settings ("Configurations" like Debug and Release), you can define any other property and use it in your build.

E.g., for dotnet build /p:IsMac=true you could add the following to your .csproj file (not that run might not pass the property correctly though IsMac=true dotnet run will work after a clean):

<PropertyGroup>
  <DefineConstants Condition=" '$(IsMac)' == 'true' ">$(DefineConstants);MAC</DefineConstants>
</PropertyGroup>

If you want to go further and automatically detect if you are building on a Mac, you can use MSBuild property functions to evaluate which operating system you are building on. Note that this currently only works for the .NET Core variant of MSBuild (dotnet msbuild). See this pull request for details on the support.

<PropertyGroup>
  <IsMac>$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::get_OSX())))</IsMac>
  <DefineConstants Condition=" '$(IsMac)' == 'true' ">$(DefineConstants);MAC</DefineConstants>
</PropertyGroup>

Comments

2

Building on Martin's answer, you can make it quite simple like this:

<PropertyGroup>
    <!-- Define additional preprocessor directives -->
    <DefineConstants Condition="'$(DefineAdditionalConstants)' != ''">$(DefineConstants);$(DefineAdditionalConstants)</DefineConstants>
</PropertyGroup>

Then on the command line, you can do:

dotnet build '-p:DefineAdditionalConstants=CONSTANT'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.