curiosity-ai / rocksdb-sharp

.net bindings for the rocksdb by facebook
BSD 2-Clause "Simplified" License
163 stars 41 forks source link

Apple Silicon Support #15

Closed devhawk closed 1 year ago

devhawk commented 2 years ago

As of v6.27.3.24603, rocksdb nuget package does not include osx-arm64 native binaries. I was able to install apple silicon binaries of RocksDB (and it's dependenies) via homebrew. However, homebrew installs apple silicon libraries into /opt/homebrew/lib (instead of /usr/local/lib) which is not on the library load path. I was able to work around for now by creating a symlink from /usr/local/lib/librocksdb.dylib to /opt/homebrew/lib/librocksdb.dylib. However, I would appreciate a more automatic solution.

I'm not a mac dev, so I'm not sure what it would take to build rocksdb for apple silicon and include it in the rocksdb package. That seems like it would be the best solution, but I'm not sure if this requires a single "universal" native binary that works with intel + apple silicon or if it requires separate native binaries for each. Again, not a mac dev.

Another alternative would be to add /opt/homebrew/lib to the basePaths collection in PosixImporter.Import<T>. That was a trivial change that worked when I tested it locally. but I wasn't sure if that approach fits with the project goals, so I didn't open a PR with that solution.

theolivenbaum commented 2 years ago

Hi @devhawk - this is definitely in my pipeline - I recently got an M1 for work to be able to figure out what's the best way to target our app to it (and with this also rocksdb). But I can't promise any dates yet.

Nevertheless, we can easily add the /opt/homebrew/lib path to the list. I'll do it now and you should have a new build soon!

dahlia commented 2 years ago

According to Apple's official docs, universal binaries can be built using lipo tool both from Intel and Apple Silicon Macs. However, I am not sure if .NET works with a single universal .dylib well for both types of Macs. (There's a runtime identifer named osx though.)

Apparently it's also possible to build native libraries for Apple Silicon Macs by giving -target arm64-apple-darwin to CFLAGS & CXXFLAGS.[^1]

[^1]: Note that Apple LLVM uses the term arm64, but GCC uses aarch64 instead. For CC=gcc CXX=g++, give -target aarch64-apple-darwin to CFLAGS & CXXFLAGS.

rubo commented 2 years ago

We're also interested in this. Any progress?

mailes commented 1 year ago

We're also interested in this. Any progress?

theolivenbaum commented 1 year ago

@dahlia thanks for the feedback - I'll need to check if it is possible to adapt the build scripts to build the ARM version as well

theolivenbaum commented 1 year ago

Did a quick review of the build scripts here - but we're currently blocked by the lack of a build machine on Azure DevOps for macOS ARM. We need that as the build script depends on installing some libraries using brew, that are then copied as dependencies into the nuget package. There's an open issue here tracking that - but no timeline available.

I could setup a hosted agent on our end using a mac m1, anyone want to chip in sharing the cost?

Havret commented 1 year ago

@theolivenbaum Maybe we could switch the build pipeline to github actions? It would be free of charge then.

theolivenbaum commented 1 year ago

@Havret it's actually the same issue, because both GitHub actions and Azure DevOps run on the same infrastructure use support the same build machines / images.

theolivenbaum commented 1 year ago

If anyone is able to adapt the build script locally on an M1 and get it to build, that would be most of the work outside of the CI environment. I have an M1 laptop I could set up as a build machine for Azure DevOps (not ideal as I also use it for testing our app), but could cover the time till we have native Apple Silicon machines on Azure

rubo commented 1 year ago

@theolivenbaum What if to temporarily use an already compiled one by Meta?

theolivenbaum commented 1 year ago

Do you know where they release it? But still might need some work because of dependencies that need to be included in the package, plus fixing the import paths

rubo commented 1 year ago

@theolivenbaum Their official package for Java is on Maven, so binaries are available here for all supported platforms.

Actually, we use ARM64 binaries for both Linux and macOS from there with this NuGet package.

theolivenbaum commented 1 year ago

@rubo that is a great find, I'll investigate a bit here then!

theolivenbaum commented 1 year ago

@rubo I'm checking this here, did you manage to just download the binaries from Maven and use as is?

I tried that but I get an exception loading them: NativeImport.NativeFunctionMissingException: Failed to find entry point for IntPtr rocksdb_options_create()

And if I inspect the exported symbols (at least for windows), I can see that all functions are prefixed with "Java_org_rocksdb_RocksDB"

rubo commented 1 year ago

@theolivenbaum That's right, it doesn't work out of the box for Windows only. For the other platforms, we have no problem. In the case of macOS, the extension of .jnilib should be changed to .dylib.

theolivenbaum commented 1 year ago

Ok that's great to know, strange that they would build it differently for Windows. I'll integrate their pre built binaries for ARM then in the nuget build and we can hopefully soon test it!

theolivenbaum commented 1 year ago

@rubo let's see: https://www.nuget.org/packages/RocksDB/8.0.0.37400

rubo commented 1 year ago

@theolivenbaum Runtime identifiers for ARM versions miss the 64 suffix. The directories linux-arm and osx-arm should be renamed to linux-arm64 and osx-arm64 respectively. Have you tested those on ARM machines?

theolivenbaum commented 1 year ago

strange - I did test locally and it just worked

theolivenbaum commented 1 year ago

I think it should work, if you look a the documentation here, they show it as just "-arm", because .NET never supported ARM32.

rubo commented 1 year ago

@theolivenbaum I'd recommend checking here instead. Have you tried it on macOS? There's no osx-arm RID in runtimes.json. We normally use with 64 suffix for both Linux and macOS. I didn't have a chance to test this version on ARM machines but pretty sure osx-arm won't work. I'll try to test that soon.

theolivenbaum commented 1 year ago

I've tested and it worked - that's why I'm surprised. I think the NuGet package folder structure is not exactly the same as the RID naming convention. In any case, I'll rename the folders :)