To debug "makeDMG4mac.py"

This refs #22.
This commit is contained in:
Kazunari Sekigawa 2018-01-16 14:08:25 +09:00
parent 1c4f81fd63
commit 7fd231bba3
4 changed files with 76 additions and 41 deletions

View File

@ -4,7 +4,7 @@ The following two files are derivative works of:
(1) makeDMG4mac.py (1) makeDMG4mac.py
(2) Resources/template-KLayoutDMG.applescript (2) Resources/template-KLayoutDMG.applescript
The contents of original "LICENSE" file is attached below. The original "LICENSE" file is quoted below.
=============================================================================== ===============================================================================
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,4 +1,4 @@
<< Draft Version 0.003>> Relevant KLayout version: 0.25.1 Relevant KLayout version: 0.25.1
# 1. Introduction # 1. Introduction
This directory "macbuild" contains different files required for building KLayout (http://www.klayout.de/) version 0.25 or later for different Mac OSXs including: This directory "macbuild" contains different files required for building KLayout (http://www.klayout.de/) version 0.25 or later for different Mac OSXs including:
@ -15,7 +15,7 @@ By default, Qt framework is "Qt5" from Mac Ports (https://www.macports.org/) whi
### IMPORTANT ### IMPORTANT
``` ```
* Please DO NOT USE "Qt 5.10.0" which is problematic in showing your design in the main canvas. * Please DO NOT USE "Qt 5.10.0" which is problematic in showing your design in the main canvas.
* Please USE "Qt 5.9.x" instead. * Please USE "Qt 5.9.x" instead (5.9.3 is recommended).
* Building with Qt4 will lead to some compile errors. * Building with Qt4 will lead to some compile errors.
``` ```
Also by default, supported script languages, i.e, Ruby and Python, are those standard ones bundled with the OS. Also by default, supported script languages, i.e, Ruby and Python, are those standard ones bundled with the OS.
@ -41,7 +41,7 @@ $ cd /where/'build.sh'/exists
$ ./build4mac.py -d $ ./build4mac.py -d
``` ```
3. Confirm successful build. 3. Confirm successful build.
4. Run 'build4mac.py' again with the same options used in 2. PLUS "-y" to deploy executables and libraries (including Qt's frameworks) under "klayout.app" bundle. 4. Run 'build4mac.py' again with the same options used in 2. PLUS "-y" to deploy executables and libraries (including Qt's frameworks) under "klayout.app" bundle. The buddy command line tools (strm*) will also be deployed.
``` ```
$ ./build4mac.py -d -y $ ./build4mac.py -d -y
``` ```
@ -58,7 +58,7 @@ $ cd /where/'build.sh'/exists
$ ./build4mac.py -r mp24 -p mp36 $ ./build4mac.py -r mp24 -p mp36
``` ```
3. Confirm successful build. 3. Confirm successful build.
4. Run 'build4mac.py' again with the same options used in 2. PLUS "-Y" to deploy executables and libraries under "klayout.app" bundle. 4. Run 'build4mac.py' again with the same options used in 2. PLUS "-Y" to deploy executables and libraries under "klayout.app" bundle. The buddy command line tools (strm*) will also be deployed.
``` ```
$ ./build4mac.py -r mp24 -p mp36 -Y $ ./build4mac.py -r mp24 -p mp36 -Y
``` ```
@ -67,6 +67,21 @@ That is, paths to other modules (Ruby, Python, and Qt5 Frameworks) remain unchan
5. Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your "/Applications" directory for installation. 5. Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your "/Applications" directory for installation.
By: Kazzz (January 08, 2018) ----
# 4. Making a DMG installer
You can make a DMG installer using another Python script 'makeDMG4mac.py'.
This script requires a directory generated by 'build4mac.py' with [-y|-Y] option (refer to 3A.4 & 3B.4)
1. Make a symbolic link from the parent directory (where 'build.sh' exists) to 'makeDMG4mac.py', that is,
```
makeDMG4mac.py -> macbuild/makeDMG4mac.py
```
2. Invoke 'makeDMG4mac.py' with -p and -m options, for example,
```
$ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
```
By: Kazzz (January 16, 2018)
[End of File] [End of File]

View File

@ -1,4 +1,4 @@
<< Draft Version 0.003>> << Draft Version 0.004>>
Relevant KLayout version: 0.25.1 Relevant KLayout version: 0.25.1
1. Introduction: 1. Introduction:
@ -15,7 +15,7 @@ Relevant KLayout version: 0.25.1
<IMPORTANT>: <IMPORTANT>:
* Please DO NOT USE "5.10.0" which is problematic in showing your design in the main canvas. * Please DO NOT USE "5.10.0" which is problematic in showing your design in the main canvas.
* Please USE "5.9.x" instead. * Please USE "5.9.x" instead (5.9.3 is recommended).
* Building with Qt4 will lead to some compile errors. * Building with Qt4 will lead to some compile errors.
Also by default, supported script languages, i.e, Ruby and Python, are those Also by default, supported script languages, i.e, Ruby and Python, are those
@ -42,6 +42,7 @@ Relevant KLayout version: 0.25.1
(3) Confirm successful build. (3) Confirm successful build.
(4) Run 'build4mac.py' again with the same options used in (2) PLUS "-y" (4) Run 'build4mac.py' again with the same options used in (2) PLUS "-y"
to deploy executables and libraries (including Qt's frameworks) under "klayout.app" bundle. to deploy executables and libraries (including Qt's frameworks) under "klayout.app" bundle.
The buddy command line tools (strm*) will also be deployed.
$ ./build4mac.py -d -y $ ./build4mac.py -d -y
(5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your (5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your
"/Applications" directory for installation. "/Applications" directory for installation.
@ -57,6 +58,7 @@ Relevant KLayout version: 0.25.1
(3) Confirm successful build. (3) Confirm successful build.
(4) Run 'build4mac.py' again with the same options used in (2) PLUS "-Y" (4) Run 'build4mac.py' again with the same options used in (2) PLUS "-Y"
to deploy executables and libraries under "klayout.app" bundle. to deploy executables and libraries under "klayout.app" bundle.
The buddy command line tools (strm*) will also be deployed.
$ ./build4mac.py -r mp24 -p mp36 -Y $ ./build4mac.py -r mp24 -p mp36 -Y
* [-Y|--DEPOLY] option deploys KLayout's dylibs and executables only. * [-Y|--DEPOLY] option deploys KLayout's dylibs and executables only.
That is, paths to other modules (Ruby, Python, and Qt5 Frameworks) That is, paths to other modules (Ruby, Python, and Qt5 Frameworks)
@ -64,6 +66,15 @@ Relevant KLayout version: 0.25.1
(5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your (5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your
"/Applications" directory for installation. "/Applications" directory for installation.
By: Kazzz (January 08, 2018) 4. Making a DMG installer
You can make a DMG installer using another Python script 'makeDMG4mac.py'.
This script requires a directory generated by 'build4mac.py' with [-y|-Y] option (refer to 3A.4 & 3B.4)
(1) Make a symbolic link from the parent directory (where 'build.sh' exists) to 'makeDMG4mac.py', that is,
makeDMG4mac.py -> macbuild/makeDMG4mac.py
(2) Invoke 'makeDMG4mac.py' with -p and -m options, for example,
$ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
By: Kazzz (January 16, 2018)
[End of File] [End of File]

View File

@ -43,13 +43,13 @@ def SetGlobals():
global DMGSerialNum # the DMG serial number global DMGSerialNum # the DMG serial number
global QtIdentification # Qt identification global QtIdentification # Qt identification
global Version # KLayout's version global Version # KLayout's version
global OccupiedDS # approx. occupied dist space global OccupiedDS # approx. occupied disc space
global BackgroundPNG # the background PNG image file global BackgroundPNG # the background PNG image file
global VolumeIcons # the volume icon file global VolumeIcons # the volume icon file
global AppleScriptDMG # the AppleScript for KLayout DMG global AppleScriptDMG # the AppleScript for KLayout DMG
global WorkDMG # work DMG file deployed under ProjectDir/ global WorkDMG # work DMG file created under ProjectDir/
global VolumeDMG # the volume name of DMG global VolumeDMG # the volume name of DMG
global TargetDMG # name of the target DMG file global TargetDMG # the name of target DMG file
global RootApplications # reserved directory name for applications global RootApplications # reserved directory name for applications
# auxiliary variables on platform # auxiliary variables on platform
global System # 6-tuple from platform.uname() global System # 6-tuple from platform.uname()
@ -126,7 +126,7 @@ def SetGlobals():
WorkDMG = "work-KLayout.dmg" WorkDMG = "work-KLayout.dmg"
VolumeDMG = "KLayout" VolumeDMG = "KLayout"
TargetDMG = "" TargetDMG = ""
RootApplications = "/Applications" # reserved directory name for applications RootApplications = "/Applications"
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
## To check the contents of the package directory ## To check the contents of the package directory
@ -181,8 +181,8 @@ def CheckPkgDirectory():
os.chdir(ProjectDir) os.chdir(ProjectDir)
os.chdir(PkgDir) os.chdir(PkgDir)
size1 = int( os.popen( "du -sm klayout.app" ) .read().strip("\n").split("\t")[0] ) size1 = int( os.popen( "\du -sm klayout.app" ) .read().strip("\n").split("\t")[0] )
size2 = int( os.popen( "du -sm klayout.scripts" ).read().strip("\n").split("\t")[0] ) size2 = int( os.popen( "\du -sm klayout.scripts" ).read().strip("\n").split("\t")[0] )
os.chdir(ProjectDir) os.chdir(ProjectDir)
return size1+size2 return size1+size2
@ -275,17 +275,18 @@ def MakeTargetDMGFile(msg=""):
# /dev/disk6s1 248Mi 228Mi 20Mi 93% 58449 5027 92% /Volumes/KLayout # /dev/disk6s1 248Mi 228Mi 20Mi 93% 58449 5027 92% /Volumes/KLayout
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
global MountDir # the mount directory: eg. /Volumes/KLayout global MountDir # the mount directory: eg. /Volumes/KLayout
global WorkDev # the file system : eg. /dev/disk6s1 global FileSys # the file system : eg. /dev/disk6s1
#---------------------------------------------------- #-------------------------------------------------------------
# [1] Print message # [1] Print message
#---------------------------------------------------- #-------------------------------------------------------------
if not msg == "": if not msg == "":
print(msg) print(msg)
#---------------------------------------------------- #-------------------------------------------------------------
# [2] Do the following jobs sequentially # [2] Do the following jobs (0) through (14) sequentially
#---------------------------------------------------- #-------------------------------------------------------------
#-------------------------------------------------------- #--------------------------------------------------------
# (0) Cleanup ProjectDir/ # (0) Cleanup ProjectDir/
#-------------------------------------------------------- #--------------------------------------------------------
@ -293,19 +294,21 @@ def MakeTargetDMGFile(msg=""):
#-------------------------------------------------------- #--------------------------------------------------------
# (1) Read the AppleScript template file and generate # (1) Read the AppleScript template file and generate
# an actual one to execute later # the actual one to execute later
#-------------------------------------------------------- #--------------------------------------------------------
os.chdir(ProjectDir) os.chdir(ProjectDir)
print( ">>> (1) Preparing AppleScript to execute later..." ) print( ">>> (1) Preparing AppleScript to execute later..." )
tempScr = "macbuild/Resources/template-KLayoutDMG.applescript"
try: try:
fd = open( "macbuild/Resources/template-KLayoutDMG.applescript", "r" ) fd = open( tempScr, "r" )
tmpl = fd.read() tmpl = fd.read()
fd.close() fd.close()
except Exception as e: except Exception as e:
print( " ! Failed to read <template-KLayoutDMG.applescript>", file=sys.stderr ) print( " ! Failed to read <%s>" tempScr % , file=sys.stderr )
return False return False
else: else:
t = string.Template(tmpl) t = string.Template(tmpl)
# Figures below were determined by experiments for best fit
applescript = t.safe_substitute( applescript = t.safe_substitute(
ORGX='50', ORGY='100', ORGX='50', ORGY='100',
WIN_WIDTH='1000', WIN_HEIGHT='700', WIN_WIDTH='1000', WIN_HEIGHT='700',
@ -334,7 +337,7 @@ def MakeTargetDMGFile(msg=""):
os.remove(WorkDMG) os.remove(WorkDMG)
dmgsize = OccupiedDS + 20 # approx. occupied size plus 20[MB] dmgsize = OccupiedDS + 20 # approx. occupied size plus 20[MB]
cmdline = 'hdiutil create -srcfolder %s -volname %s -fs HFS+ -fsargs "-c c=64,a=16,e=16" ' cmdline = 'hdiutil create -srcfolder %s -volname %s -fs HFS+ -fsargs "-c c=64,a=16,e=16" '
cmdline += '-format UDRW -size %sm %s' cmdline += '-format UDRW -size %dm %s'
command = cmdline % (PkgDir, VolumeDMG, dmgsize, WorkDMG) command = cmdline % (PkgDir, VolumeDMG, dmgsize, WorkDMG)
print( ">>> (2) Creating a work DMG file <%s> of <%d> [MB] with the volume name of <%s>..." % (WorkDMG, dmgsize, VolumeDMG) ) print( ">>> (2) Creating a work DMG file <%s> of <%d> [MB] with the volume name of <%s>..." % (WorkDMG, dmgsize, VolumeDMG) )
os.system(command) os.system(command)
@ -342,13 +345,13 @@ def MakeTargetDMGFile(msg=""):
#-------------------------------------------------------- #--------------------------------------------------------
# (3) Check if the mount point 'MountDir' already exists. # (3) Check if the mount point 'MountDir' already exists.
# If so, unmount it. # If so, unmount it first.
#-------------------------------------------------------- #--------------------------------------------------------
command1 = "hdiutil info | grep %s | grep \"/dev/\" | awk '{print $1}'" % VolumeDMG command1 = "hdiutil info | grep %s | grep \"/dev/\" | awk '{print $1}'" % VolumeDMG
print ( ">>> (3) Checking if the mount point <%s> already exists..." % MountDir) print ( ">>> (3) Checking if the mount point <%s> already exists..." % MountDir)
WorkDev = os.popen(command1).read().strip('\n') FileSys = os.popen(command1).read().strip('\n')
if os.path.isdir(MountDir) and not WorkDev == "": if os.path.isdir(MountDir) and not FileSys == "":
command2 = "hdiutil detach %s" % WorkDev command2 = "hdiutil detach %s" % FileSys
os.system(command2) os.system(command2)
print( " Mount directory <%s> was detached" % MountDir ) print( " Mount directory <%s> was detached" % MountDir )
else: else:
@ -362,29 +365,29 @@ def MakeTargetDMGFile(msg=""):
os.system(command1) os.system(command1)
command2 = "hdiutil info | grep %s | grep \"/dev/\" | awk '{print $1}'" % VolumeDMG command2 = "hdiutil info | grep %s | grep \"/dev/\" | awk '{print $1}'" % VolumeDMG
WorkDev = os.popen(command2).read().strip('\n') FileSys = os.popen(command2).read().strip('\n')
if WorkDev == "": if FileSys == "":
print( "! Failed to identify the file system on which <%s> is mounted" % VolumeDMG ) print( "! Failed to identify the file system on which <%s> is mounted" % VolumeDMG )
return False return False
else: else:
print( " Work Device = %s" % WorkDev ) print( " File System = %s" % FileSys )
#-------------------------------------------------------- #--------------------------------------------------------
# (5) Copy the background image # (5) Copy the background image
#-------------------------------------------------------- #--------------------------------------------------------
print( ">>> (5) Copying the background image and the volume icon..." ) print( ">>> (5) Copying the background image..." )
imageSrc = "macbuild/Resources/%s" % BackgroundPNG imageSrc = "macbuild/Resources/%s" % BackgroundPNG
imageDest = "%s/.background" % MountDir imageDest = "%s/.background" % MountDir
if not os.path.isdir(imageDest): if not os.path.isdir(imageDest):
os.mkdir(imageDest) os.mkdir(imageDest)
command = "cp -p %s %s/%s" % (imageSrc, imageDest, BackgroundPNG) command = "\cp -p %s %s/%s" % (imageSrc, imageDest, BackgroundPNG)
os.system(command) os.system(command)
#-------------------------------------------------------- #--------------------------------------------------------
# (6) Create a symbolic link to /Applications # (6) Create a symbolic link to /Applications
#-------------------------------------------------------- #--------------------------------------------------------
print( ">>> (6) Creating a symbolic link to /Applications..." ) print( ">>> (6) Creating a symbolic link to /Applications..." )
command = "ln -s %s %s/%s" % (RootApplications, MountDir, RootApplications) command = "\ln -s %s %s/%s" % (RootApplications, MountDir, RootApplications)
os.system(command) os.system(command)
#-------------------------------------------------------- #--------------------------------------------------------
@ -394,7 +397,6 @@ def MakeTargetDMGFile(msg=""):
command = "/usr/bin/osascript %s %s" % (AppleScriptDMG, VolumeDMG) command = "/usr/bin/osascript %s %s" % (AppleScriptDMG, VolumeDMG)
process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True ) process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True )
output, error = process.communicate() output, error = process.communicate()
sleep(4)
if not output == "": if not output == "":
print( " STDOUT: %s" % output ) print( " STDOUT: %s" % output )
if not error == "": if not error == "":
@ -403,27 +405,32 @@ def MakeTargetDMGFile(msg=""):
#-------------------------------------------------------- #--------------------------------------------------------
# (8) Copy the custom volume icon # (8) Copy the custom volume icon
#-------------------------------------------------------- #--------------------------------------------------------
sleep(4)
print( ">>> (8) Copying the volume icon..." ) print( ">>> (8) Copying the volume icon..." )
iconsSrc = "macbuild/Resources/%s" % VolumeIcons iconsSrc = "macbuild/Resources/%s" % VolumeIcons
iconsDest = "%s/.VolumeIcon.icns" % MountDir iconsDest = "%s/.VolumeIcon.icns" % MountDir
command1 = "cp -p %s %s" % (iconsSrc, iconsDest) command1 = "\cp -p %s %s" % (iconsSrc, iconsDest)
command2 = "SetFile -c icnC %s" % iconsDest command2 = "SetFile -c icnC %s" % iconsDest
os.system(command1) os.system(command1)
sleep(2)
os.system(command2) os.system(command2)
sleep(2)
#-------------------------------------------------------- #--------------------------------------------------------
# (9) Change the permission # (9) Change the permission
#-------------------------------------------------------- #--------------------------------------------------------
print( ">>> (9) Changing permission to 755..." ) print( ">>> (9) Changing permission to 755..." )
command = "chmod -Rf 755 %s &> /dev/null" % MountDir command = "\chmod -Rf 755 %s &> /dev/null" % MountDir
os.system(command) os.system(command)
#-------------------------------------------------------- #--------------------------------------------------------
# (10) Set volume bootability and startup disk options # (10) Set volume bootability and startup disk options.
# The folder will open on mount.
#-------------------------------------------------------- #--------------------------------------------------------
print( ">>> (10) Setting volume bootability and startup disk options..." ) print( ">>> (10) Setting volume bootability and startup disk options..." )
command = "bless --folder %s --openfolder %s" % (MountDir, MountDir) command = "bless --folder %s --openfolder %s" % (MountDir, MountDir)
os.system(command) os.system(command)
sleep(2)
#-------------------------------------------------------- #--------------------------------------------------------
# (11) Set attributes of files and directories # (11) Set attributes of files and directories
@ -431,12 +438,13 @@ def MakeTargetDMGFile(msg=""):
print( ">>> (11) Setting attributes of files and directories..." ) print( ">>> (11) Setting attributes of files and directories..." )
command = "SetFile -a C %s" % MountDir # Custom icon (allowed on folders) command = "SetFile -a C %s" % MountDir # Custom icon (allowed on folders)
os.system(command) os.system(command)
sleep(2)
#-------------------------------------------------------- #--------------------------------------------------------
# (12) Unmount the disk image # (12) Unmount the disk image
#-------------------------------------------------------- #--------------------------------------------------------
print( ">>> (12) Unmounting the disk image..." ) print( ">>> (12) Unmounting the disk image..." )
command = "hdiutil detach %s" % WorkDev command = "hdiutil detach %s" % FileSys
os.system(command) os.system(command)
#-------------------------------------------------------- #--------------------------------------------------------
@ -448,7 +456,7 @@ def MakeTargetDMGFile(msg=""):
os.system(command) os.system(command)
os.remove(WorkDMG) os.remove(WorkDMG)
print( "" ) print( "" )
print( " generated compressed DMG <%s>" % TargetDMG ) print( " generated compressed target DMG <%s>" % TargetDMG )
#-------------------------------------------------------- #--------------------------------------------------------
# (14) Compute MD5 checksum # (14) Compute MD5 checksum
@ -508,6 +516,7 @@ def Main():
print( "" ) print( "" )
print( " ### You are going to make <%s> from <%s>" % (TargetDMG, PkgDir) ) print( " ### You are going to make <%s> from <%s>" % (TargetDMG, PkgDir) )
print( " KLayout bundles occupy about <%d> [MB] of disc space." % OccupiedDS ) print( " KLayout bundles occupy about <%d> [MB] of disc space." % OccupiedDS )
print( "" )
ok = MakeTargetDMGFile() ok = MakeTargetDMGFile()
if not ok: if not ok:
print( " !!! Failed to make the target DMG <%s> ..." % TargetDMG, file=sys.stderr ) print( " !!! Failed to make the target DMG <%s> ..." % TargetDMG, file=sys.stderr )