Closed gonzus closed 3 years ago
Not sure if it answers you question, but with prebuildify-cross
you can compile a prebuild that's compatible with both CentOS and Ubuntu (and others).
I guess that is one way to go about this: having a single version for linux that works on many different versions of the OS. But I also see room for the case where you would want to take advantage of differences between linux versions, or where it is just not possible to have a least common denominator.
I guess the real problem here is that node-gyp-build
doesn't (currently) have the smarts to add differentiators when it is determining the name of the module it will try to load. I was curious how others were managing such a case. For us, we would like just to differentiate between linux OS flavor (CentOS
, Ubuntu
, Alpine
), but I can totally see how it might be interesting to differentiate, for example, between versions of a single flavor (Ubuntu 16
v Ubuntu 20
), or between C compilers (gcc
v clang
) or even versions of the C library. You might end up with a larger prebuilds
directory, but one that might match better your use case.
There are a few challenges with that approach:
os.release()
but would have to parse and normalize that/etc/alpine-release
exists and if so we assume musl
, else glibc
. That covers a common use case (node in alpine docker) without affecting load time for other platforms.As for:
and forcing the compilation of a local one (for the case of Ubuntu)?
That can be done with npm i --build-from-source
This seems to be what napi-rs is doing. Build binaries for different platforms.
Hi! How does one tell if a prebuild is universal (fat) binary on MacOS?
In regular shared libraries, you can use file <libname>
, and you'll get output like:
% file helloworld
helloworld: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
helloworld (for architecture x86_64): Mach-O 64-bit executable x86_64
helloworld (for architecture arm64): Mach-O 64-bit executable arm64
but these .node files are just reported as:
# prebuildify --napi --strip
% file prebuilds/darwin-arm64/node.napi.node
prebuilds/darwin-arm64/node.napi.node: Mach-O 64-bit bundle arm64
# prebuildify --napi --arch x64+arm64
% file prebuilds/darwin-x64+arm64/node.napi.node
prebuilds/darwin-x64+arm64/node.napi.node: Mach-O 64-bit bundle x86_64
In my test, the multi-arch build seems to have both archs in them, but it would be nice to be able to inspect them like one can do with file
.
@todbot When universal binaries are correctly configured via binding.gyp
(https://github.com/prebuild/prebuildify/issues/56#issuecomment-978935860), the output of file
will look like:
$ file prebuilds/darwin-x64+arm64/node.napi.node
prebuilds/darwin-x64+arm64/node.napi.node: Mach-O universal binary with 2 architectures:
[x86_64:Mach-O 64-bit x86_64 bundle, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|WEAK_DEFINES|BINDS_TO_WEAK>]
[arm64:Mach-O 64-bit arm64 bundle, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|WEAK_DEFINES|BINDS_TO_WEAK>]
We run our module on CentOS in production, and would like our developers (who mostly have mac and Ubuntu laptops) to be able to use it locally on their boxes.
Is there any way to have the
prebuilds
directory contain two different versions of a shared object for the same OS, one for CentOS and one for Ubuntu? Or somehow ignoring the pre-built version from the package (which was created for CentOS) and forcing the compilation of a local one (for the case of Ubuntu)?Or perhaps we are going about this the wrong way, and you guys have better suggestions?