Reputation: 377
I created a Mac OS X application but I don't know which steps I have to do for signing my Mac OS X application correctly. Thank you.
Upvotes: 20
Views: 27589
Reputation: 2344
At first you need an fully functional (and thus paid) Apple developer account. Then you can follow this information: https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html
The above link is the global procedure, but there is a specific topic with clean illustrated how to at the following URL: https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW2
Upvotes: 8
Reputation: 148
When you sign an app, all executables inside that app need to be signed, otherwise, the notarization will fail.
I wrote this node code that will recursively find all executables within an app and sign them.
#!/usr/bin/env node
// 5.14
const APP = "./yourAppName.app";
const IDENTITY = "your_signature_";
/****************************************************************************/
const items = [];
console.log("### finding things to sign");
const fs = require('fs');
const child_process = require('child_process');
const recursive = require("recursive-readdir");
const listdirs = require('listdirs');
const folder = `./nwjs.app`;
const main = async()=>{
const allFiles = await recursive(folder);
const exeFiles = allFiles.filter((x)=>{
try {
fs.accessSync(x, fs.constants.X_OK)
return true;
} catch (error) {
return false
}
})
console.log("all files", exeFiles);
items.push(...exeFiles)
const myListDir = (folder)=>{
return new Promise((resolve, reject) => {
listdirs(folder, function callback(err, list){
if(err){
return reject(err)
}
else {
return resolve(list)
}
});
});
}
const allFolders = await myListDir(folder);
const appFolders = allFolders.filter((x)=>{
return x.endsWith(".app")
})
console.log("all Folders", appFolders);
items.push(...appFolders)
/****************************************************************************/
console.log("");
console.log("### signing");
function exec(cmd) {
console.log(cmd);
const result = child_process.spawnSync(cmd, {shell: true, stdio: 'inherit'});
if (result.status !== 0) {
console.log(`Command failed with status ${result.status}`);
if (result.error) console.log(result.error);
//process.exit(1);
}
}
items.push(`${APP}/Contents/MacOS/nwjs`)
for (const item of items) {
try {
exec(`codesign --verbose --force --deep --strict --options runtime --timestamp --sign "${IDENTITY}" --entitlements neededToRun.entitlements "${item}"`);
} catch (error) {
console.log(error);
}
}
exec(`codesign --verbose --force --deep --strict --options runtime --timestamp --sign "${IDENTITY}" --entitlements neededToRun.entitlements "${APP}"`);
/****************************************************************************/
console.log("");
console.log("### verifying signature");
exec(`codesign --verify -vvvv "${APP}"`);
}
main();
Upvotes: -1
Reputation: 1340
With Qt
macdeployqt APP_NAME.app -codesign="Developer ID Application: YOUR NAME (ID_NUMBERS)"
Otherwise
codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app
You also need to sign every framework and dylib file into the package with something like this
codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore
codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app/Contents/Plugins/bearer/libqcorewlanbearer.dylib
Upvotes: 8
Reputation: 2317
I found the Apple documentation far too verbose. I have written up some detailed notes on how I signed my own software for Mac. There is too much to put it all here. See: http://successfulsoftware.net/2012/08/30/how-to-sign-your-mac-os-x-app-for-gatekeeper/
Upvotes: 30
Reputation: 1496
There is good Apple documentation on this. Go to the developer provisioning section and there is a good primer there that can get you running quickly.
Upvotes: 1