try to get mussagl to build on win32
[mussa.git] / makelib / osxdist.py
1 #!/usr/bin/env python
2
3 import os
4 import sys
5 import getopt
6
7 from shutil import copy, copytree
8
9 def system(cmdline):
10   #print >>sys.stderr, cmdline
11   return os.system(cmdline)
12
13 def mkdir(path):
14   path_list = []
15   head, tail = os.path.split(path)
16   path_list.insert(0, tail)
17   while len(head) > 0:
18     head, tail = os.path.split(head)
19     path_list.insert(0, tail)
20   created_path = ""
21   for path_element in path_list:
22     created_path = os.path.join(created_path, path_element)
23     if not os.path.exists(created_path):
24       os.mkdir(created_path)
25     
26 # useful information about building dmgs
27 # http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix
28 # http://developer.apple.com/documentation/developertools/Conceptual/SoftwareDistribution/Concepts/sd_disk_images.html
29
30 def makedmg(dirlist, volname):
31   """copy a list of directories into a dmg named volname
32   """
33
34   # need to detect what the real volume name is
35   mussa_mount = '/Volumes/%s' %(volname)
36   mussarw_dmg = '%sw.dmg' %(volname)
37   mussa_dmg = '%s.dmg' %(volname)
38   system('hdiutil detach '+mussa_mount)
39   if os.path.exists(mussa_mount):
40     print >>sys.stderr, "Something is in", mussa_mount
41     return 
42   if os.path.exists(mussarw_dmg):
43     os.unlink(mussarw_dmg)
44   if os.path.exists(mussa_dmg):
45     os.unlink(mussa_dmg)
46   system('hdiutil create -size 64m -fs HFS+ -volname "%s" %s'%(volname, mussarw_dmg))
47   system('hdiutil attach '+mussarw_dmg)
48   # copy files
49   for d in dirlist:
50     if d[-1] == '/':
51       d = d[:-1]
52     tail = os.path.split(d)[-1]
53     copytree(d, os.path.join(mussa_mount, tail))
54
55   system('hdiutil detach '+mussa_mount)
56   system('hdiutil convert '+mussarw_dmg +' -format UDZO -o '+mussa_dmg)
57   #system('hdiutil internet-enable -yes '+mussa_dmg)
58
59 def prelinkqt(app_name, bundle_dir, qt_lib_dir):
60   """
61   OS X's treatment of dynamic loading is annoying
62   properly prelink all the annoying qt components.
63   """
64   framework_subpath = os.path.join("%(framework)s.framework", "Versions", "4.0", "%(framework)s")
65   frameworks = ['QtCore', 'QtGui', 'QtOpenGL']
66
67   qt_framework=os.path.join(qt_lib_dir, framework_subpath)
68   app_binary=bundle_dir+"/Contents/MacOS/"+app_name
69   app_framework=os.path.join(bundle_dir, "Contents", "Frameworks", framework_subpath)
70   # install frameworks and update binary
71   for frame in frameworks:
72     qtframe = qt_framework % ({'framework': frame})
73     appframe = app_framework % ({'framework': frame})
74     exe_path = "@executable_path/../Frameworks/" + framework_subpath
75     exe_path %= ({'framework': frame})
76     mkdir(os.path.split(appframe)[0])
77     # update binary
78     copy(qtframe, appframe)
79     system("install_name_tool -id "+exe_path+" "+appframe)
80     system("install_name_tool -change "+qtframe+" "+exe_path+" "+app_binary)
81     # now that everything is in place change the frameworks 
82     # references
83     for frame2 in frameworks:
84       qtframe2 = qt_framework % ({'framework': frame2})
85       contents_exe_path = "@executable_path/../Frameworks/" + framework_subpath
86       contents_exe_path %= ({'framework': frame2})
87       system("install_name_tool -change "+qtframe2+" "+contents_exe_path+" "+
88              appframe)
89
90 def main(args):
91   qtroot = "/usr/local/qt-4.1.1"
92   bundle_dir = None
93   app_name = None
94   
95   opts, args = getopt.getopt(args, "b:n:q:h", 
96                              ["bundle=", "name=", "qt-root=", "help"])
97   for option, argument in opts:
98     if option in ("-b", "--bundle"):
99       bundle_dir = argument
100     elif option in ("-n", "--name"):
101       app_name = argument
102     elif option in ("-q", "--qt-root"):
103       qtroot = argument
104     elif option in ("-h", "--help"):
105       print "-b | --bundle   specify path to application bundle dir"
106       print "-n | --name     specify application name (and volume name)"
107       print "-q | --qtdir    where is qt is installed"
108       print "-h | --help     how to use"
109       return 0
110
111   # compute bundle name/dir
112   if bundle_dir is None and app_name is None:
113     print >>sys.stderr, "I need a name or bundle path"
114     return 1
115   elif bundle_dir is None:
116     bundle_dir = app_name + ".app"
117   elif app_name is None:
118     # strip off trailing /
119     if bundle_dir[-1] == os.path.sep:
120       bundle_dir = bundle_dir[:-1]
121     path, file = os.path.split(bundle_dir)
122     app_name = os.path.splitext(file)[0]
123
124   if not os.path.exists(bundle_dir):
125     print >>sys.stderr, "couldn't find an app at %s" % (app_bundle)
126     return 1
127   
128   qt_lib_dir = os.path.join(qtroot, 'lib')
129
130   prelinkqt(app_name, bundle_dir, qt_lib_dir)
131   makedmg([bundle_dir]+args, app_name)
132
133 if __name__ == "__main__":
134   main(sys.argv[1:])