electron / rebuild

Package to rebuild native Node.js modules against the currently installed Electron version
MIT License
1.02k stars 175 forks source link

Pass arch armv7l as "arm" to node-gyp #1140

Open fishbone1 opened 3 months ago

fishbone1 commented 3 months ago

I rebuild an Electron app with arch armv7l for Raspberry Pi. The build is executed on a Linux amd64 system, what used to work well. For newer Electron versions (30 at them moment) it fails due to enabled v8_enable_pointer_compression, which only is allowed for 64bit systems.

This leads to multiple errors like these:

error: static assertion failed: Pointer compression can be enabled only for 64-bit architectures

error: right operand of shift expression ‘(1 << 32)’ is greater than or equal to the precision 32 of the left operand

The NodeJS header files contain a logic that sets this flag according to the given target architecture.

~/.electron-gyp/30.1.0/include/node/common.gypi:

      # V8 pointer compression only supports 64bit architectures.
      ['target_arch in "arm ia32 mips mipsel ppc"', {
        'v8_enable_pointer_compression': 0,
        'v8_enable_31bit_smis_on_64bit_arch': 0,
        'v8_enable_sandbox': 0,
      }]

It seems that Electron-Packager and Electron-Rebuild have other architecture names ("armv7l") than NodeJS ("arm"). I call Electron-Packager with arch: ['armv7l']. Arch name arm ist not allowed here. For prebuild this seems to be converted:

https://github.com/electron/rebuild/blob/a93581c57d7bf9f1408693fc40614ccc10f51488/src/module-type/prebuildify.ts#L10-L13

So I think the issue can be solved if the same logic is applied for node-gyp. If someone confirms that this makes sense, I could create a PR.

Here are some workarounds but I don't know if they could cause problems when building other node modules, if that relies on arch to be named armv7l. They work for me:

Workaround 1

set env var npm_config_target_arch=arm

Workaround 2

Change architecture for the prebuild call if you are using Electron-Packager:

packager({
    appVersion: version,
    electronVersion: '30.1.0',
    name: 'myApp',
    dir: 'myApp',
    overwrite: true,
    platform: 'linux',
    arch: ['armv7l'],
    prune: true,
    out: 'dist',
    afterCopy: [(buildPath, electronVersion, platform, arch, callback) => {

        // Replace arch here:
        if (arch === 'armv7l')
            arch = 'arm';

        rebuild({ buildPath, electronVersion, arch })
            .then(() => callback())
            .catch((error) => callback(error));
    }],
}).catch(err => {
    console.error(err);
    process.exit(1);
});