VS: C# project using per-config sources
(Please let me know if a specific format is desired for reporting issues, and I will be happy to adjust)
Brief summary
Minimal repro: https://github.com/vaughantnrc/CMakeCSharpRepro20210423
I use a generator expression $<CONFIG>
in a C# source code filepath. I expect the resulting C# solution to choose the source code file based on configuration. Instead, it tries to use source code files for all of the configurations simultaneously.
Details
In my specific instance I'm working in Visual Studio 2017 on Windows. I generate C++ to C# wrapper code using SWIG, and try to compile the .cs files to a configuration-specific C# DLL. I use a generator expression to select the correct source code file (they have shared library file names that are used in DllImport attributes depending on configuration). Unfortunately the C# solution results in compiling all source code files (for all configurations) instead of just the one for the selected configuration.
No actual code generation is necessary to reproduce the issue. Minimal repro can be found below, I believe all that is needed is CMake (I have version 3.20.1), Visual Studio 2017 or 2019, and the appropriate workload(s) like .NET.
https://github.com/vaughantnrc/CMakeCSharpRepro20210423
This is part of the resulting .csproj:
<ItemGroup>
<Compile Include="D:\CMakeCSharpRepro\Debug\test.cs">
<Link>Debug\test.cs</Link>
<ObjectFileName>$(IntDir)/Debug/test.cs</ObjectFileName>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</ExcludedFromBuild>
</Compile>
<Compile Include="D:\CMakeCSharpRepro\Release\test.cs">
<Link>Release\test.cs</Link>
<ObjectFileName>$(IntDir)/Release/test.cs</ObjectFileName>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</ExcludedFromBuild>
</Compile>
<Compile Include="D:\CMakeCSharpRepro\MinSizeRel\test.cs">
<Link>MinSizeRel\test.cs</Link>
<ObjectFileName>$(IntDir)/MinSizeRel/test.cs</ObjectFileName>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</ExcludedFromBuild>
</Compile>
<Compile Include="D:\CMakeCSharpRepro\RelWithDebInfo\test.cs">
<Link>RelWithDebInfo\test.cs</Link>
<ObjectFileName>$(IntDir)/RelWithDebInfo/test.cs</ObjectFileName>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">true</ExcludedFromBuild>
</Compile>
</ItemGroup>
The ExcludedFromBuild
elements do not seem to do anything, since it will always try to compile all four files.
Changing the lines above to the following works for me:
<ItemGroup>
<Compile Include="D:\CMakeCSharpRepro\Debug\test.cs" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<Compile Include="D:\CMakeCSharpRepro\Release\test.cs" Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<Compile Include="D:\CMakeCSharpRepro\MinSizeRel\test.cs" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'" />
<Compile Include="D:\CMakeCSharpRepro\RelWithDebInfo\test.cs" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" />
</ItemGroup>
So I'm led to think that perhaps the ExcludedFromBuild
element does not belong in C# projects (though my experience suggests that it does seem to work for C++ projects). I'm wondering if this is an issue with CMake, or if some other tool is coming into play here.
(edit: The compile elements do actually close... :-) )