How can I create a Crystal executable file without dependencies?

I am writing a program in Crystal that I am going to compile and switch to other systems for execution. Ideally, it should not have any dependencies, since the target systems will be fresh Linux installations.

Unfortunately, I cannot get around the libc dependency, so I will probably have to compile the executable on a system that has the lowest version of libc that I want to target. I believe that it should be compatible with porting.

I'm having difficulty with libssl. By default, Debian Wheezy installations do not seem to be related to libssl, so I get this error when running my executable:

error while loading shared libraries: libssl.so.1.0.0: cannot open shared object file: No such file or directory 

I assume this dependency exists because I require "http/client" in my source. However, I do not make any ssl-related calls, as I only use them to connect to insecure websites.

I apparently also have a dependency on libevent-2.0.so.5 . Presumably all Crystal programs. Who knows how many other dependencies Crystal has?

My executables should run on a newly installed Linux system. So how can I create a Crystal executable without dependencies? Other than libc, I suppose.

+7
source share
2 answers

On Linux, you can list the shared libraries that an executable needs to execute with the ldd command. In OSX, otool -L can be used for the same purpose.

Typically, the linker will use shared libraries when creating an executable file if it can find them. So what you need to do is make the linker use static libraries instead. (In the future, we could add a flag to the compiler for forced selection)

You should find some of these static libraries in / opt / crystal / embedded / lib. We use them to create the Crystal portable compiler.

To use these libraries, you can run:

 $ LIBRARY_PATH=/opt/crystal/embedded/lib crystal build my_app.cr 

This should prefer the libraries available in this directory before considering others installed in standard places.

Unfortunately, OpenSSL does not apply to Crystal, so you must either copy or create a static version of libssl and libcrypto . This is a regular library anyway, available on any Linux distribution.

Regarding libc , this is more complicated. We collect Crystal binaries for releases using the old CentOS and Debian distributions to make it compatible with many other versions of libc.

+8
source

Crystal documents mention that the --static compiler flag currently only works on Alpine Linux (and recommends using the Alpine Linux Docker container).

If you are not a member of Docker, but you have Vagrant on your computer, you can use my Alpine box ( reltivkreativ / alpine ) instead of creating your own problems .

In any case, static binding works on Alpine.

Just follow these steps:

  • Enable community repository in /etc/apk/repositories
  • Run apk update to get a list of recent packages
  • Install Crystal using apk add crystal shards
  • Insert the correct libc using apk add libc-dev (metapackage that does just that)

Once this is done, you can compile your Crystal project with Crystal crystal build src/FILE.cr -o bin/FILE --release --static .

Now, having a Crystal binary file without dependencies allows you to easily distribute your project, for example, as an RPM (this is exactly how I found this question in the first place).

0
source

All Articles