ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / third_party / waf / waflib / Tools / c_osx.py
blobf70b128b87482b3cee9323205fe94afb471a66f3
1 #!/usr/bin/env python
2 # encoding: utf-8
3 # Thomas Nagy 2008-2018 (ita)
5 """
6 MacOSX related tools
7 """
9 import os, shutil, platform
10 from waflib import Task, Utils
11 from waflib.TaskGen import taskgen_method, feature, after_method, before_method
13 app_info = '''
14 <?xml version="1.0" encoding="UTF-8"?>
15 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
16 <plist version="0.9">
17 <dict>
18 <key>CFBundlePackageType</key>
19 <string>APPL</string>
20 <key>CFBundleGetInfoString</key>
21 <string>Created by Waf</string>
22 <key>CFBundleSignature</key>
23 <string>????</string>
24 <key>NOTE</key>
25 <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
26 <key>CFBundleExecutable</key>
27 <string>{app_name}</string>
28 </dict>
29 </plist>
30 '''
31 """
32 plist template
33 """
35 @feature('c', 'cxx')
36 def set_macosx_deployment_target(self):
37 """
38 see WAF issue 285 and also and also http://trac.macports.org/ticket/17059
39 """
40 if self.env.MACOSX_DEPLOYMENT_TARGET:
41 os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env.MACOSX_DEPLOYMENT_TARGET
42 elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
43 if Utils.unversioned_sys_platform() == 'darwin':
44 os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2])
46 @taskgen_method
47 def create_bundle_dirs(self, name, out):
48 """
49 Creates bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp`
50 """
51 dir = out.parent.find_or_declare(name)
52 dir.mkdir()
53 macos = dir.find_or_declare(['Contents', 'MacOS'])
54 macos.mkdir()
55 return dir
57 def bundle_name_for_output(out):
58 name = out.name
59 k = name.rfind('.')
60 if k >= 0:
61 name = name[:k] + '.app'
62 else:
63 name = name + '.app'
64 return name
66 @feature('cprogram', 'cxxprogram')
67 @after_method('apply_link')
68 def create_task_macapp(self):
69 """
70 To compile an executable into a Mac application (a .app), set its *mac_app* attribute::
72 def build(bld):
73 bld.shlib(source='a.c', target='foo', mac_app=True)
75 To force *all* executables to be transformed into Mac applications::
77 def build(bld):
78 bld.env.MACAPP = True
79 bld.shlib(source='a.c', target='foo')
80 """
81 if self.env.MACAPP or getattr(self, 'mac_app', False):
82 out = self.link_task.outputs[0]
84 name = bundle_name_for_output(out)
85 dir = self.create_bundle_dirs(name, out)
87 n1 = dir.find_or_declare(['Contents', 'MacOS', out.name])
89 self.apptask = self.create_task('macapp', self.link_task.outputs, n1)
90 inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name
91 self.add_install_files(install_to=inst_to, install_from=n1, chmod=Utils.O755)
93 if getattr(self, 'mac_files', None):
94 # this only accepts files; they will be installed as seen from mac_files_root
95 mac_files_root = getattr(self, 'mac_files_root', None)
96 if isinstance(mac_files_root, str):
97 mac_files_root = self.path.find_node(mac_files_root)
98 if not mac_files_root:
99 self.bld.fatal('Invalid mac_files_root %r' % self.mac_files_root)
100 res_dir = n1.parent.parent.make_node('Resources')
101 inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name
102 for node in self.to_nodes(self.mac_files):
103 relpath = node.path_from(mac_files_root or node.parent)
104 self.create_task('macapp', node, res_dir.make_node(relpath))
105 self.add_install_as(install_to=os.path.join(inst_to, relpath), install_from=node)
107 if getattr(self.bld, 'is_install', None):
108 # disable regular binary installation
109 self.install_task.hasrun = Task.SKIP_ME
111 @feature('cprogram', 'cxxprogram')
112 @after_method('apply_link')
113 def create_task_macplist(self):
115 Creates a :py:class:`waflib.Tools.c_osx.macplist` instance.
117 if self.env.MACAPP or getattr(self, 'mac_app', False):
118 out = self.link_task.outputs[0]
120 name = bundle_name_for_output(out)
122 dir = self.create_bundle_dirs(name, out)
123 n1 = dir.find_or_declare(['Contents', 'Info.plist'])
124 self.plisttask = plisttask = self.create_task('macplist', [], n1)
125 plisttask.context = {
126 'app_name': self.link_task.outputs[0].name,
127 'env': self.env
130 plist_ctx = getattr(self, 'plist_context', None)
131 if (plist_ctx):
132 plisttask.context.update(plist_ctx)
134 if getattr(self, 'mac_plist', False):
135 node = self.path.find_resource(self.mac_plist)
136 if node:
137 plisttask.inputs.append(node)
138 else:
139 plisttask.code = self.mac_plist
140 else:
141 plisttask.code = app_info
143 inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name
144 self.add_install_files(install_to=inst_to, install_from=n1)
146 @feature('cshlib', 'cxxshlib')
147 @before_method('apply_link', 'propagate_uselib_vars')
148 def apply_bundle(self):
150 To make a bundled shared library (a ``.bundle``), set the *mac_bundle* attribute::
152 def build(bld):
153 bld.shlib(source='a.c', target='foo', mac_bundle = True)
155 To force *all* executables to be transformed into bundles::
157 def build(bld):
158 bld.env.MACBUNDLE = True
159 bld.shlib(source='a.c', target='foo')
161 if self.env.MACBUNDLE or getattr(self, 'mac_bundle', False):
162 self.env.LINKFLAGS_cshlib = self.env.LINKFLAGS_cxxshlib = [] # disable the '-dynamiclib' flag
163 self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN
164 use = self.use = self.to_list(getattr(self, 'use', []))
165 if not 'MACBUNDLE' in use:
166 use.append('MACBUNDLE')
168 app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources']
170 class macapp(Task.Task):
172 Creates mac applications
174 color = 'PINK'
175 def run(self):
176 self.outputs[0].parent.mkdir()
177 shutil.copy2(self.inputs[0].srcpath(), self.outputs[0].abspath())
179 class macplist(Task.Task):
181 Creates plist files
183 color = 'PINK'
184 ext_in = ['.bin']
185 def run(self):
186 if getattr(self, 'code', None):
187 txt = self.code
188 else:
189 txt = self.inputs[0].read()
190 context = getattr(self, 'context', {})
191 txt = txt.format(**context)
192 self.outputs[0].write(txt)