【问题标题】:Generate C# project using CMake使用 CMake 生成 C# 项目
【发布时间】:2011-01-05 15:49:02
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c# visual-studio build build-automation cmake


    【解决方案1】:

    截至CMake 3.8.2,CMake 正式支持 CSharp 项目生成。

    要使用 CMake 构建默认的 Visual Studio 2017 生成的 C#/WPF 项目,请创建一个 CMakeList.txt 文件,如下所示。

    • 项目声明

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

        include(CSharpUtilities)
      
    • 添加所有csxamlsettingsproperties

        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)
      
    • 将设计器文件、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)
      
    • 将 appApp.xaml 属性文件设置为程序入口点(如果项目是 WPF 项目)

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

        set_property(TARGET Example PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
        set_property(TARGET Example PROPERTY WIN32_EXECUTABLE TRUE)
        // ...
      
    • 添加库

        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")
      

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

    有关WinForms 的示例,请参阅this answer

    【讨论】:

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

    CMake 2.8.9 及更高版本将TYPE 参数添加到include_external_msproject,如下所示:

    include_external_msproject(
        MyProject MyProject.csproj
        TYPE FAE04EC0-301F-11D3-BF4B-00C04F79EFBC)
    

    这使您可以指定项目是 C#(上面的神奇 GUID),否则事情会很困难 (see docs)。

    您可能仍希望将其他地方提到的configure_file 模板方法与您的.csproj 文件一起使用以获得正确的路径,除非您直接构建到您的源代码树中。

    好消息是您可以像这样在 .csproj.template 文件中通配您的 C# 文件:

    <ItemGroup>
      <Compile Include="${DOS_STYLE_SOURCE_DIR}\**\*.cs" />
    </ItemGroup>
    

    并且您需要在 CMakeLists.txt 中使用类似的东西来将 CMake 的 unix 风格的正斜杠路径分隔符转换为 Windows 风格的反斜杠,否则它将编译文件但它们不会显示为项目中的链接视觉工作室:

    FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" DOS_STYLE_SOURCE_DIR)
    

    那就是:

    CONFIGURE_FILE(MyProject.csproj.template MyProject.csproj)
    

    在您的CMakeLists.txt 中将模板文件配置为具有正确通配符路径的真实项目文件。

    HTH。

    【讨论】:

    • 你能否给出一个完整的例子(或链接到一个)如何:(1)复制源C#文件夹和文件; (2).csproj.template及其使用方法; (3) 如何更新 CMakeLists.txt 来完成这一切?
    • 您不需要复制 C# 源文件夹/文件 - 它们被就地引用。除了上面提到的通配符之外,csproj.template 文件与任何其他 csproj 文件相同。复制一份就行了。我已将实际的 CONFIGURE_FILE 命令添加到我的答案中,这是唯一缺少的东西。
    • 我的 C# 文件夹中是否需要额外的 CMakeLists.txt 或所有这些更改都发生在根 CMakeLists.txt 中?如果它们发生在根 CMakeLists.txt 中,我是将它们放在调用 include_external_msproject() 之前还是之后?
    • 让它适用于根 CMakeLists.txt 中的所有更改。但是,为了 [重新] 构建我的 C# 项目,我必须在每次 [重新] 生成 .sln 时卸载并重新加载它们,否则它们将被“跳过”。有任何想法吗?我在这里问过:stackoverflow.com/q/15859576/135862
    • 仅供参考,这里是不同 Visual Studio 项目的魔法 GUID 列表:codeproject.com/Reference/720512/…
    【解决方案3】:

    以防万一有人仍在寻找有关此的信息,确实没有理由使用 CMake 生成 C# 项目,它们是跨平台设计的。在 Linux 上,C# 项目通常由 MonoDevelop 管理,它可以很好地从 Visual Studio 读取 .csproj 文件。这应该支持 C# 项目的跨平台开发。 唯一的潜在问题是,如果您将本机 c++ 项目与 c# 项目混合在一起(例如用 c++ 编写的后端和 c# 中的 GUI),在这种情况下,只需将 cmake 复制到您的 .csproj 文件上,就好像它们是数据一样,您应该去吧。 CMake 旨在将您的构建环境设置为跨平台。这对于 c++ 来说非常方便,其中代码在 linux 上的构建方式与在 windows(或其他操作系统,如果你喜欢的话)上的构建方式非常不同,但对于可以跨平台执行的 c# 来说是不必要的,并且感谢设计由 mono 团队决定,可以构建跨平台。 CMake 确实提供了一些很棒的工具来实现自动化,但是大部分功能都可以通过正确配置的 .csproj 文件来恢复。 无论如何,我知道这个问题已经存在一年多了,但它是我在查找如何执行此操作时偶然发现的热门搜索结果之一。我已经意识到了这一点。

    【讨论】:

    • 是的,但是虽然 cmake 还提供安装功能,但普通 C# 项目 (csproj) 不提供。如果 cmake 可以提供的话,我会对 C# 项目的“make && make install”功能感兴趣。
    • 为此设置构建后事件并不难。假设您需要集成到现有的 cmake 构建系统中,您甚至可以使用 cmake configure_file 命令填写正确的安装位置。
    • 通过 CMake 生成 C# 项目是有充分理由的。如果您将原生 + C++/CLI + C# 项目与 CMake 完成的大量配置混合在一起,则需要 C# 项目将 CMake 中完成的配置考虑在内,并参考为 C++ 生成的项目并包含在正确的解决方案中。
    • @Jan 再次为此使用 configure_file (cmake.org/cmake/help/v2.8.8/cmake.html#command:configure_file)。我从事的大多数项目都是 C++、C++/CLI 和 C#,这可以很好地代替对 C# 的实际 cmake 支持。
    • 我想说使用 CMake 生成 C# 项目的最佳理由是远离 .csproj 文件。我对 .csproj 文件的最大问题是它们只能通过一组奇怪的对话进行编辑,结果是一个难以理解的 XML 文件。 CMake 没有遇到这些问题。
    【解决方案4】:

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

    请注意,Windows 窗体应用程序需要使用 csharp_set_windows_forms_properties CMake 命令,而 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"
    )
    

    【讨论】:

    • 太棒了!您是否考虑将其作为第二个示例(第一个必须重命名)添加到我的CMake C# example project on GitHub?如果您确实添加了 WinForms 示例并提交了拉取请求,我会将其重命名为更通用,我们也可以在此处链接它。
    • 刚刚创建了拉取请求。 WinForm 和 WPF 示例都适用于 VS 2017 和 VS 2019。
    【解决方案5】:

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

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

    【讨论】:

    • 更新:cmake 创建了带有 c# 源文件的 c++ 项目这一事实使该项目几乎无法使用 - Intellisense 不起作用,无法通过常规方式访问 app.config 等。我m 停止在这个方向上的进一步调查并切换到基于 MsBuild 的项目配置。
    【解决方案6】:

    您可以使用 Visual Studio 创建一个项目,然后将其拆开并使用 configure_file 命令让 CMake 编写它(您必须使用源列表生成一些 XML)并将其添加到解决方案中include_external_msproject(对于其他生成器,您需要创建自定义目标以手动在其上运行 msbuild;cmake 似乎还不支持这样做)。项目比较简单,应该可以做到。

    【讨论】:

      【解决方案7】:

      我想指出,现在可以使用 CMake 3.23 使用 SDK-Style 项目 XML 格式生成 C# 项目。

      虽然它仍然是一个候选版本,但它与 CMake 3.23 rc2 配合得很好。要创建 C# SDK 风格的项目,请使用 DOTNET_SDK 目标属性。

      例如,可以在这一行中使用 C# SDK 风格的项目

      set_target_properties(myTarget PROPERTIES DOTNET_SDK "Microsoft.NET.Sdk")
      

      还请记住,在使用 CMake 创建 C# 项目时,您不需要 project() 命令。 project() 命令总是创建一个可能有用但不是必需的新解决方案。可以使用enable_language(CSharp) 将 Target 声明为 C# 项目。

      为了测试 C# SDK 风格的项目,我在 Windows 上使用了 Visual Studio 2019 和 Visual Studio 16 Generator。

      【讨论】:

        猜你喜欢
        • 2010-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-27
        相关资源
        最近更新 更多