简体   繁体   中英

Adding my own configuration for a C# project into MSBuild / Visual Studio

I could probably hack some stupid solution to my problem, but I would love to do it right and save myself future headaches. I can write simple .vcxproj files, but they usually end up being quite beginner-like and poor quality.

I have a large-ish project, which I would like to build with two options. The two options differ from each other simply by the choice of one particular source file (.cs). The source directory contains both source files, each with its own unique file-name. The configuration needs to build, and later initialize the right file at runtime. It is ok to build the two versions separately, but the switch must be clean. I do not really care whether the initialization functions have the same name, or have different names.

I would love to get advice how to formulate that project's vcxproj file, so I can easily switch between building one version or the other version of my project.

Thanks

Using MsBuild's Condition you can enable/disable compilation based on a property like Configuration. This might be appropriate for your situation: suppose you now have 'Debug' and 'Release' configurations, you could add 'Debug_OptionB' and 'Release_OptionB' configurations. In the project file you create a boolean property based which is true if a configuration contains the 'OptionB' string:

<PropertyGroup>
  <CompilingWithOptionB>$(Configuration.Contains('_OptionB'))</CompilingWithOptionB>
</PropertyGroup>

Now use this property for conditional compilation:

<ClCompile Condition="'$(CompilingWithOptionB)'!='True'" Include="src_a.cpp" />
<ClCompile Condition="'$(CompilingWithOptionB)'=='True'" Include="src_b.cpp" />

If there are multiple source files to be included/excluded you'd put them in a seperate ItemGroup which then has the Condition, or even in seperate property sheets.

 I can write simple .vcxproj files, but they usually end up being quite beginner-like and poor quality

I'd advise not writing them yourself, but have VS create them for you and then add modifications. This is easier and also assures that the integration with VS stays intact. Especially it makes adding/removing/ordering/inspecting property sheets easier (you are using them to set common configuration options, right?).

If you don't have strong reason to include/exclude files consider compiling all files in single set of binaries and using feature toggles or other configuration mechanism (like DI container configuration) to enable/disable particular features.

Stijn's answer provides good steps to achieve conditional includes - have conditions based either on configuration names or better yet conditional symbols (like "DEBUG") and enable/disable individual items or groups with Condition=.... attribute in project file.

But be prepared that many VS tools and plugins will be at least useless (and sometimes very confused) about conditionally included code. Testing such code in VS would also be harder as you'd be able to run test only against single flavor of the binaries at the time potentially leaving other set of files untested.

Following are reasons I heard why one would like to have such "pick different files" behavior with possible alternative approaches:

  • have "full"/"limited" versions of software - this is probably only real reason why to do that. Note that C#/.Net generally is not that protected from reverse engineering, it may be too easy to overcome such limitation by copying full version anyway. Make sure to weight against complexity of testing/supporting multiple versions
  • debug only code/tracing/... - #if and conditional attributes likely cover most of the cases so files can be included all the time and code enabled/disabled with regular conditional symbols (maybe even default DEBUG build configuration is enough). All tracing/logging libraries come with enough configuration settings so such file-level exclusions are not necessary
  • Wrappers for flavor specific libraries - like 32/64 bit interop. This may be handled by separate assemblies included at run-time and/or carefully designed classes that pick correct implementation at run-time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM