Rust-rocksdb: Linking with system RocksDB

Created on 31 May 2019  ·  22Comments  ·  Source: rust-rocksdb/rust-rocksdb

https://github.com/rust-rocksdb/rust-rocksdb/pull/166 introduced the ability to link with an already-built instance of rocksdb (such as one installed system-wide). However, it requires that you explicitly give the path to search in (ROCKSDB_LIB_DIR, SNAPPY_LIB_DIR, etc.). It'd be really neat if rocksdb-sys checked if rocksdb and snappy were available in the standard OS locations too (originally suggested in https://github.com/rust-rocksdb/rust-rocksdb/pull/166#issuecomment-389564525). It's a little unfortunate to have to pass custom environment variables every time we build even though those libraries are installed system-wide.

Alternatively, even just a ROCKSDB_USE_SYSTEM=1 would be a step up.

Most helpful comment

Related to this, it'd be great if these environment variables where documented in the README and the docs!

All 22 comments

Related to this, it'd be great if these environment variables where documented in the README and the docs!

This would be really useful!

The build file for openssl-sys may be a good place to draw on from inspiration here.

I'm working on this

@lovesegfault How's your progress on this? Building rocksdb is by far the biggest part of my project's build time at the moment :cry:

What is a problem to use system library now? AFAIK, it works via pkg-config or env variable well.

@aleksuss Well, on current master, if I try to build librocksdb-sys, it still spins up a bunch of C++ compiler instances, even though I have rocksdb installed as a system-wide library:

$ ls /usr/lib/librocksdb.so*
/usr/lib/librocksdb.so  /usr/lib/librocksdb.so.6  /usr/lib/librocksdb.so.6.5.3

I had stopped working on this because other things took priority in the office. I'm going on vacation for the next ~2 weeks, so hopefully I can pick this back up :)

Note that #354 doesn’t add any library discovery magic. Mostly because RocksDB doesn’t support pkg-config or any other similar tool.

In the future a simple clause to that looks for the libraries in the usual places in case the corresponding envvar isn’t set could easily be added.

Ah, I see, so if the crate _currently_ fails to find a system-wide RocksDB, that will continue to be the case. I wonder what's making it fail. Maybe it looks for _exactly_ the same version of the .so, not just a compatible one?

Well, the current crate will attempt to find a system rocksdb and vendor if it can't. #354 means you select, through a feature, whether to vendor or not. If you don't vendor, then you must set ROCKSDB_LIB_DIR and if you don't you'll get a helpful error message.

I can add a follow up that attempts to find the lib if the envvar isn't set, I'm just generally not a fan of that behavior.

@lovesegfault Not sure I'm reading that correctly? So, you're saying that currently, if ROCKSDB_LIB_DIR is _not_ set, then rocksdb _will_ vendor? And the _only_ way to have it link with the system-wide lib is by setting ROCKSDB_LIB_DIR?

I'm curious -- why is it you would be against using the system library by default? Vendoring brings _huge_ compile times, and I'm not sure what the upside is?

@jonhoo
Current Behavior
librocksdb-sys will look for ROCKSDB_LIB_DIR envvar. If it is set it will link to the .so in that dir. If it is not set, then it will vendor rocksdb as an alternative. The _exact_ same behavior also happens for the compression libraries such as bzip2, with the variable there being BZIP2_LIB_DIR, for example.

New behavior
librocksdb-sys has a new (default) feature vendor. If that feature is enabled it will not try to look for any system libraries, in any way. Instead it will vendor rocksdb and all the compression libraries.

If the vendor feature is not enabled, then librocksdb-sys will not, in any way, attempt to vendor any libraries, including rocksdb and compression libs. Instead it will look for envvars that inform it of where to find the necessary libraries. These envvars are in the form LIBNAME_LIB_DIR. It will not attempt to do any discovery of system libraries, it relies on the user specifying them, If you have vendor disabled and forget to set the corresponding envvar, then the build will fail with a message telling you to set the envvar.

Possible future behavior
In the future, when vendor is disabled, we could attempt to do discovery of system libraries, as a fallback when the envvars are not set. I have not implemented this yet, but plan to when I have time.

Doing this with a feature is a little odd, because it means that if _any_ crate in your dependency tree includes rocksdb with the vendor feature set, then RocksDB will be vendored. It won't make much of a difference for small crates, but for a large binary that may have multiple transitive dependencies on RocksDB, it makes it pretty likely that there is no way to opt out of vendoring..

@jonhoo That's true, how else do you imagine this working?

IMHO there should be no vendoring at all, vendoring is the root of all evil. If @aleksuss and other maintainers would allow it I'd prefer to get rid of vendoring alltogether.

I agree with you -- the solution is to not vendor. At the very least, vendoring should not be in the default feature set. One option is to have vendoring be opt-in using an environment variable.

That could be done, @aleksuss @vitvakatu what are you guys' thoughts?

Features are indeed hard to control in case of transitive dependencies, and compiling RocksDB from source costs a lot (for our project, it's about 30% increase of the build time!). However, I don't like the idea of complete removing of vendoring. On some platforms we do not have newest rocksdb version available: we were even forced to make our own PPA for older Ubuntu distributions.

So, I'd prefer to save the current behavior, but maybe improve it (automatic libraries search?). Perhaps we should force user to manually enable vendoring (via env var), but it would be a bit annoying for transitive dependencies as well.

Well, on current master, if I try to build librocksdb-sys, it still spins up a bunch of C++ compiler instances, even though I have rocksdb installed as a system-wide library:

This also looks pretty weird and probably should be fixed.

@vitvakatu Yeah, I think "inverting" the behavior so that users opt-in to vendoring is probably the right way to go :)

This also looks pretty weird and probably should be fixed.

Note that I do not have any env vars set, so I believe this is intended behavior per today?

Alright, I inverted the behavior :)

@lovesegfault I think if we are inverting the behavior, then it's probably also necessary to have build.rs search for rocksdb in /usr/lib or something by default. Otherwise a bunch of users are suddenly going to get compilation errors since they do not have the env var set.

Alright, so pending work is::

  • Library discovery
  • Turn vendor feature into envvar
Was this page helpful?
0 / 5 - 0 ratings