Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static linking of OpenSSL when using sqlx and sqlx-macros #1337

Closed
emk opened this issue Sep 2, 2020 · 4 comments
Closed

Static linking of OpenSSL when using sqlx and sqlx-macros #1337

emk opened this issue Sep 2, 2020 · 4 comments

Comments

@emk
Copy link

emk commented Sep 2, 2020

Thank you for maintaining the Rust OpenSSL crates!

I'm the maintainer of rust-musl-builder, a Docker image used for building static Rust binaries that include openssl and diesel. I'm currently working to add support for sqlx, and I've run into an interesting challenge: launchbadge/sqlx#670

In a nutshell, sqlx includes an sqlx-macros package that connects to the database at compile-time. It does this to validate prepared statements, supporting syntax checking of SQL, and type-checking of prepared statement arguments. But this means that it winds up linking against openssl-sys twice:

  1. sqlx-macros links against openssl-sys and glibc at compile time. Rust insists that procedural macros are always shared libraries.
  2. sqlx links against openssl-sys and muslc-libc in the final binary, which is static.

Unfortunately, this means that we need to keep track of two versions of OpenSSL: a shared glibc version for macros, and a static musl-libc version for the final binary. And OPENSSL_STATIC doesn't offer enough control over openssl-sys to make this work.

I'm not sure what the ideal fix is here. I've proposed several solutions to the sqlx maintainers in launchbadge/sqlx#670, and I don't even know if a fix is possible at the level of sqlx. So I'm very much open to suggestions. If you do think that this problem is best fixed at the openssl-sys level, please let me know, and I'll try to figure out the details and prepare a PR.

Once again, thank you for maintaining the openssl crate! It has brought a lot of value to Rust community.

@sfackler
Copy link
Owner

sfackler commented Sep 2, 2020

All of the environment variables can be prefixed with the target architecture, so you can set X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_STATIC=1 which will only apply to the build for sqlx, not sqlx-macros: https://docs.rs/openssl/0.10.30/openssl/#manual.

@emk
Copy link
Author

emk commented Sep 3, 2020

Thank you! Preliminary testing suggests that X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_STATIC=1 works.

I will be updating rust-musl-builder accordingly and re-running the full test test suite. If it works, I'll close this issue. And with any luck, anybody using rust-musl-builder should be able to use sqlx (or other libraries using openssl-sys at compile time) without issues.

emk added a commit to emk/rust-musl-builder that referenced this issue Sep 3, 2020
`sqlx` requires linking against OpenSSL twice:

- `sqlx-macros` needs to link against OpenSSL as a shared libary for use
  at compile time.
- `sqlx` needs to link against OpenSSL a static library for use at
  runtime.

You can find the details here.

launchbadge/sqlx#670
sfackler/rust-openssl#1337

We go with the fix proposed by sfackler, and add a test program that we
can use to verify everything works correctly.
emk added a commit to emk/rust-musl-builder that referenced this issue Sep 3, 2020
- `sqlx-macros` needs to link against OpenSSL as a shared libary for use
  at compile time.
- `sqlx` needs to link against OpenSSL a static library for use at
  runtime.

You can find the details here:

launchbadge/sqlx#670
sfackler/rust-openssl#1337

We go with the fix proposed by @sfackler, and add a test program that we
can use to verify everything works correctly.

We remove a few `OPENSSL`-related variables that were added 4 years ago,
and that no longer appear to be needed.
emk added a commit to emk/rust-musl-builder that referenced this issue Sep 3, 2020
`sqlx` requires linking against OpenSSL twice:

- `sqlx-macros` needs to link against OpenSSL as a shared libary for use
  at compile time.
- `sqlx` needs to link against OpenSSL a static library for use at
  runtime.

You can find the details here:

launchbadge/sqlx#670
sfackler/rust-openssl#1337

We go with the fix proposed by @sfackler, and add a test program that we
can use to verify everything works correctly.

We remove a few `OPENSSL`-related variables that were added 4 years ago,
and that no longer appear to be needed.
@emk
Copy link
Author

emk commented Sep 4, 2020

I have updated rust-musl-builder to set:

X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR=/usr/local/musl/
X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_STATIC=1

This makes sqlx work very nicely, out of the box. It's still necessary to use cargo sqlx prepare to avoid connecting to a database at buid time.

Thank you very much for your help figuring this out!

@Rizary
Copy link

Rizary commented Nov 27, 2020

@emk sorry for tagging you, but I came across this issue when trying to build static rust binary. May I ask whether you have an example of doing cargo sqlx prepare or not in your repo? I couldn't find where should I run the command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants