Run executable on another computer without crystal installed?

I have built a simple User Agent for macOS, and it runs perfectly on my machine, but when I try to install it on anyone else’s machine, I get the following error:

dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
Referenced from: /Users/USERNAME/Desktop/binary
Reason: image not found
Trace/BPT trap: 5

I am only using crystal’s standard API. I am not using anything that requires SSL, I am only making an HTTP request, not HTTPS.

In this particular case you can compile your program with -D without_openssl. However I can’t guarantee that will work forever. And in general, you need the target machine to have more or less the same libraries as the machine you compile your program in.

2 Likes

More general: The target machine needs to have the libraries available which the binary was linked with.

2 Likes

Thanks for your reply. I just tested it, and it is giving a different error. Even why I try crystal build src/app.cr --static -D without_openssl without_libgc

dyld: Library not loaded: /usr/local/opt/bdw-gc/lib/libgc.1.dylib
Referenced from: /Volumes/DRIVE/binary
Reason: image not found
Trace/BPT trap: 5

I don’t think without_libgc is a valid compiler flag. There is gc_none which is probably what you mean. But it’s probably not a good idea to compile without GC because it will eventually break you program. The stdlib expects a working GC.

The solution is probably to install the proper bwdgc library on your system.

That we have without_openssl doesn’t mean you can exclude any library. Only that flag, and one to exclude zlib exist. The reason is the compiler includes an HTTP::Server and distributing that with openssl and zlib is a bit hard so we compile it without those things. It’s a hack. Eventually those flags will disappear and the HTTP::Server won’t be needed in the compiler as the playground will be extracted to a different binary.

1 Like

Is there a way I can use relative paths, and create a folder for the compiled crystal program to run in along with the libraries? My goal is to be able to install this on a brand new mac, without any command line installation of libraries or the crystal language.

You should be able to ship dynamic libraries with your binary and use LD_LIBRARY_PATH to add their location to the paths that are looked up for finding dynamic libraries. I’m not sure if there are any specific caveats on MacOS.

However, as far as I understand the static linking problem on MacOS, the issue are actually system libraries which are only available as dynamic libraries. So you can’t link a fully dynamic binary. But you can build static libraries. And as long as you have those .a files available, you can link them into your binary. This seems to need some trickery if a dynamic variant of the same library is also available, but it’s manageable. See https://github.com/crystal-lang/crystal/issues/2003#issuecomment-170331227 and following comments for some more details on this.

So you should be able to build a binary that has all custom libraries statically linked.