58 votes

Générer un projet C# en utilisant CMake

J'essaie de générer un projet C# au sein d'une base de code C++ CMake existante sous Windows. Après quelques recherches, je n'ai pu trouver que deux projets qui ont construit leurs propres compilateurs CSharp pour CMake : gdcm y kde .

J'ai essayé les deux. Malheureusement, le premier n'a pas réussi à générer un projet C#. Au lieu de cela, il a créé un projet VS C++ avec des fichiers cs, et en raison des drapeaux C++ définis pour le linker, la construction a toujours échoué avec des erreurs. Après avoir expérimenté avec l'exemple de projet qu'ils ont fourni, je me demande si cela pourrait être dû à une limitation du générateur de code "Visual Studio 8 2005" ?

Le deuxième projet était principalement destiné à Mono, et je n'ai donc pas réussi non plus.

Quelqu'un a-t-il eu une expérience positive dans la construction de projets C# en utilisant un de ces modules CMake ou autre ?

50voto

the_storyteller Points 1201

A partir de CMake 3.8.2 La génération de projets CSharp est officiellement supportée par CMake.

Pour construire le projet C#/WPF généré par défaut par Visual Studio 2017 à l'aide de CMake, créez un fichier CMakeList.txt comme suit.

  • Déclaration de projet

    project(Example VERSION 0.1.0 LANGUAGES CSharp)
  • Inclure CMake CSharpUtilities si vous envisagez d'utiliser WPF ou d'autres propriétés du concepteur.

    include(CSharpUtilities)
  • Ajouter tous 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)
  • Lier les fichiers du concepteur, xaml et d'autres fichiers de propriétés avec leur cs fichiers

    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)
  • Set app App.xaml fichier de propriétés comme point d'entrée du programme (si le projet est un projet WPF)

    set_property(SOURCE App.xaml PROPERTY VS_XAML_TYPE "ApplicationDefinition")
  • Définir d'autres csproj drapeaux de fichiers

    set_property(TARGET Example PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
    set_property(TARGET Example PROPERTY WIN32_EXECUTABLE TRUE)
    ...
  • Ajouter des bibliothèques

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

Pour un exemple fonctionnel de WPF, voir https://github.com/bemehiser/cmake_csharp_example

Pour un WinForms exemple, voir cette réponse .

29voto

Alastair Maw Points 1549

CMake 2.8.9 et plus ajoutent un TYPE pour include_external_msproject comme ça :

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

Cela vous permet de spécifier que le projet est C# (le GUID magique ci-dessus), sinon les choses se compliquent ( voir docs ).

Vous voudrez probablement continuer à utiliser l'option configure_file l'approche par modèle mentionnée ailleurs avec votre .csproj pour y mettre les bons chemins, à moins que vous ne construisiez directement dans votre arbre source.

La bonne nouvelle est que vous pouvez utiliser des caractères génériques pour vos fichiers C# dans le fichier .csproj.template comme suit :

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

Et vous aurez besoin de quelque chose comme ça dans votre CMakeLists.txt pour convertir les séparateurs de chemin forwardslash de CMake de style unix en backslashes de style Windows, sinon il compilera les fichiers mais ils n'apparaîtront pas comme liens dans le projet dans Visual Studio :

FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" DOS_STYLE_SOURCE_DIR)

Alors c'est juste :

CONFIGURE_FILE(MyProject.csproj.template MyProject.csproj)

Dans votre CMakeLists.txt pour configurer le fichier modèle en un véritable fichier de projet avec le bon chemin d'accès.

HTH.

1 votes

Pourriez-vous donner un exemple complet (ou un lien vers un exemple) de la façon de : (1) Copier le dossier et les fichiers C# source ; (2) le modèle .csproj.template et comment l'utiliser ; et (3) comment mettre à jour CMakeLists.txt pour faire tout cela ?

3 votes

Il n'est pas nécessaire de copier le dossier/fichiers source C# - ils sont référencés sur place. Le fichier csproj.template est identique à n'importe quel autre fichier csproj, à l'exception du caractère générique mentionné ci-dessus. Il suffit d'en copier un. J'ai ajouté la commande CONFIGURE_FILE réelle à ma réponse, qui était la seule chose manquante.

0 votes

Ai-je besoin d'un CMakeLists.txt supplémentaire dans mon dossier C# ou tous ces changements se produisent-ils dans le CMakeLists.txt de base ? Si elles se produisent dans le Root CMakeLists.txt, dois-je les mettre avant ou après l'appel à include_external_msproject() ?

24voto

Max Ehrlich Points 632

Au cas où quelqu'un chercherait encore des informations à ce sujet, il n'y a vraiment aucune raison de générer des projets C# avec CMake, ils sont multiplateformes par conception. Sous Linux, les projets C# sont généralement gérés avec MonoDevelop qui peut lire les fichiers .csproj de Visual Studio sans problème. Cela devrait permettre le développement multiplateforme des projets C#. Le seul problème potentiel serait si vous aviez des projets natifs c++ mélangés avec des projets c# (comme un backend écrit en c++ avec une interface graphique en c#), dans ce cas, il suffit que cmake copie vos fichiers .csproj comme s'il s'agissait de données et vous devriez être prêt. CMake est destiné à configurer votre environnement de construction pour être multiplateforme. Cela s'avère très pratique avec c++ où le code est construit d'une manière très différente sur linux que sur Windows (ou d'autres OS si vous aimez ça), mais c'est plutôt inutile pour c# qui peut être exécuté sur plusieurs plateformes et, grâce aux décisions de conception de l'équipe mono, peut être construit sur plusieurs plateformes. CMake fournit d'excellents outils pour automatiser les choses, mais la plupart de ces fonctionnalités peuvent être récupérées avec un fichier .csproj correctement configuré. Quoi qu'il en soit, je sais que cette question date de plus d'un an, mais c'est l'un des premiers résultats de recherche sur lequel je suis tombé lorsque j'ai cherché comment faire cela. Depuis, je me suis rendu compte de la situation.

4 votes

Oui, mais alors que cmake fournit également une fonctionnalité d'installation, les projets C# simples (csproj) ne le font pas. Je serais intéressé par la fonctionnalité "make && make install" pour les projets C# si cmake pouvait la fournir.

0 votes

Il n'est pas difficile de mettre en place un événement post-construction pour cela. Si vous devez vous intégrer dans un système de construction cmake existant, vous pouvez même utiliser la commande cmake configure_file pour indiquer l'emplacement d'installation correct.

32 votes

Il y a une bonne raison de générer des projets C# par CMake. Si vous avez un projet mixte natif + C++/CLI + C# avec beaucoup de configuration faite par CMake, vous avez besoin que le projet C# prenne en compte la configuration faite dans CMake et se réfère aux projets générés pour C++ et soit inclus dans la bonne solution.

8voto

squareskittles Points 161

Pour faire suite à la réponse fournie par @the_storyteller, CMake v3.8 et plus supporte effectivement C# comme un langage de première classe. Comme un exemple WPF a déjà été fourni, voici un exemple CMake complet pour une simple application Windows Forms. J'ai fourni les commandes optionnelles pour lier d'autres bibliothèques construites localement dans l'arbre source, et lier les dépendances de bibliothèques tierces.

Notez que les applications Windows Forms nécessitent l'utilisation de l'option csharp_set_windows_forms_properties CMake, alors que les projets WPF utilisent csharp_set_designer_cs_properties y csharp_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"
)

2voto

Leonid Points 300

J'ai finalement réussi à générer une solution valide en utilisant le deuxième module c# - kde. Bien que cmake ait créé un certain nombre de fichiers .vcproj alors que je m'attendais à obtenir des .csproj, je suppose que c'est la seule forme que le générateur "Visual Studio 8 2005" peut offrir.

Néanmoins, j'ai pu construire cette solution avec succès et produire des exécutables et des bibliothèques dll.

1 votes

Mise à jour : le fait que cmake ait créé des projets c++ avec des fichiers source c# rend le projet presque inutilisable - Intellisense ne fonctionne pas, app.config ne peut pas être accédé par les moyens habituels, etc. J'arrête les recherches dans cette direction et je passe à la configuration de projet basée sur MsBuild.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X