Thursday, December 17, 2015

Getting CoreCLR to run on CentOS

At work, we are forced to use CentOS (because reasons), but we also want to use CoreCLR (because other reasons). Unfortunately, CoreCLR doesn't currently work straight out of the box because of various library conflicts and missing dependencies. Fortunately, there is a way to install all of them with a little bash hands-on time.

TL;DR

Here's the short list of libraries. Further below there are concrete bash scripts for installing each.
Where versions are specified, it means that CoreCLR (as of rc2-16317) requires these particular versions, others won't work.
  • Through yum: epel-release (this is needed, because libunwind is in epel repo).
  • Through yum: automake, libtool, curl, libunwind, gettext, libcurl-devel, openssl-devel, zlib.
  • libuv: https://github.com/libuv/libuv/archive/v1.4.2.tar.gz
  • libicu 52: http://download.icu-project.org/files/icu4c/52.1/icu4c-52_1-RHEL6-x64.tgz
  • openssl 1.0.0: https://www.openssl.org/source/openssl-1.0.0t.tar.gz

dnvm

First, get DNVM (DotNet Version Manager). This is standard.

 $ curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev PROFILE=~/.bashrc sh  
 $ source ~/.dnx/dnvm/dnvm.sh  

Notice the "PROFILE=~/.bashrc" part before "sh". This is needed to make dnvminstall put bootstrap in the right place (i.e. "bashrc", not "bash_profile"), because currently it doesn't.

coreclr

Then, need to make sure unzip is installed (usually is, but just in case).

 sudo yum install -y unzip  

Now we can install CoreCLR using dnvm itself:

 dnvm install latest -r coreclr  

For extra thrill, go commando and update from "unstable dev" channel:

 dnvm install latest -u -r coreclr  

This, however, will not work out of the box because of a bunch of missing libraries. Most of them can be easily installed with yum:

# epel-release repo is needed, because libunwind is in it
sudo yum -y install epel-release
sudo yum -y install automake libtool curl libunwind gettext libcurl-devel openssl-devel zlib

libuv

But libuv isn't available like that, so needs to be installed manually:

mkdir ~/libuv
curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | tar zxfv - -C ~/libuv
pushd ~/libuv/libuv-1.4.2
sudo sh autogen.sh && ./configure && make && sudo make install
popd && rm -rf ~/libuv
sudo ldconfig

libicu52

At this point, CoreCLR beta7 is fine. But beta8 and later still require one more thing: libicu52. CentOS 7.2 comes with libicu50 standard, and there is no later versions available through yum by default (as of this writing). But even if there were, the upgrade would break some other packages already installed - welcome to dependency nightmare!
And don't even think of upgrading to 53 or later: apparently CoreCLR specifically needs version 52.

Thankfully, there is a way hack to have your cake and eat it, too: install both versions side by side, using LD_LIBRARY_PATH to make both visible.

mkdir ~/libicu52

# Note: the link below is for x64. Check your architecture.
curl -sSL http://download.icu-project.org/files/icu4c/52.1/icu4c-52_1-RHEL6-x64.tgz | tar zxfv - -C ~/libicu52
sudo cp -r ~/libicu52/usr/local/lib /opt/libicu52
rm -r ~/libicu52

# This will set the var locally, use ~/.bashrc or /etc/environment for permanence
export LD_LIBRARY_PATH=/opt/libicu52:$LD_LIBRARY_PATH

openssl 1.0.0

Next up - openssl. CentOS comes with 1.0.1, but alas, CoreCLR requires 1.0.0, and creating a symlink wouldn't do.

mkdir ~/openssl
curl -sSL https://www.openssl.org/source/openssl-1.0.0t.tar.gz | tar zxfv - -C ~/openssl
pushd ~/openssl/openssl-1.0.0t
./config shared && make && sudo make install
popd && rm -rf ~/libuv
sudo ldconfig

Notice the "./config shared" part. The argument "shared" is essential, otherwise only statically linked version will get installed.

libcurl-gnutls.4

There is already a libcurl.4 that comes with CentOS, but CoreCLR is compiled against the gnutls version for some reason. Since they provide the same API, a mere symlink solves the problem:

 sudo ln /lib64/libcurl.so.4 /lib64/libcurl-gnutls.so.4  



And voila! CoreCLR is good to go! (at least up to rc2-16317).



2 comments:

  1. Great manual!
    one small comment, after installing the open ssl 1.0.0 you should export it as well in addition to libicu52 as follows: export LD_LIBRARY_PATH=~/openssl/openssl-1.0.0t:/opt/libicu52:$LD_LIBRARY_PATH

    ReplyDelete
  2. Actually, it's a bit outdated now: CoreCLR is dropping the whole dnvm thing and moving to a different dotnet CLI thing.

    ReplyDelete