msbuild, defining Conditional Compilation Symbols
Asked Answered
C

4

86

I'm possibly just blind, but is there a command line to specify conditional compilation symbols in MSBUILD?

I currently have this Line in my buildscript:

SET MSBUILD=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe
SET CONFIG=Debug
%MSBUILD% /p:Configuration=%CONFIG% /p:OutputPath=..\..\output source\MyProject\MyProject.csproj

And I'd like to add a condition. In Visual Studio, i can just go into Project Properties => Build => Conditional compilation symbols, but I have not seen that option for msbuild?

Bonus Karma if you know if I can completely override all symbols already specified in the .csproj files to make sure that only the conditionals from my Buildscript go in.

Crandale answered 26/1, 2009 at 14:38 Comment(1)
And BTW, this is not a duplicate of #296647 because the other question has the same title but the answer only includes Visual Studio/Project File modification.Crandale
S
154

Have you seen this? (most info is in the penultimate post)

/p:DefineConstants="MYSYMBOL1;MYSYMBOL2"
Sitarski answered 26/1, 2009 at 15:40 Comment(7)
Added the Code, that was it, thanks! It overrides all Constants that may be defined in the .csproj file, which is good as well.Crandale
For this to work for me, I was forced to add this to the command line: /t:RebuildSniggle
using xbuild from os x terminal I get MSBUILD: error MSBUILD0005: Invalid syntax. Property name and value expected as <prop name>=[<prop value>]Crossway
Worked great. /p:DefineConstants="QCBUILD" My solution has lots of projects in it. This seems to be solution global. Does anyone want to point me to how to get a solution global conditional compilation symbol while using the Visual Studio (not command line)?Emmons
Is there any way to append to the existing defines?Wehrmacht
Note that this will replace the existing defines, so if you were relying on things like NETCOREAPP or NETFRAMEWORK being defined, you'll lose those. To append to the existing defines, it's better to add a property in your .csproj file like: <DefineConstants>$(DefineConstants);FOO;BAR</DefineConstants>.Alysiaalyson
As of MS Build from Visual Studio 2019, this doesn't seem to work for a C++ project - the defined symbols don't get to the command line, passed to the C++ compiler.Imbrication
S
22

I had to use a space instead of a semicolon a la this post by Björn Lasar: http://www.linqinpark.net/2009/01/13/MSBuildWithMultipleDefineConstants.aspx

Update: the blog has disappeared; retrieved via Internet Archive:

Recently I had to use MSBuild directly to automate some builds. I also had to configure some preprocessor defines based upon a configuration. This is usually done by an Argument like this

"/p:DefineConstants=MY_PREPROC_FLAG"

Nothing special here since there are enough comments on the web about that. Today I needed one Flag more and I used the commandline syntax similar to how I knew it from the IDE:

"/p:DefineConstants=MY_PREPROC_FLAG;YET_ANOTHER_FLAG"

but this one didn't work.

So the point is that if you want to support multiple defines to a project by commandline you'll have to separate them by simple spaces...

"/p:DefineConstants=MY_PREPROC_FLAG YET_ANOTHER_FLAG" 

and it will be added to the (semicolon-separated) Defines from the IDE. Good to know I think...

Sirotek answered 26/11, 2009 at 17:17 Comment(2)
How do you test for the existence of these symbols? I tried if '$(SIGN_ASSEMBLY)' == '' goto :exit but if the symbol doesn't exist, you get the same empty string.Homogony
@MikeDoonsebury one always uses the presence of a value, and its specific value, i.e. == "True" - not sure what you mean with the goto exit in msbuild - the equivalent would be to put a Condition on the <Task and/or on the task invocation e.g. <Exec Condtion="$(SignAssembly)=='True' ...Sirotek
S
6

/p:DefineConstants is an all or nothing deal.

If you just want to turn off trace symbol, you can't just do it with: msbuild /p:DefineTrace=false

You have to define something to override all the symbols already defined: msbuild /p:DefineConstants="RANDOM-SYMBOL"

Thanks Michael Stum point this hidden rule out I have also wrote a blog about it --- dead link

Shoreless answered 11/11, 2011 at 11:15 Comment(1)
"all the symbols" is really important here. If you use /p: DefineConstants to define a constant you will lose all the other defined constant in a project. DefineConstants should contain all the constants need in the project you can not mix and match constants defined in project and defined with DefineConstantsMultilateral
D
1

What is said in the answers is valid for C# code, and also for ASP.NET "codebehind" C# code. For ASP.NET web projects, if you want to do conditional compilation in the ASPX pages as well, it works a bit differently to conditionally render HTML on the page (note I've removed MasterPageFile="..." AutoEventWireup="true" CodeBehind="..." Inherits="..." which you usually have in the <%@ ... %> declaration as well):

<%@ Page Title="MyPage" Language="C#" CompilerOptions="/d:DebugSym1;DebugSym2" %>

<% #if DebugSym1 %>         
    <h4>Section1</h4>
<% #else %>
    <h4>(Section 1 skipped)</h4>
<% #endif %>

<% #if DebugSym2 %>         
    <h4>Section2</h4>
<% #else %>
    <h4>(Section 2 skipped)</h4>
<% #endif %>

If you remove DebugSym1 or DebugSym2 from the CompilerOptions, then the #else part of the relevant #if statement is rendered.

I thought this was worth mentioning for completeness of this topic and can save you time. More you can find in this article, if you're interested.

Duma answered 17/6, 2013 at 12:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.