@@ -29,7 +29,6 @@ command toolsBuilderRun pPlatform, pEdition, pVersion
2929 -- Fetch the documentation
3030 local tDocsFolder
3131 put builderBuiltDocsFolder() into tDocsFolder
32-
3332 -- Now build the package
3433 local tPackageFile
3534 toolsBuilderMakePackage pVersion , pEdition , pPlatform , tEngineFolders , tIdeFolder , tDocsFolder
@@ -62,6 +61,19 @@ command toolsBuilderRunDisk pPlatform, pEdition, pVersion
6261 toolsBuilderMakeDisk pVersion , pEdition , pPlatform , tInputFile
6362end toolsBuilderRunDisk
6463
64+ command toolsBuilderRunBundle pPlatform, pEdition, pVersion
65+ if pPlatform is not "macosx" then
66+ exit toolsBuilderRunBundle
67+ end if
68+
69+ if the platform is not "macos" then
70+ builderLog "error" , "Cannot generate MacOSX app bundle on this platform"
71+ exit toolsBuilderRunBundle
72+ end if
73+
74+ toolsBuilderMakeAppBundle pVersion , pEdition , pPlatform
75+ end toolsBuilderRunBundle
76+
6577// //////////////////////////////////////////////////////////////////////////////
6678
6779private command toolsBuilderMakePackage pVersion, pEdition, pPlatform, pEngineFolders, pIdeFolder, pDocsFolder
@@ -457,56 +469,188 @@ private command toolsBuilderMakeInstaller pVersion, pEdition, pPlatform, pIdeFol
457469 end switch
458470end toolsBuilderMakeInstaller
459471
460- command toolsBuilderMakeDisk pVersion, pEdition, pPlatform, tInputZip
461- -- Compute the output file
472+ private function escapeArg pArg
473+ replace "'" with "\'" in pArg
474+ put "'" before pArg
475+ put "'" after pArg
476+ return pArg
477+ end escapeArg
478+
479+ private function findSigningIdentity
480+ get shell ("/usr/bin/security -q find-identity -v" )
481+ filter it with "*Developer ID Application: Runtime Revolution Ltd*"
482+ return it
483+ end findSigningIdentity
484+
485+ command toolsBuilderMakeAppBundle pVersion, pEdition, pPlatform
486+ -- Compute the name of the installer bundle
462487 local tOutputFileStub , tOutputFileFolder
463488 put builderOutputFolder() into tOutputFileFolder
464489 put tOutputFileFolder & slash & getInstallerFilenameStub(pVersion , pPlatform , pEdition ) into tOutputFileStub
465- builderEnsureFolderForFile tOutputFileStub
466490
467- get shell ("/usr/bin/security -q find-identity -v" )
468- filter it with "*Developer ID Application: Runtime Revolution Ltd*"
491+ -- Remove any stale app bundles
492+ local tAppBundle
493+ put tOutputFileFolder & slash & getBundleFilenameStub(pVersion , pPlatform , pEdition ) & ".app" into tAppBundle
494+ if there is a folder tAppBundle then
495+ builderLog "message" , "Removing old macosx app bundle" && "'" & tAppBundle & "'"
496+ get shell ("rm -r" && escapeArg(tAppBundle ))
497+ if the result is not zero then
498+ builderLog "error" , "Failed to remove old macosx app bundle:" && it
499+ throw "failure"
500+ end if
501+ end if
502+
503+ -- Run the installer to generate the raw app bundle
504+ builderLog "message" , "Installing macosx IDE to" && "'" & tAppBundle & "'"
505+ get shell (tOutputFileStub & ".app/Contents/MacOS/installer install noui -log /dev/stderr -location" && escapeArg(tAppBundle ))
506+ if the result is not zero then
507+ builderLog "error" , "Failed to run macosx installer:" && it
508+ throw "failure"
509+ end if
510+
511+ -- Remove the list of installed files from the app bundle (it isn't needed)
512+ delete file tAppBundle & "/.setup.txt"
513+
514+ -- Copy just the executable out of the installer to use as the auto-updater
515+ -- (on OSX, the payload is separate and is un-neccessary)
516+ builderLog "message" , "Adding auto-updater to app bundle"
517+ get shell ("cp" && escapeArg(tAppBundle & "/LiveCode Setup.app/Contents/MacOS/Installer" ) && escapeArg(tAppBundle & "/Contents/MacOS/autoupdater" ))
518+ if the result is not zero then
519+ builderLog "error" , "Failed to add auto-updater:" && it
520+ throw "failure"
521+ end if
522+
523+ -- Remove the rest of the installer from the app bundle
524+ builderLog "message" , "Removing installer from app bundle"
525+ get shell ("rm -r" && escapeArg(tAppBundle & "/LiveCode Setup.app" ))
526+ if the result is not zero then
527+ builderLog "error" , "Failed to clean macosx app bundle:" & it
528+ throw "failure"
529+ end if
530+
531+ -- Copy a shell script and AppleScript into the app bundle to catch attempts
532+ -- from old auto-updaters to launch the installer
533+ builderLog "message" , "Adding installer shim to app bundle"
534+ get shell ("install -m755" && escapeArg(builderCommunityResourceFolder() & "/dmg/fake-installer.sh" ) && escapeArg(tAppBundle & "/Contents/MacOS/installer" ))
535+ if the result is not zero then
536+ builderLog "error" , "Failed to copy installer stub shell script:" && it
537+ throw "failure"
538+ end if
539+ get shell ("osacompile" && "-o" && escapeArg(tAppBundle & "/Contents/MacOS/installer.scpt" ) && escapeArg(builderCommunityResourceFolder() & "/dmg/open-dmg.applescript" ))
540+ if the result is not zero then
541+ builderLog "error" , "Failed to compile installer stub AppleScript:" && it
542+ throw "failure"
543+ end if
544+
545+ -- Find the signing identity and sign the app bundle
546+ get findSigningIdentity()
469547 if it is not empty then
470- builderLog "message" , "Signing macosx installer' " && tOutputFileStub & ".app" & "'"
548+ builderLog "message" , "Signing macosx app bundle " && "'" & tAppBundle & "'"
471549 wait 1 second
472- get shell ("/usr/bin/codesign -s " && word 2 of it && "' " & tOutputFileStub & ".app'" )
473- if it is not empty then
474- builderLog "error" , "Could not macosx sign installer :" && it
550+ get shell ("/usr/bin/codesign --sign " && word 2 of it && "--deep --verbose=2 " && escapeArg( tAppBundle ) )
551+ if the result is not zero then
552+ builderLog "error" , "Could not sign macosx app bundle :" && it
475553 throw "failure"
476554 end if
477- builderLog "report" , "Successfully signed macosx installer' " && tOutputFileStub & ".app" & "'"
555+ builderLog "report" , "Successfully signed macosx app bundle " && "'" & tAppBundle & "'"
478556 else
479- builderLog "warning" , "No valid identity found for signing OSX installer"
557+ builderLog "warning" , "No valid identity found for signing OSX app bundle"
558+ end if
559+ end toolsBuilderMakeAppBundle
560+
561+ command toolsBuilderMakeDisk pVersion, pEdition, pPlatform
562+ -- Get the name of the app bundle that is being built
563+ local tOutputFileFolder
564+ local tDmgFolder
565+ local tAppBundle
566+ put builderOutputFolder() into tOutputFileFolder
567+ put builderOutputFolder() & slash & "DMG" into tDmgFolder
568+ put tOutputFileFolder & slash & getBundleFilenameStub(pVersion , pPlatform , pEdition ) & ".app" into tAppBundle
569+
570+ -- DMG output filename
571+ local tDmgFile
572+ local tTempDmg
573+ put tOutputFileFolder & slash & getDmgFilenameStub(pVersion , pPlatform , pEdition ) & ".dmg" into tDmgFile
574+ put tOutputFileFolder & slash & getDmgFilenameStub(pVersion , pPlatform , pEdition ) & "-rw.dmg" into tTempDmg
575+
576+ -- Remove any stale DMG folder
577+ if there is a folder tDmgFolder then
578+ builderLog "message" , "Removing old DMG directory"
579+ get shell ("rm -r" && escapeArg(tDmgFolder ))
580+ if the result is not zero then
581+ builderLog "error" ,"Failed to remove old DMG directory:" && it
582+ throw "failure"
583+ end if
584+ end if
585+
586+ -- Create a new DMG folder
587+ create folder tDmgFolder
588+
589+ -- Copy the app bundle into the DMG contents folder
590+ builderLog "message" , "Copying app bundle into DMG directory"
591+ get shell ("cp -R" && escapeArg(tAppBundle ) && escapeArg(tDmgFolder & slash))
592+ if the result is not zero then
593+ builderLog "error" , "Failed to copy app bundle into DMG directory:" && it
594+ throw "failure"
480595 end if
481596
482- local tEdition
483- put toUpper (char 1 of pEdition ) & toLower (char 2 to - 1 of pEdition ) into tEdition
484-
485- local tDmgFile , tDmgName , tDmgAppFolder
486- put tOutputFileStub & ".dmg" into tDmgFile
487- put "LiveCode" && tEdition && getReadableVersion(pVersion ) && "Installer" into tDmgName
488- put (tOutputFileFolder & slash & "Install LiveCode" && tEdition && getReadableVersion(pVersion ) & ".app" ) into tDmgAppFolder
489597 builderLog "message" , "Building Mac DMG to '" & tDmgFile & "'"
490598 if there is a file tDmgFile then
491599 delete file tDmgFile
492- if there is a file tDmgFile then
493- builderLog "error" , "Could not remove existing dmg - make sure it is not mounted"
494- throw "failure"
495- end if
600+ end if
601+ if there is a file tTempDmg then
602+ delete file tTempDmg
603+ end if
604+ if there is a file tDmgFile or there is a file tTempDmg then
605+ builderLog "error" , "Could not remove existing dmg - make sure it is not mounted"
606+ throw "failure"
496607 end if
497608
609+ -- The following is sometimes needed to work around bugs in hdiutil
498610 -- local tTrashFile
499611 -- put builderWorkspaceFolder() & "/deploy/.Trash" into tTrashFile
500612 -- put empty into URL ("file:" & tTrashFile)
501613
502- -- Do the DMG build
503- rename (tOutputFileStub & ".app" ) to tDmgAppFolder
504- -- SN-2015-03-09: [[ DMG creation failure ]] Ensure that hdiutil will allocate enough
505- -- memory if the installer end up being over a gigabyte large.
506- get shell ("hdiutil create -fs HFS+ -size 1G -volname" && quote & tDmgName & quote && "-srcfolder" && quote & tDmgAppFolder & quote && quote & tDmgFile & quote )
507- rename tDmgAppFolder to (tOutputFileStub & ".app" )
614+ -- Attempt to detach any DMGs with the name we're about to create
615+ -- We ignore failures here as it may not be mounted and an already-mounted
616+ -- disk will cause a very visible error during the next step.
617+ local tVolumeName
618+ put getBundleFilenameStub(pVersion , pPlatform , pEdition ) into tVolumeName
619+ get shell ("hdiutil detach" && escapeArg(tVolumeName ))
620+
621+ -- Generate an initial read-write DMG and mount it
622+ builderLog "message" , "Generating initial DMG"
623+ get shell ("hdiutil create -fs HFS+ -format UDRW -attach -volname" && escapeArg(tVolumeName ) && "-srcfolder" && escapeArg(tDmgFolder ) && escapeArg(tTempDmg ))
508624 if "created:" is not in it then
509- builderLog "error" , "Dmg creation failed -" && the last line of it
625+ builderLog "error" , "Failed to create initial DMG:" && it
626+ throw "failure"
627+ end if
628+
629+ -- Generate the multi-resolution TIFF for the DMG background image
630+ local tBackgroundImage
631+ put tOutputFileFolder & slash & "bg-" & pEdition & ".tiff" into tBackgroundImage
632+ builderLog "message" , "Generating DMG background image"
633+ get shell ("tiffutil -cathidpicheck" && escapeArg(builderCommunityResourceFolder() & "/dmg/bg-" & pEdition & ".png" ) \
634+ && escapeArg(builderCommunityResourceFolder() & "/dmg/bg-" & pEdition & "@2x.png" ) \
635+ && "-out" && escapeArg(tBackgroundImage ))
636+ if the result is not zero then
637+ builderLog "error" ,"Failed to generate DMG background image:" && it
638+ throw "failure"
639+ end if
640+
641+ -- Run the DMG prettifier script (this unmounts the DMG at the end)
642+ builderLog "message" , "Setting DMG background and styling"
643+ get shell (builderRepoFolder() & "/tools/make-dmg-pretty.sh" && escapeArg(tVolumeName ) && escapeArg(tBackgroundImage ))
644+ if it is not empty or the result is not zero then
645+ builderLog "error" , "Failed to apply DMG styling:" && it
646+ throw "failure"
647+ end if
648+
649+ -- Convert the DMG into a read-only, compressed DMG
650+ builderLog "message" , "Compressing DMG"
651+ get shell ("hdiutil convert" && escapeArg(tTempDmg ) && "-format UDBZ -o" && escapeArg(tDmgFile ))
652+ if the result is not zero or not line - 1 of it begins with "created:" then
653+ builderLog "error" , "Failed to compress DMG:" && it
510654 throw "failure"
511655 end if
512656
@@ -547,6 +691,10 @@ function getReadableVersion pVersion
547691 return tNumber & tTag
548692end getReadableVersion
549693
694+ function getBundleFilenameStub pVersion, pPlatform, pEdition
695+ return "LiveCode" && the upper of char 1 of pEdition & the lower of char 2 to - 1 of pEdition && getReadableVersion(pVersion )
696+ end getBundleFilenameStub
697+
550698function getInstallerFilenameStub pVersion, pPlatform, pEdition
551699 set the itemDelimiter to "-"
552700 if item 2 of pVersion is "gm" then
@@ -561,13 +709,27 @@ function getInstallerFilenameStub pVersion, pPlatform, pEdition
561709 else if pPlatform begins with "linux" then
562710 put "Linux" into pPlatform
563711 end if
564-
565- -- Ensure that the edition name is capitalised appropriately
566- local tEdition
567- put toUpper (char 1 of pEdition ) & toLower (char 2 to - 1 of pEdition ) into tEdition
568- return "LiveCode" & tEdition & "Installer-" & pVersion & "-" & pPlatform
712+
713+ return "LiveCode" & the upper of char 1 of pEdition & the lower of char 2 to - 1 of pEdition & "Installer-" & pVersion & "-" & pPlatform
569714end getInstallerFilenameStub
570715
716+ function getDmgFilenameStub pVersion, pPlatform, pEdition
717+ set the itemDelimiter to "-"
718+ if item 2 of pVersion is "gm" then
719+ delete item - 2 to - 1 of pVersion
720+ end if
721+ replace "-" with "_" in pVersion
722+ replace "." with "_" in pVersion
723+ if pPlatform is "macosx" then
724+ put "Mac" into pPlatform
725+ else if pPlatform is "windows" then
726+ put "Windows" into pPlatform
727+ else if pPlatform is "linux" or pPlatform is "linux-x64" or pPlatform is "linux-armv6hf" then
728+ put "Linux" into pPlatform
729+ end if
730+ return "LiveCode" & the upper of char 1 of pEdition & the lower of char 2 to - 1 of pEdition & "-" & pVersion & "-" & pPlatform
731+ end getDmgFilenameStub
732+
571733function loadTextFile pFile
572734 get url ("binfile:" & pFile )
573735 replace numToChar (13 ) & numToChar (10 ) with return in it
0 commit comments