web-dev-qa-db-fra.com

Est-il possible de compiler un seul fichier de code C # avec le compilateur Roslyn au cœur .net?

Dans l'ancien .net, nous pouvions utiliser le compilateur csc pour compiler un seul fichier cs ou plusieurs fichiers. Avec .net core, nous avons dotnet build qui insiste pour avoir un fichier de projet approprié. Existe-t-il un compilateur autonome en ligne de commande permettant de compiler des fichiers de code source sans projet (et répertoriant les dépendances référencées sur la même ligne de commande)?

Sous Linux, lorsque l'ancien csc et le nouveau noyau .net sont installés, je reçois les timings suivants:

[root@li1742-80 test]# time dotnet build
Microsoft (R) Build Engine version 15.3.409.57025 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  test -> /root/test/bin/Debug/netcoreapp2.0/test.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:03.94

real    0m7.027s
user    0m5.714s
sys     0m0.838s

[root@li1742-80 test]# time csc Program.cs
Microsoft (R) Visual C# Compiler version 2.3.0.61801 (3722bb71)
Copyright (C) Microsoft Corporation. All rights reserved.


real    0m0.613s
user    0m0.522s
sys     0m0.071s
[root@li1742-80 test]#

Notez 7 secondes avec le noyau .net par rapport à plusieurs centaines de millisecondes avec l'ancien csc pour le même Program.cs.

J'aimerais pouvoir compiler aussi rapidement avec le noyau .net que j’ai pu le faire avec csc.

16
Andrew Savinykh

Oui, il est possible de compiler un fichier avec des compilateurs csc ou vbc dans .NET Core.

; TL; DR; Pour appeler directement le compilateur Roslyn, il est nécessaire d'utiliser le pilote de ligne de commande csc. {Exe | dll} et, comme Roslyn, contrairement à l'ancien fichier csc.exe, ne fait pas référence implicitement à mscorlib.dll, il est nécessaire de passer à la référence des dépendances requises. c'est-à-dire les bibliothèques System.Runtime et System.Private.CoreLib et toute autre référence requise. La liste suivante montre comment compiler le programme HelloWorld suivant.

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Utiliser WSL avec Ubuntu 16.04 et dotnet-sdk-2.0.0 installé:

time dotnet /usr/share/dotnet/sdk/2.0.0/Roslyn/csc.exe -r:/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0/System.Private.CoreLib.dll -r:/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0/System.Console.dll -r:/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0/System.Runtime.dll HelloWorld.cs
Microsoft (R) Visual C# Compiler version 2.3.2.61921 (ad0efbb6)
Copyright (C) Microsoft Corporation. All rights reserved.

real    0m0.890s
user    0m0.641s
sys     0m0.250s

ls -li
total 4
 4785074604720852 -rw-rw-rw- 1 developer developer  178 Dec  7 15:07 HelloWorld.cs
11821949022487213 -rw-rw-rw- 1 developer developer 4096 Dec  7 15:13 HelloWorld.exe

Les dépendances requises qui sont passées au compilateur sont différentes sur différentes plates-formes. Sous Windows, il suffit donc de transmettre System.Runtime.dll et System.Console.dll, tandis que sur Ubuntu 16.04, il est nécessaire de passer en plus System.Private.CoreLib.dll. Roslyn et les pilotes de ligne de commande de différentes versions du SDK sont situés à des emplacements différents (modifications de la présentation du SDK entre les versions) et le SDK 2.2.2 le plus récent est livré avec csc.dll et vbc.dll au lieu de csc.exe et vbc.exe. Par conséquent, avant d'utiliser cette méthode, il est nécessaire de vérifier la disposition de votre SDK.

Explication détaillée

Le compilateur Roslyn a été conçu de manière légèrement différente des compilateurs csc.exe et vbc.exe déjà utilisés. Tout d'abord, Roslyn est écrite en C # et VB et est une application .NET gérée. Sous Windows, il s’agissait principalement d’un service commun fonctionnant dans un processus serveur VBCSCompiler.exe (.dll). Cependant, Roslyn est livré avec les pilotes de ligne de commande gérés csc.exe et vbc.exe (les dernières versions du SDK dotnet sont livrés avec csc.dll et vbc.dll) qui peuvent être utilisés pour compiler les fichiers source directement à partir de la ligne de commande. Quoi qu’il en soit, c’est exactement ce que le système de compilation de dotnet appelle Roslyn via une ligne de commande. L'exécution de la simple commande dotnet csc.exe -help imprimera des informations d'utilisation qui vous guideront dans l'utilisation du compilateur directement à partir de la ligne de commande (voir dernière liste). 

La différence majeure entre les anciens compilateurs natifs et Roslyn est due au fait que cette dernière est une application gérée, c'est une heure de démarrage. Même après avoir été compilé dans des assemblys natifs R2R (Ready To Run), Roslyn devrait commencer par charger tout le framework dotnet, puis l'initialiser, puis charger les assemblys Roslyn et lancer le processus de compilation. Cependant, il est toujours un peu plus lent que d’exécuter un compilateur natif, comme on peut le voir avec les timings précédents, pas beaucoup plus lentement.

Il y a quelques jours, un nouvel article de documentation a été ajouté à corefx repo décrivant Scénario avancé - Créez et exécutez le code d'application avec csc/vbc et CoreRun . Toute personne intéressée peut l’utiliser comme guide pour travailler au niveau bas de .NET Core.

    Microsoft (R) Visual C# Compiler version 2.3.2.61921 (ad0efbb6)
Copyright (C) Microsoft Corporation. All rights reserved.


                              Visual C# Compiler Options

                        - OUTPUT FILES -
 /out:<file>                   Specify output file name (default: base name of
                               file with main class or first file)
 /target:exe                   Build a console executable (default) (Short
                               form: /t:exe)
 /target:winexe                Build a Windows executable (Short form:
                               /t:winexe)
 /target:library               Build a library (Short form: /t:library)
 /target:module                Build a module that can be added to another
                               Assembly (Short form: /t:module)
 /target:appcontainerexe       Build an Appcontainer executable (Short form:
                               /t:appcontainerexe)
 /target:winmdobj              Build a Windows Runtime intermediate file that
                               is consumed by WinMDExp (Short form: /t:winmdobj)
 /doc:<file>                   XML Documentation file to generate
 /refout:<file>                Reference Assembly output to generate
 /platform:<string>            Limit which platforms this code can run on: x86,
                               Itanium, x64, arm, anycpu32bitpreferred, or
                               anycpu. The default is anycpu.

                        - INPUT FILES -
 /recurse:<wildcard>           Include all files in the current directory and
                               subdirectories according to the wildcard
                               specifications
 /reference:<alias>=<file>     Reference metadata from the specified Assembly
                               file using the given alias (Short form: /r)
 /reference:<file list>        Reference metadata from the specified Assembly
                               files (Short form: /r)
 /addmodule:<file list>        Link the specified modules into this Assembly
 /link:<file list>             Embed metadata from the specified interop
                               Assembly files (Short form: /l)
 /analyzer:<file list>         Run the analyzers from this Assembly
                               (Short form: /a)
 /additionalfile:<file list>   Additional files that don't directly affect code
                               generation but may be used by analyzers for producing
                               errors or warnings.
 /embed                        Embed all source files in the PDB.
 /embed:<file list>            Embed specific files in the PDB

                        - RESOURCES -
 /win32res:<file>              Specify a Win32 resource file (.res)
 /win32icon:<file>             Use this icon for the output
 /win32manifest:<file>         Specify a Win32 manifest file (.xml)
 /nowin32manifest              Do not include the default Win32 manifest
 /resource:<resinfo>           Embed the specified resource (Short form: /res)
 /linkresource:<resinfo>       Link the specified resource to this Assembly
                               (Short form: /linkres) Where the resinfo format
                               is <file>[,<string name>[,public|private]]

                        - CODE GENERATION -
 /debug[+|-]                   Emit debugging information
 /debug:{full|pdbonly|portable|embedded}
                               Specify debugging type ('full' is default,
                               'portable' is a cross-platform format,
                               'embedded' is a cross-platform format embedded into
                               the target .dll or .exe)
 /optimize[+|-]                Enable optimizations (Short form: /o)
 /deterministic                Produce a deterministic Assembly
                               (including module version GUID and timestamp)
 /refonly                      Produce a reference Assembly in place of the main output
 /instrument:TestCoverage      Produce an Assembly instrumented to collect
                               coverage information
 /sourcelink:<file>            Source link info to embed into PDB.

                        - ERRORS AND WARNINGS -
 /warnaserror[+|-]             Report all warnings as errors
 /warnaserror[+|-]:<warn list> Report specific warnings as errors
 /warn:<n>                     Set warning level (0-4) (Short form: /w)
 /nowarn:<warn list>           Disable specific warning messages
 /ruleset:<file>               Specify a ruleset file that disables specific
                               diagnostics.
 /errorlog:<file>              Specify a file to log all compiler and analyzer
                               diagnostics.
 /reportanalyzer               Report additional analyzer information, such as
                               execution time.

                        - LANGUAGE -
 /checked[+|-]                 Generate overflow checks
 /unsafe[+|-]                  Allow 'unsafe' code
 /define:<symbol list>         Define conditional compilation symbol(s) (Short
                               form: /d)
 /langversion:<string>         Specify language version mode: ISO-1, ISO-2, 3,
                               4, 5, 6, 7, 7.1, Default, or Latest

                        - SECURITY -
 /delaysign[+|-]               Delay-sign the Assembly using only the public
                               portion of the strong name key
 /publicsign[+|-]              Public-sign the Assembly using only the public
                               portion of the strong name key
 /keyfile:<file>               Specify a strong name key file
 /keycontainer:<string>        Specify a strong name key container
 /highentropyva[+|-]           Enable high-entropy ASLR

                        - MISCELLANEOUS -
 @<file>                       Read response file for more options
 /help                         Display this usage message (Short form: /?)
 /nologo                       Suppress compiler copyright message
 /noconfig                     Do not auto include CSC.RSP file
 /parallel[+|-]                Concurrent build.
 /version                      Display the compiler version number and exit.

                        - ADVANCED -
 /baseaddress:<address>        Base address for the library to be built
 /checksumalgorithm:<alg>      Specify algorithm for calculating source file
                               checksum stored in PDB. Supported values are:
                               SHA1 (default) or SHA256.
 /codepage:<n>                 Specify the codepage to use when opening source
                               files
 /utf8output                   Output compiler messages in UTF-8 encoding
 /main:<type>                  Specify the type that contains the entry point
                               (ignore all other possible entry points) (Short
                               form: /m)
 /fullpaths                    Compiler generates fully qualified paths
 /filealign:<n>                Specify the alignment used for output file
                               sections
 /pathmap:<K1>=<V1>,<K2>=<V2>,...
                               Specify a mapping for source path names output by
                               the compiler.
 /pdb:<file>                   Specify debug information file name (default:
                               output file name with .pdb extension)
 /errorendlocation             Output line and column of the end location of
                               each error
 /preferreduilang              Specify the preferred output language name.
 /nostdlib[+|-]                Do not reference standard library (mscorlib.dll)
 /subsystemversion:<string>    Specify subsystem version of this Assembly
 /lib:<file list>              Specify additional directories to search in for
                               references
 /errorreport:<string>         Specify how to handle internal compiler errors:
                               Prompt, send, queue, or none. The default is
                               queue.
 /appconfig:<file>             Specify an application configuration file
                               containing Assembly binding settings
 /moduleassemblyname:<string>  Name of the Assembly which this module will be
                               a part of
 /modulename:<string>          Specify the name of the source module
12
Jacek Blaszczynski

Le compilateur peut être directement appelé à l'aide de

$ /usr/local/share/dotnet/sdk/2.0.0/Roslyn/RunCsc.sh

Toutefois, cette commande particulière peut ne pas être utile sans une infrastructure de projet prise en charge car vous devez transmettre manuellement tous les assemblys de référence .NET Core ou .NET Standard, qui sont normalement gérés par le SDK et NuGet. Vous obtiendrez des erreurs comme celle-ci:

$ /usr/local/share/dotnet/sdk/2.0.0/Roslyn/RunCsc.sh Program.cs
Microsoft (R) Visual C# Compiler version 2.3.2.61921 (ad0efbb6)
Copyright (C) Microsoft Corporation. All rights reserved.

Program.cs(1,7): error CS0246: The type or namespace name 'System' could not be found (are you missing a using directive or an Assembly reference?)
Program.cs(5,11): error CS0518: Predefined type 'System.Object' is not defined or imported
Program.cs(7,26): error CS0518: Predefined type 'System.String' is not defined or imported
Program.cs(7,16): error CS0518: Predefined type 'System.Void' is not defined or imported
4
Martin Ullrich

En bref, il n'est pas pris en charge sans projet prédéfini.

Mais le commentaire de @ Andrew montre qu'il est toujours possible si vous êtes prêt à répertorier toutes les dépendances, y compris les dépendances système implicites dans les options de ligne de commande.

À partir de erreur CS0518: le type prédéfini 'System.Object' n'est pas défini ou importé # 12393 :

Pour le moment, nous n’avons pas l’intention de faciliter l’utilisation de csc.exe dans ce fichier manière. Le guide consiste à utiliser les outils CLI de dotnet pour le moment étant. Même si des modifications devaient être apportées ici, elles seraient activées le cadre pour fournir une référence unifiée et/ou simplifiée assemblées pour le compilateur. Le compilateur n'aura jamais plus type compliqué ou résolution de l’Assemblée qu’aujourd’hui (par conception).

Voir aussi closed Permet d'invoquer directement le compilateur # 7689 .

0
Vadzim