Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • CMake CMake
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 4,107
    • Issues 4,107
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 18
    • Merge requests 18
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • CMakeCMake
  • CMakeCMake
  • Issues
  • #22108
Closed
Open
Issue created Apr 23, 2021 by Thomas Vaughan@vaughantnrcContributor

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.

I read the guide at: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/msbuild/how-to-exclude-files-from-the-build?view=vs-2015&redirectedfrom=MSDN#using-conditions-to-exclude-a-file-or-directory-from-the-inputs-for-a-build

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... :-) )

Edited Apr 26, 2021 by Thomas Vaughan
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking