Having a Look at dotnet CLI Tool and .NET Native Compilation in Linux

dotnet CLI tool can be used for building .NET Core apps and for building libraries through your development flow (compiling, NuGet package management, running, testing, etc.) on various operating systems. Today, I will be looking at this tool in Linux, specifically its native compilation feature.
2016-01-03 18:20
Tugberk Ugurlu


I have been following ASP.NET 5 development from the very start and it has been an amazing experience so far. This new platform has seen so many changes both on libraries and concepts throughout but the biggest of all is about to come. The new command line tools that ASP.NET 5 brought to us like dnx and dnu will vanish soon. However, this doesn’t mean that we won’t have a command line first experience. Concepts of these tools will be carried over by a new command line tool: dotnet CLI.

Note that dotnet CLI is not even a beta yet. It’s very natural that some of the stuff that I show below may change or even be removed. So, be cautious.

image

Scott Hanselman gave an amazing introduction to this tool in his blog post. As indicated in that post, new dotnet CLI tool will give a very similar experience to us compared to other platforms like Go, Ruby, Python. This is very important because, again, this will remove another entry barrier for the newcomers.

You can think of this new CLI tool as combination of following three in terms of concepts:

  • csc.exe
  • msbuild.exe
  • nuget.exe

Of course, this is an understatement but it will help you get a grasp of what that tools can do. One other important aspect of the tool is to be able to bootstrap your code and execute it. Here is how:

In order to install dotnet CLI tool into my Ubuntu machine, I just followed the steps on the Getting Started guide for Ubuntu.

image

Step one is to create a project structure. My project has two files under "hello-dotnet" folder. Program.cs:

using System;

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

project.json:

{
    "version": "1.0.0-*",
    "compilationOptions": {
        "emitEntryPoint": true
    },

    "dependencies": {
        "Microsoft.NETCore.Runtime": "1.0.1-beta-*",
        "System.IO": "4.0.11-beta-*",
        "System.Console": "4.0.0-beta-*",
        "System.Runtime": "4.0.21-beta-*"
    },

    "frameworks": {
        "dnxcore50": { }
    }
}

These are the bare essentials that I need to get something outputted to my console window. One important piece here is the emitEntryPoint bit inside the project.json file which indicates that the module will have an entry point which is the static Main method by default.

The second step here is to restore the defined dependencies. This can be done through the "dotnet restore" command:

image

Finally, we can now execute the code that we have written and see that we can actually output some text to console. At the same path, just run "dotnet run" command to do that:

image

Very straight forward experience! Let’s just try to compile the code through "dotnet compile" command:

image

Notice the "hello-dotnet" file there. You can think of this file as dnx which can just run your app. It’s basically the bootstrapper just for your application.

image

So, we understand that we can just run this thing:

image

Very nice! However, that’s not all! This is still a .NET application which requires a few things to be in place to be executed. What we can also do here is to compile native, standalone executables (just like you can do with Go).

image

Do you see the "--native" switch? That will allow you to compile the native executable binary which will be specific to the acrhitecture that you are compiling on (in my case, it’s Ubuntu 14.04):

image

"hello-dotnet" file here can be executed same as the previous one but this time, it’s all machine code and everything is embedded (yes, even the .NET runtime). So, it’s very usual that you will see a significant increase in the size:

image

This is a promising start and amazing to see that we have a unified tool to rule them all (famous last words). The name of the tool is also great, it makes it straight forward to understand based on your experiences with other platforms and seeing this type of command line first architecture adopted outside of ASP.NET is also great and will bring consistency throughout the ecosystem. I will be watching this space as I am sure there will be more to come :)

Resources



Comments

Mark Rendle
by Mark Rendle on Wednesday, Jan 06 2016 14:06:49 +00:00
Thanks for the post, very informative. I haven't had a play with the `dotnet` command yet, but obviously I should. One question, and I don't know if you'll have found the answer while writing this: The output with the `--native` flag includes the `System.Native.so` shared library. Do you know if there will be an option to statically-link that library at compile time, to get a true standalone executable?
Tugberk
by Tugberk on Monday, Jan 18 2016 10:23:58 +00:00
@mark Good question! I assume there will be something in the near feature to handle that but I haven't dug into that. I should probably update the blog post indicating that.
zapya
by zapya on Tuesday, Oct 25 2016 11:22:34 +00:00
Download Zapya for PC to share files and folders easily from PC to other devices
Blog comments are temporarily disabled. Even if it's not the best experience, you can send your comments to me through Twitter for now.

Tags