s3: libsmbclient: Add missing talloc stackframe.
[bbaumbach/samba-autobuild/.git] / third_party / waf / wafadmin / Tools / osx.py
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, platform
15 import TaskGen, Task, Build, Options, Utils
16 from TaskGen import taskgen, feature, after, before
17 from Logs import error, debug
18
19 # plist template
20 app_info = '''
21 <?xml version="1.0" encoding="UTF-8"?>
22 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
23 <plist version="0.9">
24 <dict>
25         <key>CFBundlePackageType</key>
26         <string>APPL</string>
27         <key>CFBundleGetInfoString</key>
28         <string>Created by Waf</string>
29         <key>CFBundleSignature</key>
30         <string>????</string>
31         <key>NOTE</key>
32         <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
33         <key>CFBundleExecutable</key>
34         <string>%s</string>
35 </dict>
36 </plist>
37 '''
38
39 # see WAF issue 285
40 # and also http://trac.macports.org/ticket/17059
41 @feature('cc', 'cxx')
42 @before('apply_lib_vars')
43 def set_macosx_deployment_target(self):
44         if self.env['MACOSX_DEPLOYMENT_TARGET']:
45                 os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env['MACOSX_DEPLOYMENT_TARGET']
46         elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
47                 if sys.platform == 'darwin':
48                         os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2])
49
50 @feature('cc', 'cxx')
51 @after('apply_lib_vars')
52 def apply_framework(self):
53         for x in self.to_list(self.env['FRAMEWORKPATH']):
54                 frameworkpath_st = '-F%s'
55                 self.env.append_unique('CXXFLAGS', frameworkpath_st % x)
56                 self.env.append_unique('CCFLAGS', frameworkpath_st % x)
57                 self.env.append_unique('LINKFLAGS', frameworkpath_st % x)
58
59         for x in self.to_list(self.env['FRAMEWORK']):
60                 self.env.append_value('LINKFLAGS', ['-framework', x])
61
62 @taskgen
63 def create_bundle_dirs(self, name, out):
64         bld = self.bld
65         dir = out.parent.get_dir(name)
66
67         if not dir:
68                 dir = out.__class__(name, out.parent, 1)
69                 bld.rescan(dir)
70                 contents = out.__class__('Contents', dir, 1)
71                 bld.rescan(contents)
72                 macos = out.__class__('MacOS', contents, 1)
73                 bld.rescan(macos)
74         return dir
75
76 def bundle_name_for_output(out):
77         name = out.name
78         k = name.rfind('.')
79         if k >= 0:
80                 name = name[:k] + '.app'
81         else:
82                 name = name + '.app'
83         return name
84
85 @taskgen
86 @after('apply_link')
87 @feature('cprogram')
88 def create_task_macapp(self):
89         """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications
90         or use obj.mac_app = True to build specific targets as Mac apps"""
91         if self.env['MACAPP'] or getattr(self, 'mac_app', False):
92                 apptask = self.create_task('macapp')
93                 apptask.set_inputs(self.link_task.outputs)
94
95                 out = self.link_task.outputs[0]
96
97                 name = bundle_name_for_output(out)
98                 dir = self.create_bundle_dirs(name, out)
99
100                 n1 = dir.find_or_declare(['Contents', 'MacOS', out.name])
101
102                 apptask.set_outputs([n1])
103                 apptask.chmod = 0755
104                 apptask.install_path = os.path.join(self.install_path, name, 'Contents', 'MacOS')
105                 self.apptask = apptask
106
107 @after('apply_link')
108 @feature('cprogram')
109 def create_task_macplist(self):
110         """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications
111         or use obj.mac_app = True to build specific targets as Mac apps"""
112         if  self.env['MACAPP'] or getattr(self, 'mac_app', False):
113                 # check if the user specified a plist before using our template
114                 if not getattr(self, 'mac_plist', False):
115                         self.mac_plist = app_info
116
117                 plisttask = self.create_task('macplist')
118                 plisttask.set_inputs(self.link_task.outputs)
119
120                 out = self.link_task.outputs[0]
121                 self.mac_plist = self.mac_plist % (out.name)
122
123                 name = bundle_name_for_output(out)
124                 dir = self.create_bundle_dirs(name, out)
125
126                 n1 = dir.find_or_declare(['Contents', 'Info.plist'])
127
128                 plisttask.set_outputs([n1])
129                 plisttask.mac_plist = self.mac_plist
130                 plisttask.install_path = os.path.join(self.install_path, name, 'Contents')
131                 self.plisttask = plisttask
132
133 @after('apply_link')
134 @feature('cshlib')
135 def apply_link_osx(self):
136         name = self.link_task.outputs[0].name
137         if not self.install_path:
138                 return
139         if getattr(self, 'vnum', None):
140                 name = name.replace('.dylib', '.%s.dylib' % self.vnum)
141
142         path = os.path.join(Utils.subst_vars(self.install_path, self.env), name)
143         if '-dynamiclib' in self.env['LINKFLAGS']:
144                 self.env.append_value('LINKFLAGS', '-install_name')
145                 self.env.append_value('LINKFLAGS', path)
146
147 @before('apply_link', 'apply_lib_vars')
148 @feature('cc', 'cxx')
149 def apply_bundle(self):
150         """use env['MACBUNDLE'] to force all shlibs into mac bundles
151         or use obj.mac_bundle = True for specific targets only"""
152         if not ('cshlib' in self.features or 'shlib' in self.features): return
153         if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False):
154                 self.env['shlib_PATTERN'] = self.env['macbundle_PATTERN']
155                 uselib = self.uselib = self.to_list(self.uselib)
156                 if not 'MACBUNDLE' in uselib: uselib.append('MACBUNDLE')
157
158 @after('apply_link')
159 @feature('cshlib')
160 def apply_bundle_remove_dynamiclib(self):
161         if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False):
162                 if not getattr(self, 'vnum', None):
163                         try:
164                                 self.env['LINKFLAGS'].remove('-dynamiclib')
165                                 self.env['LINKFLAGS'].remove('-single_module')
166                         except ValueError:
167                                 pass
168
169 # TODO REMOVE IN 1.6 (global variable)
170 app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources']
171
172 def app_build(task):
173         env = task.env
174         shutil.copy2(task.inputs[0].srcpath(env), task.outputs[0].abspath(env))
175
176         return 0
177
178 def plist_build(task):
179         env = task.env
180         f = open(task.outputs[0].abspath(env), "w")
181         f.write(task.mac_plist)
182         f.close()
183
184         return 0
185
186 Task.task_type_from_func('macapp', vars=[], func=app_build, after="cxx_link cc_link static_link")
187 Task.task_type_from_func('macplist', vars=[], func=plist_build, after="cxx_link cc_link static_link")