Package wafadmin :: Package Tools :: Module osx
[hide private]
[frames] | no frames]

Source Code for Module wafadmin.Tools.osx

  1  #!/usr/bin/env python 
  2  # encoding: utf-8 
  3  # Thomas Nagy 2008 
  4   
  5  """MacOSX related tools 
  6   
  7  To compile an executable into a Mac application bundle (a .app), set its 'mac_app' attribute 
  8    obj.mac_app = True 
  9   
 10  To make a bundled shared library (a .bundle), set the 'mac_bundle' attribute: 
 11    obj.mac_bundle = True 
 12  """ 
 13   
 14  import os, shutil, sys 
 15  import TaskGen, Task, Build, Options 
 16  from TaskGen import taskgen, feature, after, before 
 17  from Logs import error, debug 
18 19 @taskgen 20 -def create_task_macapp(self):
21 if self.type == 'program' and self.link_task: 22 apptask = self.create_task('macapp', self.env) 23 apptask.set_inputs(self.link_task.outputs) 24 apptask.set_outputs(self.link_task.outputs[0].change_ext('.app')) 25 self.apptask = apptask
26 42
43 @taskgen 44 @before('apply_link') 45 @before('apply_lib_vars') 46 @feature('cc', 'cxx') 47 -def apply_bundle(self):
48 """the uselib system cannot modify a few things, use env['MACBUNDLE'] to force all shlibs into mac bundles 49 or use obj.mac_bundle = True for specific targets only""" 50 if not 'shlib' in self.features: return 51 if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False): 52 self.env['shlib_PATTERN'] = '%s.bundle' 53 uselib = self.to_list(self.uselib) 54 if not 'MACBUNDLE' in uselib: uselib.append('MACBUNDLE')
55
56 @taskgen 57 @after('apply_link') 58 @feature('cc', 'cxx') 59 -def apply_bundle_remove_dynamiclib(self):
60 if not 'shlib' in self.features: return 61 if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False): 62 self.env["LINKFLAGS"].remove("-dynamiclib") 63 self.env.append_value("LINKFLAGS", "-bundle")
64 65 66 67 app_dirs = ['Contents', os.path.join('Contents','MacOS'), os.path.join('Contents','Resources')] 68 69 app_info = ''' 70 <?xml version="1.0" encoding="UTF-8"?> 71 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> 72 <plist version="0.9"> 73 <dict> 74 <key>CFBundlePackageType</key> 75 <string>APPL</string> 76 <key>CFBundleGetInfoString</key> 77 <string>Created by Waf</string> 78 <key>CFBundleSignature</key> 79 <string>????</string> 80 <key>NOTE</key> 81 <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string> 82 <key>CFBundleExecutable</key> 83 <string>%s</string> 84 </dict> 85 </plist> 86 '''
87 88 -def app_build(task):
89 global app_dirs 90 env = task.env 91 92 i = 0 93 for p in task.outputs: 94 srcfile = p.srcpath(env) 95 96 debug('osx: creating directories') 97 try: 98 os.mkdir(srcfile) 99 [os.makedirs(os.path.join(srcfile, d)) for d in app_dirs] 100 except (OSError, IOError): 101 pass 102 103 # copy the program to the contents dir 104 srcprg = task.inputs[i].srcpath(env) 105 dst = os.path.join(srcfile, 'Contents', 'MacOS') 106 debug('osx: copy %s to %s' % (srcprg, dst)) 107 shutil.copy(srcprg, dst) 108 109 # create info.plist 110 debug('osx: generate Info.plist') 111 # TODO: Support custom info.plist contents. 112 113 f = file(os.path.join(srcfile, "Contents", "Info.plist"), "w") 114 f.write(app_info % os.path.basename(srcprg)) 115 f.close() 116 117 i += 1 118 119 return 0
120
121 -def install_shlib(task):
122 """see http://code.google.com/p/waf/issues/detail?id=173""" 123 nums = task.vnum.split('.') 124 125 path = self.install_path 126 127 libname = task.outputs[0].name 128 129 name3 = libname.replace('.dylib', '.%s.dylib' % task.vnum) 130 name2 = libname.replace('.dylib', '.%s.dylib' % nums[0]) 131 name1 = libname 132 133 filename = task.outputs[0].abspath(task.env) 134 bld = Build.bld 135 bld.install_as(path + name3, filename, env=task.env) 136 bld.symlink_as(path + name2, name3) 137 bld.symlink_as(path + name1, name3)
138
139 @taskgen 140 @feature('osx') 141 @after('install_target_cshlib') 142 -def install_target_osx_cshlib(self):
143 if not Options.is_install: return 144 if getattr(self, 'vnum', '') and sys.platform != 'win32': 145 self.link_task.install = install_shlib
146 147 Task.task_type_from_func('macapp', vars=[], func=app_build, after="cxx_link cc_link ar_link_static") 148