24

I need to create a demo version of an existing large application consisting of multiple projects. I'd like to use the existing projects, and just neuter the functionality via preprocessor directives

#if DEMO
    mycode.NeuterNow();
#endif

We are building our app using MSBuild, and I'd ideally use something along the lines of:

MSBuild -DefineProperty:DEMO MySolution.sln

Does such functionality exist?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
BrianH
  • 1,082
  • 1
  • 16
  • 23

3 Answers3

18

Try

msbuild /p:DefineConstants=DEBUG;DEMO MySolution.sln

You have to include DEBUG or RELEASE and any other constants already defined in the solution file, but I think this should work. Disclaimer: I've never actually tried it myself.

configurator
  • 40,828
  • 14
  • 81
  • 115
12

That's a duplicate of this one, and yes, /p:DefineConstants does work fine, and configurator is right, this will override ALL conditional symbols already defined in the Project File (which is good IMHO), so you'll have to define them all.

Community
  • 1
  • 1
Michael Stum
  • 177,530
  • 117
  • 400
  • 535
8

I discovered something interesting when pursuing my own solution to this problem and I thought I'd share.

The /p directive in MSBuild isn't limited to properties that already exist in a build file. You can use it to set anything.

So if, for example, you lead your preprocessor directives with $(FeatureSet) and then call MSBuild as, for example

MSBuild solution.sln /p:FeatureSet=DEMO

it gets #defined accordingly without having to manually clobber and respecify any other preprocessor directives you have running.

I've verified this works in VS2010. Not quite as sure about how you'd define FeatureSet for a build done inside Visual Studio without MSBuild.

Glazius
  • 729
  • 7
  • 28
  • 2
    Can you give me a full example of this? I can't figure it out how to do this exactly... – Christoph Fink Sep 10 '14 at 08:32
  • 2
    Again, this is just VS2010. I don't know about later versions. Preprocessor directives are a semicolon-separated list of items in your project properties, under configuration - C++ - preprocessor. Manually add $(Variable) to the list, then when you call MSBuild from the command line you can set /p:Variable=FOO and things like #ifdef FOO will respond to it. – Glazius Sep 11 '14 at 14:54
  • I confirm that it works with VS2017 when /p:DefineConstants wouldn't do it for me. I put `$(MyDefines)` and used `/p:MyDefines="DEMO;NO_OPENCL"` when calling MSBuild.exe. Now that I think of it I didn't see anything called "DefineConstants" in my .vcxproj, maybe that's why it didn't work. – Michel Rouzic Nov 15 '18 at 20:57
  • @MichelRouzic does your solution have 1 project or more than 1? I can't seem to get it to work if there are multiple projects. Rather, I think for some reason VS thinks that the $(Var) is a environment variable which doesn't expand to anything – Roy2511 Sep 03 '19 at 10:29
  • Only one project, I have no idea how to fix it for more than one. – Michel Rouzic Sep 03 '19 at 15:34
  • Nvm, I figured it's just easier to create multiple configurations with different preprocessor definitions from the GUI. And then call MSBuild using /p:Configuration=Release_DefineDEMO etc. Of course, this only works if you know the definitions beforehand, If its generated from some batch file which you pass into the command line, this wont work. – Roy2511 Sep 04 '19 at 06:34