Showing posts with label dotnetcore. Show all posts
Showing posts with label dotnetcore. Show all posts

Friday, 19 August 2016

dotnet core - Native Cross Platform

Following my initial foray into the world of dotnet core I was very excited at what this offers. I can now take my C# code and really easily build and run it on any of my Windows, Linux and Mac platforms. True, I've been able to do that for a while with Mono, but the tooling seems to be making it a common operation on each and something that I can see the toolchain working well with on Docker and Cloud deployments.

Pumped up by this and reading through the final post that I mentioned in the last article I wanted to have a look at a native build of the application. There are a number of reasons for this that we'll dig in to. First of all the build completed in the last post is a dotnet portable application. Take a look in bin/Debug/netcoreapp1.0 and you can see this is creating a dll that the dotnet core exe uses to run the application. It's a jumping off point. It also means that you need to have the dotnet core runtime and libraries already installed. This is possible with Linux deploys and there are a bunch of examples out there and with a bit more faff it's possible with Docker, but I was interested in making this really simple by being able to copy over a single file.

What's more, I had a taste for wanting to be able to build on my Windows or Mac box and create the Linux cross-compiled version that I could then put on a Docker container and use in the Cloud.

In the post there is a very nice walk through of setting up for various native compile targets. This requires some modifications to the basic project.json file as follows:


{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {
  },
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "version": "1.0.0"
        }
      },
      "imports": "dnxcore50"
    }
  },
  "runtimes": {
    "win7-x64": {},
    "ubuntu.14.10-x64": {}
  }
}

A new runtimes section has been added with some targets. A list of the supported runtimes can be found in the RID catalog.

Restoring and building now gives us a new directory bin/Debug/netcoreapp1.0/win7-x64 with the following contents:














Which you can see clearly this time now contains the dotnetcore.exe that kicks things off. However, this does not look like a native exe to me and more disappointingly the ubuntu version seems to have been missed completely.

Forgetting the cross-compile for the moment, certainly there should be a native build and then I could go through some hassle, setup a Linux machine and build on that. I took a look for some other examples. This post gives some very positive early looks at dotnet core and native compiling. This time using the dotnet compile --native option. It seems that this is from a very early pre-release version and the compile option has now been scrubbed in favour of dotnet build --native.

Digging a bit more it seems that both cross-compiling and indeed native compiling has been disabled in RC2. It seems I'm not the only one to have struggled with this and taken a look also at using the --Native switch on the build option.

Not wanting to be deterred completely I decided to uninstall RC2 as I had Preview2 and install an earlier version. Getting hold of Preview1 was next to impossible. I found how to get dotnet core versions with PowerShell. After faffing around a bit I was blocked due to scripting being unhelpfull disabled on the machine I was using. Undeterred I did finally find a Preview1 msi, installed, tested and once again the native build option was not available.

As a last stab, I did download the dotnet cli source code and start kicking off a compile which didn't work directly in Visual Studio and I'd pretty much lost the energy at that point to have another round with PowerShell on another machine.

This is most frustrating as although I could probably fight this through to get it working on Docker, I'm also interested if some of the backend functions I have could be easily used as AWS Lambdas. This would allow me to reuse some existing C# code just when needed without the costs of porting. It might not be the fastest in run-time, but certainly would be beneficial in terms of reuse. This post got it to work, presumably with a build where the native option was still available.

Well, hopefully native and cross-compile will come back as I think for now I'll need to put this to one side until RC2 is out the door.

dotnet core - Getting Started

With the rise of interest in Docker containerisation and the benefits that it provides particularly in Cloud deployments I've been keeping an eye on how Microsoft are evolving their strategy to join the party. From the early initial demonstration at the 2015 Keynote (video) to the more recent inclusion of Docker properly as a first class citizen on Windows shown at DockerCon.

The parallel path to this in Nadella's open-source drive after the acquisiton of Xamarin earlier this year is the dotnet core initiative which brings dotnet more easily onto Linux and macOS. This brings Mono into the fold and at the same time by making it open-source keeps it with it's most active community.

As I have a bunch of existing C# code from various projects bringing some of that over to Linux and Docker has some interesting opportunities and potential to reuse some of the components easily in non-Azure Cloud deployments.

Getting started was no problem at all. As most of the C# has originated from Windows, I'm starting on that platform and will look later at how the tools will work on a Mac later. The target platform is for Linux - Ubuntu or CentOS. The tools are easily downloaded for the platform of choice here

Once installed it's a simple matter to make a basic Hello World example:


using System;

namespace HelloWorldSample 
{
 public static class Program 
 {
  public static void Main() 
  {
   Console.WriteLine("Hello World!");
  }
 }
}

This should be saved as program.cs in a project directory. The dotnet toolset then requires the  the basic project settings, such as the compile target and dependencies to be configured in a simple json file such as below:


{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

This can be saved in the same project directory as project.json for example.

It's now time to use the dotnet command line interface (CLI) to build the project. Run up a CMD prompt and within the directory you'll need to first pull down any dependency packages (like the referenced dlls in Visual Studio) that are used in the project. One of the key functions of the dotnet tooling is that it includes the NuGet package manager. Try the following:

dotnet restore

This will go away and download any packages you need and will also create a file project.json.lock which is used to track any of your project changes.

Now we can build and run the sample using dotnet run. This goes through a compile (build) stage and then runs the application straight after:

Neat! Using the run command again will recognise that the application has already been build and will just run it:

You'll also see that typical bin and obj directories have been created within the application.

This is great. The code is portable and the same kind of operation should run very nicely on my Mac as well.

There's a really good tutorial here that runs through much of the same example which we'll explore a bit further in the next post.