Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compile a C# solution with Roslyn?

Tags:

c#

roslyn

I have a piece of software that generates code for a C# project based on user actions. I would like to create a GUI to automatically compile the solution so I don't have to load up Visual Studio just to trigger a recompile.

I've been looking for a chance to play with Roslyn a bit and decided to try and use Roslyn instead of msbuild to do this. Unfortunately, I can't seem to find any good resources on using Roslyn in this fashion.

Can anyone point me in the right direction?

like image 555
KallDrexx Avatar asked Nov 07 '12 23:11

KallDrexx


People also ask

How do I compile and run C code?

Step 1: Open turbo C IDE(Integrated Development Environment), click on File and then click on New. Step 2: Write the C program code. Step 3: Click on Compile or press Alt + F9 to compile the code. Step 4: Click on Run or press Ctrl + F9 to run the code.

What is the command to compile C?

Run the gcc command to compile your C program. The syntax you'll use is gcc filename. c -o filename.exe . This compiles the program and makes it executable.

How do I compile a C file in Windows?

Type "cl filename. c" (without quotes) and press the "Enter" key to compile the code page. The C file is compiled into an executable (EXE) file named "filename.exe."

Do you need a compiler to run C?

C is a mid-level language and it needs a compiler to convert it into an executable code so that the program can be run on our machine.


2 Answers

You can load the solution by using Roslyn.Services.Workspace.LoadSolution. Once you have done so, you need to go through each of the projects in dependency order, get the Compilation for the project and call Emit on it.

You can get the compilations in dependency order with code like below. (Yes, I know that having to cast to IHaveWorkspaceServices sucks. It'll be better in the next public release, I promise).

using Roslyn.Services; using Roslyn.Services.Host; using System; using System.Collections.Generic; using System.IO;  class Program {     static void Main(string[] args)     {         var solution = Solution.Create(SolutionId.CreateNewId()).AddCSharpProject("Foo", "Foo").Solution;         var workspaceServices = (IHaveWorkspaceServices)solution;         var projectDependencyService = workspaceServices.WorkspaceServices.GetService<IProjectDependencyService>();         var assemblies = new List<Stream>();         foreach (var projectId in projectDependencyService.GetDependencyGraph(solution).GetTopologicallySortedProjects())         {             using (var stream = new MemoryStream())             {                 solution.GetProject(projectId).GetCompilation().Emit(stream);                 assemblies.Add(stream);             }         }     } } 

Note1: LoadSolution still does use msbuild under the covers to parse the .csproj files and determine the files/references/compiler options.

Note2: As Roslyn is not yet language complete, there will likely be projects that don't compile successfully when you attempt this.

like image 87
Kevin Pilch Avatar answered Oct 04 '22 10:10

Kevin Pilch


I also wanted to compile a full solution on the fly. Building from Kevin Pilch-Bisson's answer and Josh E's comment, I wrote code to compile itself and write it to files.

Software Used

Visual Studio Community 2015 Update 1

Microsoft.CodeAnalysis v1.1.0.0 (Installed using Package Manager Console with command Install-Package Microsoft.CodeAnalysis).

Code

using System; using System.Collections.Generic; using System.IO; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.MSBuild;  namespace Roslyn.TryItOut {     class Program     {         static void Main(string[] args)         {             string solutionUrl = "C:\\Dev\\Roslyn.TryItOut\\Roslyn.TryItOut.sln";             string outputDir = "C:\\Dev\\Roslyn.TryItOut\\output";              if (!Directory.Exists(outputDir))             {                 Directory.CreateDirectory(outputDir);             }              bool success = CompileSolution(solutionUrl, outputDir);              if (success)             {                 Console.WriteLine("Compilation completed successfully.");                 Console.WriteLine("Output directory:");                 Console.WriteLine(outputDir);             }             else             {                 Console.WriteLine("Compilation failed.");             }              Console.WriteLine("Press the any key to exit.");             Console.ReadKey();         }          private static bool CompileSolution(string solutionUrl, string outputDir)         {             bool success = true;              MSBuildWorkspace workspace = MSBuildWorkspace.Create();             Solution solution = workspace.OpenSolutionAsync(solutionUrl).Result;             ProjectDependencyGraph projectGraph = solution.GetProjectDependencyGraph();             Dictionary<string, Stream> assemblies = new Dictionary<string, Stream>();              foreach (ProjectId projectId in projectGraph.GetTopologicallySortedProjects())             {                 Compilation projectCompilation = solution.GetProject(projectId).GetCompilationAsync().Result;                 if (null != projectCompilation && !string.IsNullOrEmpty(projectCompilation.AssemblyName))                 {                     using (var stream = new MemoryStream())                     {                         EmitResult result = projectCompilation.Emit(stream);                         if (result.Success)                         {                             string fileName = string.Format("{0}.dll", projectCompilation.AssemblyName);                              using (FileStream file = File.Create(outputDir + '\\' + fileName))                             {                                 stream.Seek(0, SeekOrigin.Begin);                                 stream.CopyTo(file);                             }                         }                         else                         {                             success = false;                         }                     }                 }                 else                 {                     success = false;                 }             }              return success;         }     } } 
like image 35
Ryan Kyle Avatar answered Oct 04 '22 10:10

Ryan Kyle