Closed ajsutton closed 2 years ago
There's a couple of hacks in here to work around the fact that the blst build system doesn't work well with Mac fat binaries. Firstly blst uses the ar
command to build an archive of the two compilation outputs (server.o
and assembly.o
). We can set CFLAGS
to get those .o
files to be compiled as fat, but ar
doesn't support fat archives - you need to use libtool -static
which does essentially the same job but supports fat binaries and unfortunately has different CLI syntax. We can't make that work just by setting env vars so use ar
to expand the built archive again then recreate it with libtool -static
which fortunately works.
But then the final built jar has the fat library under Mac/x86_64/
directory and the swig code is configured to find the library to load based on the OS and arch names, so on ARM it would be looking in Mac/arm64
. We get around that by just copying the library to Mac/arm64
directory. Down side is we're including two copies of the fat binary when we could just use one but it makes it work with the current version of blst. We may be able to push some changes back upstream to avoid these work arounds in future releases.
Can we get this one merged?
Can we get this one merged?
Unfortunately when I've been able to get people testing this on an M1 Mac the native library doesn't seem to load correctly when using an M1 native JVM. It looks like the dylib is correctly multi-arch so I suspect there's something in the loading process that isn't writing out the right library or something like that. Though it could still be that the compilation isn't right.
@ajsutton here’s an alternative approach that does not attempt to make a universal binary:
assumptions:
# must run within blst/bindings/java
# assume run on x86_64 arch Mac
# test compiler architectures
cc -dM -E -x c /dev/null | grep -q x86_64
cc -arch arm64 -dM -E -x c /dev/null | grep -q AARCH64
build steps:
# start clean
rm -f libblst.a supranational.blst.jar
rm -fr supranational
# CC for build of libblst.a
# CXX for build of SWIG layer
CC="cc -arch arm64 " CXX="c++ -arch arm64" ./build.sh
# os.arch of this JVM is x86_64, but we cross compiled above
mv supranational/blst/Mac/x86_64 supranational/blst/Mac/aarch64
# reset for new compile
rm -f libblst.a supranational.blst.jar
# build with defaults of x86_64
./build.sh
double check the output
lipo -info supranational/blst/Mac/x86_64/libblst.dylib
lipo -info supranational/blst/Mac/aarch64/libblst.dylib
jar tf supranational.blst.jar
@ajsutton here’s an alternative approach that does not attempt to make a universal binary:
ooo, that's really cool and definitely reduces the hackiness a step. Have you been able to test if the resulting jar actually loads BLST on an M1 Mac using a native JVM?
Ah, the downside of just calling ./build.sh
is it doesn't build the portable version of BLST - it builds the fully optimised one which doesn't work on all CPUs. The key question is whether there are any Macs that don't work with the optimised version - I'd have to go read up on the details of what's required in a CPU. Might be able to just call the top level build.sh with the portable arg like was done previously to solve it...
Also seems the latest blst doesn't like my approach which isn't so great...
@dwhjames I've switched over to your approach with a couple of tweaks to ensure we keep building a compatible library. I note that you called the directory aarch64 and I previously had it as arm64 so there's a good chance that's all that was stopping it from working previously.
Attached is a zip file with the jblst jar built from this PR and a little test class that tries to init the BLST native library. It works on my x86 Mac but I don't have an M1 Mac to try it on.
The arm64 vs. aarch64 is annoying
❯ echo $OSTYPE
darwin20.0
❯ echo $CPUTYPE
arm64
yet
System.getProperty(“os.name”) == "Mac OS X"
System.getProperty(“os.arch”) == "aarch64"
and clang -arch arm64
rather than -aarch aarch64
🤯
Anyway, I don’t have a M1 Mac either, but I got a colleague to run my version of this and it succeeded.
Our only differences are:
"-D__BLST_PORTABLE__"
Your variation looks 👍
Builds in the MacOS library targeting both x86_64 and arm64 which should produce a single FAT library file that works on both architectures automatically.
fixes #13