whyoleg / cryptography-kotlin

Kotlin Multiplatform cryptography / crypto library
https://whyoleg.github.io/cryptography-kotlin/
Apache License 2.0
285 stars 18 forks source link

Error in build: undefined references #11

Closed btwonion closed 6 months ago

btwonion commented 10 months ago

Hi, whenever i execute linuxX64Binaries i get this error: https://pastes.dev/sru6wccvSU . I hope you can help me.

whyoleg commented 10 months ago

Hey! Could you please provide some information about which specific dependency you are adding to the project? I mean, the log shows, that it can't find openssl declarations, this means that libcrypto is not found. Looks like you are adding only cryptography-provider-openssl3-api and there is no libcrypto in it. For more information of openssl provider, and difference in artefacts you can take a look in documentation here: https://whyoleg.github.io/cryptography-kotlin/modules/cryptography-provider-openssl3/ Quote regarding api artefact:

Module doesn’t provide any configuration of how it should be linked to libcrypto library, and so building final binary will fail unless correct linking arguments will be provided

Most likely you need to use cryptography-provider-openssl3-shared or cryptography-provider-openssl3-prebuilt instead of cryptography-provider-openssl3-api

btwonion commented 10 months ago

this is my subproject build script: https://pastes.dev/7wz1ZChliP as you can see i use prebuilt already

whyoleg commented 10 months ago

Thank you! Looks like something related to sharedLib configuration - I will take a look and come back with more information. Also, BTW, Im not sure, that prebuilt variant will work with sharedLib, as prebuilt include linking to static library. Also I have no idea how export work there, as I never tried it.

BTW, what is your use case for sharedLib configuration and overall?

btwonion commented 10 months ago

thanks. i just want to export the required libraries to my executable. is this not the common way to do so?

btwonion commented 10 months ago

also with the shared dependency on top it adds this error to the output: /home/antonw/.konan/dependencies/x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2/x86_64-unknown-linux-gnu/bin/ld.gold: error: cannot find -lcrypto

whyoleg commented 10 months ago

So, what I could say after a little testing: 1. I've reproduced the issue at my side (though, with macOS, not with linux, but it doesn't matter) with prebuilt dependency

2. The issue comes from building shared library with dependency on statically linked openssl - which, as I said earlier will not work AFAIK

3. So to overcome 2, if you need to build sharedLib, you need to use shared dependency - in this case, to build binary you need to have libcrypto in one of default paths like said in documentation:

Embedded linking arguments use default paths, where openssl3 is installed, though if it’s installed in a custom directory, additional configuration will be required

Default paths for linux are:

The error message like this: error: cannot find -lcrypto, says, that there is no libcrypto there, so you need to provide it somehow to K/N compiler via link path. F.e. via linkerOpts.add("-L/path/to/openssl") in executable or sharedLib. Also, libcrypto there should be compatible with K/N toolchain. Yeah, working with shared native libraries is hard...

5. Im not fully sure, how export works for sharedLib, I always thought that it works only for XCFramework (Apple) - at my side I don't see difference in produced binaries and headers when you add export for sharedLib - so I think it's redundant

6. Regarding:

i just want to export the required libraries to my executable. is this not the common way to do so?

If you just want to create executable you don't need to create sharedLib configuration and everything will work with prebuilt variant out of the box then.

Feel free to ask any other question, I will try to help as much as I can!

btwonion commented 10 months ago

okay. i removed the sharedLib block and it seems like (atm during compile time) it is not necessary. i also installed openssl manually and linked its executable via linkerOpts, but the error persists. what exactly do you mean with

libcrypto there should be compatible with K/N toolchain ?

whyoleg commented 10 months ago

What do you mean by "linked its executable via linkerOpts"?

K/N uses rather old GCC (8 if I remember correctly), so if libcrypto is built with much newer toolchain it could fail to link (because of glibc version)

btwonion commented 10 months ago

this is my linux target now:

linuxX64 {
    binaries {
      executable {
        entryPoint = "fyi.pauli.ichor.hephaistos.main"
        linkerOpts.add("-L/usr/lib/openssl")
      }
    }
  }

i also only tried the openssl rpm package, which's executable is only moved to /usr/bin (https://packages.fedoraproject.org/pkgs/openssl/openssl/fedora-39.html#files). just thought maybe this could be added here, too: https://github.com/whyoleg/cryptography-kotlin/blob/main/cryptography-providers/openssl3/shared/src/commonMain/cinterop/linking.def

whyoleg commented 10 months ago

If you want to use shared and built on fedora you need to install openssl-libs because for linking you don't need openssl cli, but openssl provided native libraries - in case of cryptography-kotlin it's libcrypto (openssl also provides libssl which implements TLS) https://packages.fedoraproject.org/pkgs/openssl/openssl-libs/fedora-39.html

And as I see there, libraries will be put in /usr/lib64/ - which is already in the linking.def file, so no additional config is needed.

BTW, Could you share a little more information about your final use case? Which specific functionality do you need from cryptography-kotlin and how it will be used? I mean, will it be a library, CLI application, or something else? This will help me to understand, what could be missing at my side and may be how can I improve documentation. Thank you in advance!

btwonion commented 10 months ago

okay. i use this library for the RSA keypair atm. finally it should be an minecraft server reimplementation based on kotlin multiplatform, which is why i chose the openssl provider for my non-jvm target.

btwonion commented 10 months ago

It looks like i have libcrypto already installed. Then i don't have to add a linkerOpt manually, right? Furthermore, what exactly is the fix for the error then?

whyoleg commented 10 months ago

It looks like i have libcrypto already installed. Then i don't have to add a linkerOpt manually, right?

Yes, that's right, if you want to use shared variant and you have it installed in default paths you don't need to provide any additional setup. Though, know that you will need to have it also on a machine where you are planning to run the app.

Furthermore, what exactly is the fix for the error then?

Could you clarify once more, which specific error?

Overall, if you do want to use sharedLib you need to use only shared dependency (but Im really not sure that this is what you need). If you don't need sharedLib and only need to be able to use executable - you can safely use prebuilt variant instead - no additional setup is needed.

BTW, If there will be some reproducer (on GitHub f.e.) it will be easier for me to help with specific issues.

btwonion commented 10 months ago

with this build script: https://pastes.dev/WwUG2LFcHs im encountering this error: https://pastes.dev/pDNOXCoZHN and i have the files libcrypto.so.3.1.1 and libcrypto.so.3 (a link to 3.1.1) located in /lib64/

whyoleg commented 10 months ago

Thank you! I don't have Linux machine at my side, but I tested several configurations on CI and I was able to reproduce the issue. In the end, looks like the issue is on Kotlin side (related to caches) and to workaround It for now you need to add kotlin.native.cacheKind.linuxX64=none to gradle.properties - this issue is reproduced only when building debug binaries on linux machine, so that it was hard to debug... I will think on what I can do to test such things properly.

btwonion commented 10 months ago

thanks for your help. it compiles now, but it takes much longer (as expected). should i close this issue?

whyoleg commented 10 months ago

Not yet, I do want to report the issue with a reproducer to Kotlin issue tracker and after that add link here, for you to keep track and for anyone else who will struggle with similar issues. After that I will close the issue. Thank you for all your information!

whyoleg commented 6 months ago

Finally, reported an issue: https://youtrack.jetbrains.com/issue/KT-66737/K-N-Linking-of-binary-on-linux-fails