electron-builder: Can't use extraFiles that contain Universal binaries

  • Version: 22.10.4
  • Electron Version: 11.2.0
  • Electron Type (current, beta, nightly): current
  • Target: macOS Universal

I have universal binaries built from another project which I want to include via extraFiles, and have been doing so a while, but I’ve since updated builds to create Universal binaries.

I’m specifying the folder for the binaries as:

"extraFiles": [
  {
    "from": "binaries/${arch}",
    "to": "binaries"
  }
],

So the configuration only expects to find files in x64 and arm64 folders, so it only attributes these files to one of those architectures.

Ideally, it should either test the contents of the files given in either folder, or have a new configuration option for a ‘universal’ arch to indicate the files are already universal, or additionally search the universal arch as well as x64 and arm64.

I’ve resorted to splitting the binaries with lipo -extract for now so that builder is happy, but I don’t think this is an ideal solution.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 7
  • Comments: 17 (3 by maintainers)

Commits related to this issue

Most upvoted comments

My prebuilt universals get lipo extracted before the build into binaries/arm64 and binaries/x64

lipo -extract arm64 myUniversalBinary -output binaries/arm64/myUniversalBinary
lipo -extract x86_64 myUniversalBinary -output binaries/x64/myUniversalBinary

Then included into the package with extraFiles:

"extraFiles": [
    {
        "from": "binaries/${arch}",
        "to": "binaries"
    }
],

The builder then uses lipo to recombine them back again.

Pretty sure any changes that could be made here for detecting whether a binary is already universal would be part of either @electron/electron-osx-sign or @electron/universal libraries.

I’d advocate for using this workaround https://github.com/electron-userland/electron-builder/issues/5552#issuecomment-805615861

So basically you didn’t add the binaries in the extraResources field of package.json, packaged as usual, then used lipo -extract, then placed the files manually? And then I guess you need to recombine the thing? Sorry if my question seems dumb, trying to understand how lipo works 😕

Thanks!

Workaround

  1. prepare universal extralFiles

  2. use afterSign hook

    • copy extraFiles into packaged app
    • resign code
module.exports = async function(packContext){
  const {
    appOutDir,
    packager
  } = packContext

  const appFile = path.join(
    appOutDir,
    `${packager.appInfo.productFilename}.app`
  )
  copy('<extraFile path>',path.join(appFile, 'Contents/Library/xxxxx/xxx.qlgenerator'))

  // resign
  await packager.signApp(packContext, true)
}

Seems like this is fixed by https://github.com/electron/universal/pull/47 + https://github.com/electron-userland/electron-builder/pull/6913, if you put the file in the new x64ArchFiles allowlist.

Hello everyone,

I have a related issue (I think) with a .dylib which we build directly from Xcode as universal and try to include in our asset folder.

However, when packaging our Electron app for universal, it builds properly for x64, arm64 and then when it actually starts the universal part, we get the following error:

fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: /private/var/folders/8p/ylf73sqs61bgxnj99fngjlq00000gn/T/electron-universal-dqUU4L/Tmp.app/Contents/Resources/assets/plugins/xxxxxxxx.dylib and /Users/xxxxxxx/Documents/xxxxxxx/xxxxxxx/release/mac-universal--arm64/xxxxxxxx.app/Contents/Resources/assets/plugins/xxxxxxx.dylib have the same architectures (x86_64) and can't be in the same fat output file

Has anybody found a way to include an already compiled-for-universal dynamic lib without encountering this error?

It’s still relevant. The only current work-around requires signing twice.

I just encountered the same issue as @XRenSiu, we bundle a Safari extension inside the extraFiles which contains Frameworks/libswift* which are no longer used in arm64. Adding an option to inject extraFiles for universal should solve it for us.

Although we still build separate x64 and arm64 packages for dmg (to lower space usage), where we would want to always include the universal binaries as well.