Dynamically set conditional compilation symbols
I would like to have a list of conditional compilation symbols, maybe a table where each symbol has a checkbox, and then at build time, only symbols that are 'swit开发者_运维知识库ched' on are included in the compilation. Is there any way to do this besides programmatically changing the project file before each compile?
First, I assume for this answer that you would like to do it from Visual Studio IDE and you a compile C++ project.
You can do it by adding property pages to your project where you specify all these compilation symbols. The property pages gives you the UI in very little effort. When the user edits the property pages, the data is stored on items/properties in your project file or user file. You will also need to add a custom task that will actually take the data that was stored by the property pages and apply it when files are compiled.
So here it is with a few more details:
Import your targets file from your project file. Edit the .vcxproj and add at the end (before the closing element
</Project>
for example) something like:
<Import Project="$(ProjectDir)MyTargets.xml" />
Compose MyTargets.xml file. It should import the property pages and define the custom target.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PropertyPageSchema Include="$(ProjectDir)MyProperties.xml"/>
</ItemGroup>
<Target Name="AddMySymbols"
Inputs="@ClCompile"
Outputs="__non_existent_outputs__"
BeforeTargets="ClCompile">
<ItemGroup>
<ClCompile Include="@ClCompile">
<PreprocessorDefinitions Condition="'$(MY_SYMBOL)'='true'">MY_SYMBOL; %(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
</Target>
</Project>
AddMySymbols target is performed before compiling every file. For each file we add MY_SYMBOL to PreprocessorDefinitions if a property called "MY_SYMBOL" is true.
- Compose MyProperties.xml file. This file is used by Visual Studio to display the property pages UI. It will allow the user to set MY_SYMBOL property to true/false. Here is an example of MyProperties.xml:
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">
<Rule Name="Symbols" PageTemplate="tool" DisplayName="Symbols" SwitchPrefix="/" Order="1" xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Rule.Categories>
<Category Name="MySymbols">
<Category.DisplayName>
<sys:String>My Symbols</sys:String>
</Category.DisplayName>
</Category>
</Rule.Categories>
<Rule.DataSource>
<DataSource Persistence="ProjectFile" ItemType="" HasConfigurationCondition="false" />
</Rule.DataSource>
<BoolProperty
Name="MY_SYMBOL"
Category="MySymbols"
DisplayName="MY_SYMBOL"
Description="When enabled, MY_SYMBOL will be added to preprocessor symbols when compiling C/C++ files."/>
</ProjectSchemaDefinitions>
ItemType is "" so that MY_SYMBOL will be saved in the project file as a property and not as an item. You could arrange it differently and work with items instead.
If you would like the symbols to be saved per user you could save it to the user file by changing DataSource to <DataSource Persistence="UserFile" ItemType="" HasConfigurationCondition="false" />
Here is a link to some explanations about property pages.
Amir
精彩评论