electron-builder icon indicating copy to clipboard operation
electron-builder copied to clipboard

Can't use extraFiles that contain Universal binaries

Open IanMDay opened this issue 4 years ago • 17 comments

  • 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.

IanMDay avatar Jan 18 '21 15:01 IanMDay

I have x64 and arm64 binary built from another project, x64 need support macOS 10.13 and it includes Frameworks/libswift* , but arm64 doesn't include Frameworks

use @electron/universal, i get some error While trying to merge mach-o files across your apps we found a mismatch, the number of mach-o files is not the same between the arm64 and x64 builds

As @IanMDay said:

or have a new configuration option for a 'universal' arch to indicate the files are already universal

that is great.

XRenSiu avatar Feb 08 '21 08:02 XRenSiu

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.

Hinton avatar Mar 20 '21 10:03 Hinton

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)
}

XRenSiu avatar Mar 24 '21 08:03 XRenSiu

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

stale[bot] avatar Jun 02 '21 16:06 stale[bot]

Yes, its still relevant.

ghost avatar Jun 03 '21 06:06 ghost

+1. Currently stuck here.

alectrocute avatar Jul 27 '21 20:07 alectrocute

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

mmaietta avatar Jul 28 '21 07:07 mmaietta

@mmaietta Thanks so much for your help. How are you "preparing your extraFiles for universal"? I have a .node native module that I require("./src/release/Build/my_module.node"). Am I supposed to use electron-rebuild to compile it for universal? Any ideas?

When I build for universal, electron-builder and/or @electron/universal only include the x64 binary. I am not yet using extraFiles.

alectrocute avatar Jul 28 '21 12:07 alectrocute

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

stale[bot] avatar Oct 02 '21 02:10 stale[bot]

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

Hinton avatar Oct 04 '21 08:10 Hinton

Thanks for keeping this ticket open @Hinton! As a side effect of this bug, I've become pretty proficient using lipo manually.

alectrocute avatar Oct 04 '21 13:10 alectrocute

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?

pmstani avatar Mar 17 '22 14:03 pmstani

I ended up using lipo -extract to split the universal out to its distinct parts and place those files into the x64 and arm folders.

ghost avatar Mar 17 '22 16:03 ghost

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!

pmstani avatar Mar 17 '22 16:03 pmstani

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.

ghost avatar Mar 18 '22 09:03 ghost

Thanks that was very useful. I figured it out at the same time I received your reply, but I'm sure it'll be useful to many others!

pmstani avatar Mar 18 '22 09:03 pmstani

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.

jtbandes avatar Jun 14 '22 01:06 jtbandes