Search code examples
visual-studio-2010linkerstatic-librariesconditional-compilation

Visual Studio 2010 - trying to conditionally compile static library based on target .exe


I have a static library that is used in production code and test code. I want to be able to inject test data only if I am building the test .exe. I would like to do this using preprocessor #defines, rather than MSVS configurations (e.g., Debug vs. Release) because I am testing performance. Debug builds turn off optimization, which is great during debugging but not so great when I want to test performance.

As an example, say I have Foo.lib, Production.exe, and Test.exe projects in MSVS. Production.exe and Test.exe both link Foo.lib. I would like Production.exe and Test.exe to rebuild Foo.lib with their respective preprocessor definitions, so the code in Foo.lib will conditionally compile based on which executable it is targeted for.

I'm open to other solutions, and I hope I stated my problem clearly. First post on stack overflow.


Solution

  • You'll need to set up multiple solution configurations to support each of the scenarios you desire. First we'll add a new Test configuration to the static library, and create an accompanying Test solution configuration:

    • In Solution Explorer in Visual Studio, right click on the top-level solution node.
    • Click Configuration Manager...
    • Find your C/C++ static library project in the project list. Click the Configuration cell for that project. It will turn into a drop-down. Pick New.. from that drop-down.
      • Enter in a name for a new project configuration. Call it whatever you like. In these steps, I'll call it Test.
      • For the Copy settings from: field, select Release, since you want a test configuration that does have optimization enabled.
      • Leave the Create new solution configurations checkbox checked.
      • Click OK

    Now you can modify your static library's new Test configuration with your desired #defines:

    • Find your C/C++ project in Solution Explorer. Right-click on it and select Properties...
    • Select your new Test configuration from the Configuration drop-down at the top-right.
    • In the left-hand pane, select Configuration Properties | C/C++ | Preprocessor
    • On the right, add your desired #defines to the list of Preprocessor Definitions

    ...now, you want to set your builds up so that you have a build configuration that builds Test.exe with the static library's Test configuration, and the Release.exe with the library's Release configuration. Go back to the Configuration Manager (as we did in the first two steps above):

    1. Set up your build configuration for Release.exe:

      • In the top-left drop down, select Release as the Active solution configuration:
      • For your Release.exe project, select its Release configuration, and make sure Build is checked
      • For your Test.exe project, make sure Build is unchecked.
      • For the static library, select its Release configuration, and make sure Build is checked
    2. Set up your build configuration for Test.exe:

      • In the top-left drop down, select Test as the Active solution configuration:
      • For your Release.exe project, make sure Build is unchecked.
      • For your Test.exe project, select its Release configuration (I assume that's what you want), and make sure Build is checked
      • For the static library, select its Test configuration, and make sure Build is checked

    Now, when you change your solution to Test or Release configuration, I'd expect you to have the build behavior you desire for each.