Reputation: 39638
I am trying to generate a Visual Studio C# project with CMake. This is what I have so far:
cmake_minimum_required(VERSION 3.10)
project(myProject VERSION 0.1.0 LANGUAGES CSharp)
add_library(myLib SHARED
src/file1.cs
src/file2.cs
src/file3.cs)
set_property(TARGET myLib PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "netstandard1.4")
I got the framework name from a .csproj file I generated with Visual Studio that looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
</Project>
This is what I need in order to build the library for .NET Standard 1.4. However, CMake generates this (among all the other stuff):
<TargetFrameworkVersion>netstandard1.4</TargetFrameworkVersion>
This does not seem to be valid, since Visual Studio complains that it cannot open the project. I did not find anything in the CMake documentation to set <TargetFramework>
instead of <TargetFrameworkVersion>
. Is this possible?
Upvotes: 3
Views: 4075
Reputation: 39638
This is how I managed to generate the project properly. Beware, it is an ugly hack. Check whether CMake has been updated to properly support this before you go this way.
So, first thing: The VS_DOTNET_TARGET_FRAMEWORK_VERSION
is not necessary. To add the proper <TargetFramework>
, this line can be used:
set_property(TARGET myLib PROPERTY VS_GLOBAL_TargetFramework "netstandard1.4")
You also want to add this, because for reasons that escape me, CMake thinks it is a good idea to generate a project with C# 3 as language level by default:
set_property(TARGET myLib PROPERTY VS_GLOBAL_LangVersion "6")
The generated project will not open in Visual Studio properly. That is because with .NET Core, there came some changes to the csproj format that CMake is currently unable to produce. For reference, this article covers them. CMake is unable to properly generate them, so I will first tell you what modifications you would need to make and then give you some hacky PowerShell script that does it for you.
There is an attribute Sdk
on the root <Project>
now, which we need to set like this:
<Project Sdk="Microsoft.NET.Sdk" ...
The automatically generated ZERO_CHECK
project does not work, so let's just get rid of it (we don't need it really). Delete it from <ProjectReference ... </ProjectReference>
and if it's the only item, delete the whole XML tag.
Then, since the project will now automatically reference stuff from the SDK, we need to get rid of the references to Microsoft.CSharp.targets
and Microsoft.Common.props
. Otherwise, Visual Studio will show you a warning and an error that stuff is loaded multiple times. Just delete the lines that contain these strings.
The standard projects ALL_BUILD
and ZERO_CHECK
which CMake always generates do not work and I could not be bothered to properly fix them, since they are not really necessary. I just deleted them from the .sln
file.
That's it! Now you can open the project in Visual Studio and it will work properly.
This is a script I wrote as workaround to properly generate the project & solution. It generates the solution in a folder cmake-vs
. You need the dotnet
utility which is part of the .NET Core SDK.
Be aware that paths may not be portable. Replace myLib
with your library name.
mkdir -Force cmake-vs | Out-Null
Set-Location cmake-vs
& "$Env:Programfiles\CMake\bin\cmake.exe" -G "Visual Studio 15 2017 Win64" ".."
& "$Env:Programfiles\CMake\bin\cmake.exe" --build .
((Get-Content "myLib.csproj") `
<# add Sdk attribute to project which is needed by netstandard1.4 #> `
-replace ('<Project ','<Project Sdk="Microsoft.NET.Sdk" ') `
<# remove reference to ZERO_CHECK project which causes problems #> `
-replace ('(?ms)<ProjectReference.*</ProjectReference>','') |
<# remove imports that are unneccessary for netstandard1.4 and cause
problems #> `
Select-String -Pattern "Microsoft.CSharp.targets" -NotMatch |
Select-String -Pattern "Microsoft.Common.props" -NotMatch |
<# for some reason, Select-String prepends an empty line which is not
allowed before <?xml ..., so we trim it away. #>
Out-String).Trim() | Out-File "myLib.csproj"
<# use dotnet util (part of the .NET Core SDK) to remove projects with problems
from the solution because I am really tired of regexes #>
& "$Env:Programfiles\dotnet\dotnet.exe" sln myLib.sln remove ALL_BUILD.vcxproj
& "$Env:Programfiles\dotnet\dotnet.exe" sln myLib.sln remove ZERO_CHECK.vcxproj
Upvotes: 5