Compilation on OpenBSD

Hello,

I’ve tried to compile my project on Linux and it works great, however I have problems on OpenBSD.

The default crypto library is LibreSSL and I had to use pkg_add openssl to install OpenSSL. Fine.

Now, I try to compile my project and it doesn’t work, I guess because the OpenSSL library isn’t in the usual folder, headers are in /usr/local/include/eopenssl40/ and the library is in/usr/local/lib/eopenssl40.

But I can’t get it to work even when using shards build myprogramm -- --linker-flags='-L /usr/local/lib/eopenssl40 -lssl -lcrypto'. I still get this error:

test$ shards build authd --link-flags='-I/usr/local/include/eopenssl40/ -L/usr/local/lib/eopenssl40/ -lssl -lcrypto'         
Dependencies are satisfied
Building: authd
Error target authd failed to compile:
Showing last frame. Use --error-trace for full trace.

There was a problem expanding macro 'macro_10576938180752'

Code in lib/openssl_ext/src/openssl_ext/bio/bio.cr:10:5

 10 | {% if OpenSSL::BIO.has_method?(:ktls_recv?) %}
      ^
Called macro defined in lib/openssl_ext/src/openssl_ext/bio/bio.cr:10:5

 10 | {% if OpenSSL::BIO.has_method?(:ktls_recv?) %}

Which expanded to:

   1 | 
 > 2 |       Box(IO).unbox(LibCrypto.BIO_get_data(bio))
                                     ^-----------
Error: undefined fun 'BIO_get_data' for LibCrypto

The problem comes from the openssl_ext library (used by crystal-community/jwt).

I really don’t know what to do at this point. I can write anything in the --link-flags= parameter, it changes absolutely nothing. But I know that the library is in /usr/local/lib/eopenssl40/ :

test$ nm -g /usr/local/lib/eopenssl40/libcrypto.so.45.0 | grep BIO_get_data                                                                                                                                                                   
00251b10 T BIO_get_data

Thanks for your help.

Hello,

Crystal uses pkg-config to detect libraries.

Is pkg-config installed on your system, and can it detect your SSL library?

pkg-config --variable=includedir libssl
pkg-config --modversion libssl
pkg-config --libs libssl

However, you also set --link-flags, so this may not be the real cause.

The OpenSSL detection logic is around here

OpenSSL 4.0 support was added very recently:

This part is quite complex, so there may be some reason why detection does not work in your environment.

A similar BSD-related issue was reported a long time ago.

Also, the free AI tool DeepWiki may help you analyze this problem.

Thanks for your answer.

I tried OpenSSL 3.5, too. It doesn’t change anything.

I have pkg-config installed and it works:

test$ pkg-config --variable=includedir libssl              
/usr/include
test$ pkg-config --modversion libssl                       
2.0.0
test$ pkg-config --libs libssl                
-lssl

I don’t even get what is wrong. The error is Error: undefined fun 'BIO_get_data' for LibCrypto but this function does exist in LibCrypto and it isn’t conditioned by the detection of any library or environment. The function is just there. The error doesn’t seem to come from the linker at all.

The crystal compiler version:

test$ crystal version
Crystal 1.17.1 [19be240d1] (2025-07-22)

The compiler was not built in release mode.

LLVM: 19.1.7
Default target: x86_64-unknown-openbsd7.9

I don’t think it should be a problem, but since I’m out of ideas, idk.

EDIT: the library detection seems to fail:

test$ crystal eval 'require "openssl"; puts LibSSL::OPENSSL_VERSION'
0.0.0

I don’t know if it is of some any significance in my specific case, but it still seems wrong.

You have libressl installed and found, not openssl, and a very old and unsupported version at that. I think we only support 3.x and you probably should consider 4.x

That, or the pkg-config lies for libressl (that’s possible) and we should upgrade to a version detector based on the variables in the C headers, which is the only safe mean to detect the correct openssl/libressl version.

pkg-config might not be finding the .pc file.
If the .pc file is in a non‑standard directory, setting PKG_CONFIG_PATH may help.

Confirmed: I booted my OpenBSD 7.6 VM and /usr/lib/pkg-config/libssl.pc file is stuck to report the version as 2.0.0, despite having libressl 4.0.0 installed.

Looking at /usr/include/openssl/opensslv.h it reflects the OPENSSL_VERSION_NUMBER of 0x20000000L while LIBRESSL_VERSION_NUMBER is 0x4000000fL :person_shrugging:

@karchnu If you really want OpenSSL, you must tweak PKG_CONFIG_DIR so its libssl.pc and libcrypto.pc files can be found. We do support LibreSSL however, and you should have nothing to do.

On OpenBSD 7.6, I can run the spec/std/openssl specs from Crystal master branch with the system LibreSSL 4.0.0 without configuration issues (despite the wrong version information reported by libssl.pc which means we sadly can’t use new features).

Upgraded to OpenBSD 7.8 and no issues with LibreSSL 4.2.0 either.

Well, I’m on a fresh install of OpenBSD 7.9. Why isn’t it just working if LibreSSL is supported? In order to make it work with LibreSSL, should I create a pc file with the real version of the library?

Both LibreSSL and OpenSSL are fine by me. I just want spider-gazelle/openssl_ext to work.

Anyway, I installed OpenSSL and copied the version of libssl.pc and libcrypto.pc found in the package (they didn’t have these names exactly, so it couldn’t work out-the-box) and played with PKG_CONFIG_PATH and it worked. Thanks!

@ysbaddaden compatibility statements are about standard library support for LibreSSL.

But the error is coming from 3rd-party code in GitHub - spider-gazelle/openssl_ext: Crystal bindings for OpenSSL RSA · GitHub, which does not look like it explicitly supports LibreSSL. Also, not sure which versions of OpenSSL are supported.
Would be nice to mention supported versions somewhere. Ping @stakach

Another issue seems to be that you’re using an older version of Crystal’s standard library. Please always report which version of Crystal you’re using so people who want to help can give you the right advice.
LibCrypt.BIO_get_data should always be defined since Crystal 1.19. Since it’s missing, it means pre-1.19 stdlib detected a libcrypto version of OpenSSL < 1.1.0 or LibreSSL < 2.7.0 where this symbol doesn’t exist.
Using an older stdlib is not necessarily a problem. But upgrading to latest might even fix this problem (although there might be further issues).

It’s tested against linux, mac and windows. Not really sure what versions are supported TBH

Happy to accept pull requests or increase CI coverage to other OS’s

@stakach Did you test with LibreSSL? That’s the issue, here.