web-dev-qa-db-fra.com

Générer un projet C # à l'aide de CMake

J'essaie de générer un projet C # dans une base de code C++ CMake existante sous Windows. Après quelques recherches, je n'ai trouvé que deux projets qui ont construit leurs propres compilateurs CSharp pour CMake: gdcm et 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++ contenant des fichiers cs et, en raison des indicateurs C++ définis pour l'éditeur de liens, la génération 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, donc je n'ai pas réussi non plus.

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

50
Leonid

Depuis CMake 3.8.2 , la génération de projet CSharp est officiellement supportée par CMake.

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

  • Déclaration de projet

    project(Example VERSION 0.1.0 LANGUAGES CSharp)
    
  • Incluez CMake CSharpUtilities si vous prévoyez d'utiliser WPF ou d'autres propriétés de concepteur.

    include(CSharpUtilities)
    
  • Ajouter tout 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)
    
  • Liez les fichiers du concepteur, les fichiers xaml et les autres fichiers de propriétés avec leurs fichiers cs correspondants

    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)
    
  • Définir l'application 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 indicateurs de fichier csproj

    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 WPF fonctionnel, voir https://github.com/bemehiser/cmake_csharp_example

Pour un exemple WinForms , voir cette réponse .

34
the_storyteller

CMake 2.8.9 et versions ultérieures ajoutent un paramètre TYPE à include_external_msproject ainsi:

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

Cela vous permet de spécifier que le projet est C # (la magie GUID ci-dessus), sinon les choses sont difficiles ( voir la documentation ).

Vous souhaiterez probablement toujours utiliser le configure_file approche modèle mentionnée ailleurs avec votre .csproj fichier pour obtenir les bons chemins, sauf si vous construisez directement dans votre arbre source.

La bonne nouvelle est que vous pouvez joker vos fichiers C # dans le .csproj.template fichier comme ceci:

<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 vers l'avant de style Unix de CMake en barres obliques inverses de style Windows, sinon il compilera les fichiers mais ils ne s'afficheront pas sous forme de 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 de modèle en un vrai fichier de projet avec le bon chemin générique.

HTH.

28
Alastair Maw

Juste au cas où quelqu'un serait toujours à la recherche d'informations à ce sujet, il n'y a vraiment aucune raison de générer des projets C # avec CMake, ils sont multiplates-formes par conception. Sous Linux, les projets C # sont généralement gérés avec MonoDevelop qui peut très bien lire les fichiers .csproj de Visual Studio. Cela devrait permettre le développement multiplateforme de projets C #. Le seul problème potentiel serait si vous aviez des projets c ++ natifs mélangés à des projets c # (comme un backend écrit en c ++ avec une interface graphique en c #), dans ce cas, ayez simplement cmake copie sur vos fichiers .csproj comme s'il s'agissait de données et vous devriez être bon pour aller. CMake est destiné à configurer votre environnement de génération pour qu'il soit multiplateforme. Cela est 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 systèmes d'exploitation si vous y êtes), mais n'est pas nécessaire pour c # qui peut exécuter multiplateforme et, grâce à la conception les décisions de l'équipe mono, peuvent construire une plateforme croisée. CMake fournit d'excellents outils pour automatiser les choses, mais une grande partie de cette fonctionnalité peut être récupérée avec un fichier .csproj correctement configuré. Quoi qu'il en soit, je sais que cette question remonte à plus d'un an, mais c'est l'un des meilleurs résultats de recherche sur lesquels je suis tombé lorsque je cherchais comment faire. J'ai depuis réalisé cette réalisation.

25
Max Ehrlich

J'ai finalement pu 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 .csproj, mais je suppose que c'est la seule forme que le générateur "Visual Studio 8 2005" peut offrir.

Néanmoins, j'ai réussi à créer cette solution et à produire des exécutables et des bibliothèques de DLL.

2
Leonid

Pour se greffer sur la réponse fournie par @the_storyteller, CMake v3.8 et supérieur prend en charge C # en tant que langage de première classe. Un exemple WPF étant déjà fourni, voici un exemple CMake complet pour une simple application Windows Forms. J'ai fourni les commandes facultatives pour la liaison dans d'autres bibliothèques construites localement dans l'arborescence source et la liaison des dépendances de bibliothèque tierces.

Notez que les applications Windows Forms nécessitent l'utilisation de csharp_set_windows_forms_properties CMake, tandis que les projets WPF utilisent csharp_set_designer_cs_properties et 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"
)
2
squareskittles

Vous pouvez créer un projet avec Visual Studio, le démonter et le faire écrire par CMake à l'aide de configure_file commande (vous devrez générer un peu de XML avec la liste des sources) et l'ajouter à la solution avec include_external_msproject (pour les autres générateurs, vous devrez créer la cible personnalisée pour exécuter manuellement msbuild dessus; cmake ne semble pas encore le faire). Le projet est assez simple, il devrait donc être possible de le faire.

1
Jan Hudec