Hello,
I am trying to get my app code signed, but Apple now requires all apps to be notarized. I am getting the following error back from Apple:
The executable does not have the hardened runtime enabled.
This is referring to the main executable created by hover build. I have tried adding the hardening to the Xcode project, but Im assuming hover build does not use the xcode project to build it.. How do I add the hardened runtime capability when using hover?
The documentation from Apple:
Hardened runtime is available in the Capabilities pane of Xcode 10 or later, but you can enable the feature manually using earlier versions of Xcode, as long as you鈥檙e on macOS 10.13.6 or later. To do this, add the following flag to the
OTHER_CODE_SIGN_FLAGSbuild setting:
--options=runtime
Is there a way to provide this build settings when creating the cmd binary?
I think I found how to do it, the codesign utility lets you add the option:
codesign -s "<COMMON_NAME>" -fv --options runtime App.app/Contents/MacOS/<EXECUTABLE>
I'm sorry, but I cannot help you on this one. Please report your finding here, as it might help others.
This sounds like something we may want to do for the release build of an app? Or should it also be done for debug builds?
Related issue #156
I have very little experience with MacOS, help is welcome and much appreciated @alexelisenko
I have been able to successfully sign, notarize and distribute the app with a DMG installer. My findings:
hover build -t "lib/main.dart" I dont use the main_desktop.dart
/MyApp.app
/Contents
Info.plist
/MacOS
/Resources
MacOS folder in the app packageMove the following files to the .app directory under the MacOS folder
/assets
/flutter_assets
FlutterEmbedder.framework
icudtl.dat
myapp_binary
/ResourcesIt is very important to have the following fields in the Info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleExecutable</key>
<string>*YOUR EXECUTABLE (myapp_binary)*</string>
<key>CFBundleIconFile</key>
<string>icon.icns</string>
<key>CFBundleIdentifier</key>
<string>*YOUR BUNDLE*</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSUIElement</key>
<true/>
</dict>
</plist>
First sign the app bundle:
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep MyApp.app
Sign the executable with the runtime options (This is now required for MacOS 10.14+)
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep --options runtime MyApp.app/Contents/MacOS/MyAppBinary
Sign the FlutterEmbedder Framework separately
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep MyApp.app/Contents/MacOS/FlutterEmbedder.framework/Versions/A/
You will need an application specific password for the following steps
https://support.apple.com/en-ca/HT204397
How to generate an app-specific password
Sign in to your Apple ID account page.
In the Security section, click Generate Password below App-Specific Passwords.
Follow the steps on your screen.
After you generate your app-specific password, enter or paste it into the password field of the app as you would normally.
Compress the .app directory into zip, then:
xcrun altool --notarize-app --primary-bundle-id "YOUR BUNDLE ID" --username "YOUR DEVELOPER EMAIL" --password "YOUR APP SPECIFIC PASSWORD" --file MyApp.zip
Once the zip is uploaded, you will get a REQUEST-ID back, use it to check the status
Check status: xcrun altool --notarization-info <REQUEST-ID> -u "YOUR DEVELOPER EMAIL" -p "YOUR APP SPECIFIC PASSWORD"
If there is an error, you will see it in the output of the check status ^ command. There will be a link to a log file which will contain the errors to fix.
If approved, staple the app: xcrun stapler staple MyApp.app/
I used the create-dmg tool: brew install create-dmg
Then run with command:
create-dmg --volname "MyApp Installer" \
--volicon MyApp.app/Contents/Resources/icon.icns \
--background MyApp.app/Contents/Resources/installer-bg.png \
--window-size 800 400 \
--icon-size 100 \
--icon "MyApp.app" 200 200 \
--app-drop-link 600 185 \
"MyApp-1.0.dmg" "MyApp.app/"
Do not sign the DMG, the MacOS gatekeeper will detect the signed app in the image. If you sign the dmg, you will need to notarize it too, and there are many bug reports with notarizing image files.
This sounds like something we may want to do for the release build of an app? Or should it also be done for debug builds?
It's is more related to packaging (hover dist maybe?)
related to #99
Indeed this will be useful for packaging. Thanks @alexelisenko !
@Drakirus @GeertJohan I have found that using the --options runtime, which is required by Apple for the app to be notarized, caused a Dart crash. I have files bug reports.
Also, is there any updates on how MacOS 10.15+ will be handled? It is my understanding that OpenGL is no longer supported.
Hopefully you can get the --options runtime bug to be fixed :crossed_fingers:.
About OpenGL not been supported on MacOS, we did talk about it in #40.
tl;dr: It might be a non-issue if Metal gets ported into go-gl/glfw.
@Drakirus I have found the issue with enabling hardened runtime.
You need to also add entitlements for allowing JIT, since AOT with Dart in the flutterembedder is not supported yet, which is why it crashes.
I will post the exact entitlement file and codesign command that is working for me.
Moved to #207.
@alexelisenko what is related to code signing can be reported in this issue.
@Drakirus I have found the issue with enabling hardened runtime.
You need to also add entitlements for allowing JIT, since AOT with Dart in the flutterembedder is not supported yet, which is why it crashes.
I will post the exact entitlement file and codesign command that is working for me.
Hi, have you figured out the entitlement file that is working for you? I met the same issue:(
@wud147 Yes, You need to codesign with the entitlement file:
codesign -s "Developer ID Application: <APPLE DEVELOPER IDENTITY>" -fv --entitlements entitlements.xml --deep --options runtime MyAPP.app
The entitlement file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
</dict>
</plist>
Once codesigned and notarized, did you notice any issue launching the app?
I have a go-glfw app that refuses to launch the first time after clicking "Open" in the Gatekeeper dialog.
I'd like to know if this also happen with go-flutter.
Most helpful comment
I have been able to successfully sign, notarize and distribute the app with a DMG installer. My findings:
Step 1: build with either hover or manual
hover build -t "lib/main.dart"I dont use the main_desktop.dartStep 2: create .app package:
Step 3: move the build output to the
MacOSfolder in the app packageMove the following files to the .app directory under the MacOS folder
Step 4: modify Info.plist, add icons and/or installer background to
/ResourcesIt is very important to have the following fields in the Info.plist:
Step 5: Sign the app package
First sign the app bundle:
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep MyApp.appSign the executable with the
runtimeoptions (This is now required for MacOS 10.14+)codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep --options runtime MyApp.app/Contents/MacOS/MyAppBinarySign the FlutterEmbedder Framework separately
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep MyApp.app/Contents/MacOS/FlutterEmbedder.framework/Versions/A/Step 6: Notarize the package with Apple
You will need an application specific password for the following steps
https://support.apple.com/en-ca/HT204397
Compress the
.appdirectory into zip, then:xcrun altool --notarize-app --primary-bundle-id "YOUR BUNDLE ID" --username "YOUR DEVELOPER EMAIL" --password "YOUR APP SPECIFIC PASSWORD" --file MyApp.zipOnce the zip is uploaded, you will get a REQUEST-ID back, use it to check the status
Check status:
xcrun altool --notarization-info <REQUEST-ID> -u "YOUR DEVELOPER EMAIL" -p "YOUR APP SPECIFIC PASSWORD"If there is an error, you will see it in the output of the check status ^ command. There will be a link to a log file which will contain the errors to fix.
If approved, staple the app:
xcrun stapler staple MyApp.app/Step 7: create DMG
I used the
create-dmgtool:brew install create-dmgThen run with command:
All Done
Do not sign the DMG, the MacOS gatekeeper will detect the signed app in the image. If you sign the dmg, you will need to notarize it too, and there are many bug reports with notarizing image files.