sodium.node is wrong architecture for Android
RangerMauve opened this issue · comments
I installed sodium-native-nodejs-mobile and got it to compile into the APK by cleaning out the libsodium
folder.
However, when I try to require sodium-native-nodejs-mobile
inside the nodejs-mobile project, I get the following stack trace:
10-13 16:03:38.486 9366 9453 E nodejs : /data/data/com.teliosmobile/files/nodejs-project/node_modules/bindings/bindings.js:91
10-13 16:03:38.486 9366 9453 E nodejs : throw e
10-13 16:03:38.486 9366 9453 E nodejs : ^
10-13 16:03:38.486 9366 9453 E nodejs :
10-13 16:03:38.486 9366 9453 E nodejs : Error: dlopen failed: "/data/data/com.teliosmobile/files/nodejs-project/node_modules/sodium-native-nodejs-mobile/build/Release/sodium.node" is for EM_X86_64 (62) instead of EM_AARCH64 (183)
10-13 16:03:38.486 9366 9453 E nodejs : at Object.Module._extensions..node (internal/modules/cjs/loader.js:1065:18)
10-13 16:03:38.486 9366 9453 E nodejs : at Module.load (internal/modules/cjs/loader.js:879:32)
10-13 16:03:38.486 9366 9453 E nodejs : at Function.Module._load (internal/modules/cjs/loader.js:724:14)
10-13 16:03:38.486 9366 9453 E nodejs : at Module.require (internal/modules/cjs/loader.js:903:19)
10-13 16:03:38.486 9366 9453 E nodejs : at require (internal/modules/cjs/helpers.js:74:18)
10-13 16:03:38.486 9366 9453 E nodejs : at bindings (/data/data/com.teliosmobile/files/nodejs-project/node_modules/bindings/bindings.js:84:48)
10-13 16:03:38.486 9366 9453 E nodejs : at Object.<anonymous> (/data/data/com.teliosmobile/files/nodejs-project/node_modules/sodium-native-nodejs-mobile/index.js:1:33)
10-13 16:03:38.486 9366 9453 E nodejs : at Module._compile (internal/modules/cjs/loader.js:1015:30)
10-13 16:03:38.486 9366 9453 E nodejs : at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
10-13 16:03:38.486 9366 9453 E nodejs : at Module.load (internal/modules/cjs/loader.js:879:32)
As well, when I use objdump
to inspect the sodium.node binary, I'm seeing the following:
objdump -f ./build/Release/sodium.node
./build/Release/sodium.node: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000001040
This is telling me that it's not compiled for arm64, however I'm not seeing anything in the instructions or build scripts that would enable this functionality. 😅
I've tried stuff like specifying the architecture and platform for npm install, and that doesn't seem to help either. e.g. npm i --save sodium-native-nodejs-mobile --target_arch=arm64 --target_platform=android
I've also tried to rebuild with the target_arch
argument, and the binary still seems to be x86-64. node-gyp clean configure rebuild --verbose --target_arch=arm64
What's strangeis that using target_arch=ia32 seems to compile the binary as expected.
node-gyp clean configure rebuild --verbose --target_arch=ia32
...
objdump -f ./build/Release/sodium.node
./build/Release/sodium.node: file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00001050
Any pointers would be very much appreciated!
I think this is supposed to be solved by nodejs-mobile recompiling stuff with .gyp
in it at runtime. Not seeing that though.
Hey @RangerMauve
It sounds like you're using conventional npm install and node-gyp to compile, and that's likely to be incorrect. nodejs-mobile has its own fork of node-gyp called nodejs-mobile-gyp and it runs as part of the Android compilation of the APK. Have you seen https://github.com/nodejs-mobile/nodejs-mobile-react-native#native-modules ?
Interesting. It seems like that Android compilation isn't invoking the code that does the nodejs-mobile-gyp code. :/ Have you seen this before?
Do I need to be running something other than react-native run-android
to make it work? 😅
Thank you for the pointer @staltz! That helped me narrow down where to look. After I read the how the gradle script does native compilation I came up with the following:
Deleting the build
folder inside sodium-native-nodejs-mobile
then running NODEJS_MOBILE_BUILD_NATIVE_MODULES=1 react-native run-android
seems to have forced recompliation and I'm now getting the following error which seems unrelated to this specific Github issue. 😅
Metro has encountered an error: SHA-1 for file /home/mauve/.nvm/versions/node/v15.2.1/lib/node_modules/react-native/node_modules/metro-runtime/src/polyfills/require.js (/home/mauve/.nvm/versions/node/v15.2.1/lib/node_modules/react-native/node_modules/metro-runtime/src/polyfills/require.js) is not computed.
Potential causes:
1) You have symlinks in your project - watchman does not follow symlinks.
2) Check `blockList` in your metro.config.js and make sure it isn't excluding the file path.: /home/mauve/.nvm/versions/node/v15.2.1/lib/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph.js (245:13)
�[0m �[90m 243 |�[39m�[0m
�[0m �[90m 244 |�[39m �[36mif�[39m (�[33m!�[39msha1) {�[0m
�[0m�[31m�[1m>�[22m�[39m�[90m 245 |�[39m �[36mthrow�[39m �[36mnew�[39m �[33mReferenceError�[39m(�[32m`SHA-1 for file ${filename} (${resolvedPath}) is not computed.�[39m�[0m
�[0m �[90m |�[39m �[31m�[1m^�[22m�[39m�[0m
�[0m �[90m 246 |�[39m �[32m Potential causes:�[39m�[0m
�[0m �[90m 247 |�[39m �[32m 1) You have symlinks in your project - watchman does not follow symlinks.�[39m�[0m
�[0m �[90m 248 |�[39m �[32m 2) Check \`blockList\` in your metro.config.js and make sure it isn't excluding the file path.`�[39m)�[33m;�[39m�[0m
Great to hear that you figured it out! It may seem like I have all the answers but in reality I wouldn't have known that you have to delete that folder. So many things can go wrong, it seems.
About this new error, I think you have to tell metro (react-native's browserify) to ignore the JS files that are in the nodejs-project. Check Manyverse's metro config file in the project root for an example.
I've actually added the blocklist according to the nodejs-mobile docs (with updated to account for the change from blacklist to blocklist)
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* @format
*/
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true
}
})
},
resolver: {
blockList: [
/\/nodejs-assets\/.*/,
/\/android\/.*/,
/\/ios\/.*/
]
}
}
I'll try the manyverse one to see if it helps. Thanks for the tip!
Clearning the NPM cache and adding resetCache: true
to my metro.config seems to have helped. Running into other issues now.
Mobile apps are hell. :P
Err, looks like it was a false alarm. Still doesn't seem to be building. 😅
It seems that my project properties didn't contain a reactNativeDebugArchitectures
property, and this the abiFilters for the NDKI were null.
To fix it I added the ndk.abiFilters
property to the defaultConfig in my android/app/build.gradle
. (this was originally generated by react-native. You can see an example of this in manyverse' build here: https://gitlab.com/staltz/manyverse/-/blob/master/android/app/build.gradle#L159