使用CMake生成C#项目

Leo*_*nid 48 c# build-automation build cmake visual-studio

我正在尝试在Windows上的现有C++ CMake代码库中生成一个C#项目.经过一些研究,我发现只有两个项目为CMake构建了自己的CSharp编译器: gdcmkde.

我试过了他们两个.不幸的是,第一个未能生成C#项目.相反,它创建了一个带有cs文件的VS C++项目,并且由于为链接器设置了C++标志,因此构建总是失败并出现错误.在尝试了他们提供的示例项目之后,我想知道这是否可能是由于"Visual Studio 8 2005"代码生成器的限制?

第二个项目主要针对Mono,所以我也没有成功.

有没有人在使用其中一个CMake模块或其他东西构建C#项目方面有积极的经验?

the*_*ler 36

CMake 3.8.2开始,CSharp项目生成由CMake正式支持.

要使用CMake构建默认的Visual Studio 2017生成的C#/ WPF项目,请按如下方式创建CMakeList.txt文件.

  • 项目宣言

    project(Example VERSION 0.1.0 LANGUAGES CSharp)
    
    Run Code Online (Sandbox Code Playgroud)
  • CSharpUtilities如果您计划使用WPF或其他设计器属性,请包含CMake .

    include(CSharpUtilities)
    
    Run Code Online (Sandbox Code Playgroud)
  • 添加所有cs,xaml,settings,properties

    add_executable(Example
        App.config
        App.xaml
        App.xaml.cs
        MainWindow.xaml
        MainWindow.xaml.cs
    
        Properties/AssemblyInfo.cs
        Properties/Resources.Designer.cs
        Properties/Resources.resx
        Properties/Settings.Designer.cs
        Properties/Settings.settings)
    
    Run Code Online (Sandbox Code Playgroud)
  • 链接设计器文件,xaml文件和其他属性文件及其相应的cs文件

    csharp_set_designer_cs_properties(
        Properties/AssemblyInfo.cs
        Properties/Resources.Designer.cs
        Properties/Resources.resx
        Properties/Settings.Designer.cs
        Properties/Settings.settings)
    
    csharp_set_xaml_cs_properties(
        App.xaml
        App.xaml.cs
        MainWindow.xaml
        MainWindow.xaml.cs)
    
    Run Code Online (Sandbox Code Playgroud)
  • 将app App.xaml属性文件设置为程序入口点(如果项目是WPF项目)

    set_property(SOURCE App.xaml PROPERTY VS_XAML_TYPE "ApplicationDefinition")
    
    Run Code Online (Sandbox Code Playgroud)
  • 设置其他csproj文件标志

    set_property(TARGET Example PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
    set_property(TARGET Example PROPERTY WIN32_EXECUTABLE TRUE)
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  • 添加库

    set_property(TARGET Example PROPERTY VS_DOTNET_REFERENCES
        "Microsoft.CSharp"
        "PresentationCore"
        "PresentationFramework"
        "System"
        "System.Core"
        "System.Data"
        "System.Data.DataSetExtensions"
        "System.Net.Http"
        "System.Xaml"
        "System.Xml"
        "System.Xml.Linq"
        "WindowsBase")
    
    Run Code Online (Sandbox Code Playgroud)

有关工作示例,请参阅https://github.com/bemehiser/cmake_csharp_wpf_example

  • 遗憾的是,这仅在 Windows 上受支持 (2认同)
  • 仅在 Windows 上支持通过 CMake 生成 Visual Studio 项目,可能是因为 Visual Studio 本身仅对 Windows 提供了不错的支持。(是的,Mac 上也有部分支持,但 CMake 中不支持。) (2认同)
  • 是的,但是 Linux 和 Mac 上的 Mono 对 Visual Studio *项目* 的支持已有十多年了。 (2认同)
  • 这是否支持混合项目?我需要一个带有 c++ 库和 c# 项目的 Visual Studio 解决方案 (2认同)
  • 根据您设置目录结构的方式,是的.例如,如果你有一个包含C++文件的目录,这些文件可以编译成库,而另一个目录包含C#文件,你可以在C++文件夹中使用`project(CPPExample VERSION 0.1.0 LANGUAGES CPP)`,构建你的库目标,然后在C#项目中使用该目标.可能还有其他更优雅的方法来做到这一点,但这就是我做到的. (2认同)

Ala*_*Maw 28

CMake 2.8.9及以上添加一个TYPE参数include_external_msproject如下:

include_external_msproject(
    MyProject MyProject.csproj
    TYPE FAE04EC0-301F-11D3-BF4B-00C04F79EFBC)
Run Code Online (Sandbox Code Playgroud)

这允许您指定项目是C#(上面的神奇GUID),否则事情就会发生(请参阅文档).

您可能仍然希望使用文件configure_file中其他地方提到的模板方法.csproj来获取正确的路径,除非您直接构建到源树中.

好消息是你可以在文件中通配你的C#文件,.csproj.template如下所示:

<ItemGroup>
  <Compile Include="${DOS_STYLE_SOURCE_DIR}\**\*.cs" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

并且你需要这样的东西CMakeLists.txt来将CMake的unix风格的转发路径分隔符转换成Windows风格的反斜杠,否则它将编译文件,但它们不会在Visual Studio的项目中显示为链接:

FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" DOS_STYLE_SOURCE_DIR)
Run Code Online (Sandbox Code Playgroud)

那就是:

CONFIGURE_FILE(MyProject.csproj.template MyProject.csproj)
Run Code Online (Sandbox Code Playgroud)

在您CMakeLists.txt使用正确的通配符路径将模板文件配置为实际项目文件.

HTH.

  • 您不需要复制C#源文件夹/文件 - 它们是就地引用的.csproj.template文件与任何其他csproj文件相同,但上面提到的通配符除外.只需复制一份.我已经将实际的CONFIGURE_FILE命令添加到我的答案中,这是唯一缺少的. (3认同)

Max*_*ich 24

万一有人仍然在寻找有关这方面的信息,实际上没有理由用CMake生成C#项目,它们是跨设计的跨平台.在Linux上,C#项目通常使用MonoDevelop进行管理,可以从visual studio中读取.csproj文件.这应该可以实现C#项目的跨平台开发.唯一可能的问题是,如果你将原生c ++项目与c#项目混合在一起(比如用c#中用c ++编写的后端),在这种情况下只需要对.csproj文件进行cmake复制,就像它们是数据一样,你应该很高兴去.CMake旨在将您的构建环境设置为跨平台.这对于c ++非常方便,其中代码在linux上以非常不同的方式构建,而不是在windows(或其他操作系统,如果你进入),但对于可以执行跨平台的c#来说是不必要的,并且,由于设计单声道团队的决策,可以构建跨平台.CMake确实提供了一些很好的自动化工具,但是大部分功能都可以通过正确配置的.csproj文件来恢复.无论如何,我知道这个问题已经超过一年了,但它是我在查找如何做到这一点时偶然发现的顶级搜索结果之一.我已经实现了这一点.

  • 有一个很好的理由由CMake生成C#项目.如果您使用CMake完成了大量配置的混合原生+ C++/CLI + C#项目,则需要C#项目将CMake中完成的配置考虑在内,并参考为C++生成的项目并包含在正确的解决方案中. (28认同)
  • 我想说使用CMake生成C#项目的最好理由是远离.csproj文件.我对.csproj文件的最大问题是它们只能通过一组奇怪的对话来编辑,结果是一个不可穿透的XML文件.CMake既没有这些问题也没有. (4认同)
  • 是的,但是虽然cmake还提供了安装功能,但普通的C#项目(csproj)却没有.如果cmake可以提供它,我会对C#项目的"make && make install"功能感兴趣. (3认同)

squ*_*les 8

借助@the_storyteller 提供的答案,CMake v3.8及更高版本确实支持将 C# 作为一流语言。因为已经提供了 WPF 示例,所以这里是一个简单的 Windows 窗体应用程序的完整 CMake 示例。我提供了用于链接在源树中本地构建的其他库以及链接 3rd 方库依赖项的可选命令。

请注意,Windows 窗体应用程序需要使用csharp_set_windows_forms_propertiesCMake 命令,而 WPF 项目使用csharp_set_designer_cs_propertiescsharp_set_xaml_cs_properties.

CMakeLists.txt

cmake_minimum_required(VERSION 3.8)

project(MyWinFormApp LANGUAGES CSharp)

# Include CMake utilities for CSharp, for WinForm and WPF application support.
include(CSharpUtilities)

# Define the executable, including any .cs files. 
# The .resx and other Properties files are optional here, but including them makes them visible in the VS solution for easy editing. 
add_executable(MyWinFormApp
    App.config
    Form1.cs
    Form1.Designer.cs
    Form1.resx
    Program.cs
    Properties/AssemblyInfo.cs
    Properties/Resources.Designer.cs
    Properties/Resources.resx
    Properties/Settings.Designer.cs
    Properties/Settings.settings
)

# Set the .NET Framework version for the executable.
set_property(TARGET MyWinFormApp PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
# Set the executable to be 32-bit.
set_property(TARGET MyWinFormApp PROPERTY WIN32_EXECUTABLE TRUE)
# Set the C# language version (defaults to 3.0).
set(CMAKE_CSharp_FLAGS "/langversion:latest")

# Set the source file properties for Windows Forms use.
csharp_set_windows_forms_properties(
    Form1.cs
    Form1.Designer.cs
    Form1.resx
    Program.cs
    Properties/AssemblyInfo.cs
    Properties/Resources.Designer.cs
    Properties/Resources.resx
    Properties/Settings.Designer.cs
    Properties/Settings.settings
)

# If necessary, link in other library dependencies that were built locally in this source tree.
target_link_libraries(MyWinFormApp MyLocalLib)

# If necessary, link in other library/DLL references, such as 3rd party libraries.
set_property(TARGET MyWinFormApp PROPERTY 
    VS_DOTNET_REFERENCE_MyThirdPartyLib /path/to/libs/MyThirdPartyLib.dll)

# Add in the .NET reference libraries.
set_property(TARGET MyWinFormApp PROPERTY VS_DOTNET_REFERENCES
    "Microsoft.CSharp"
    "System"
    "System.Core"
    "System.Data"
    "System.Drawing"
    "System.Windows.Forms"
)
Run Code Online (Sandbox Code Playgroud)


Leo*_*nid 2

我终于能够使用第二个 C# 模块 - kde 生成有效的解决方案。虽然,cmake 创建了许多 .vcproj 文件,而我希望获得 .csproj,但我猜这是“Visual Studio 8 2005”生成器可以提供的唯一形式。

尽管如此,我还是能够成功构建这个解决方案并生成可执行文件和 dll 库。