3 # Thomas Nagy 2008-2018 (ita)
9 import os
, shutil
, platform
10 from waflib
import Task
, Utils
11 from waflib
.TaskGen
import taskgen_method
, feature
, after_method
, before_method
14 <?xml version="1.0" encoding="UTF-8"?>
15 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
18 <key>CFBundlePackageType</key>
20 <key>CFBundleGetInfoString</key>
21 <string>Created by Waf</string>
22 <key>CFBundleSignature</key>
25 <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
26 <key>CFBundleExecutable</key>
27 <string>{app_name}</string>
36 def set_macosx_deployment_target(self
):
38 see WAF issue 285 and also and also http://trac.macports.org/ticket/17059
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])
47 def create_bundle_dirs(self
, name
, out
):
49 Creates bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp`
51 dir = out
.parent
.find_or_declare(name
)
53 macos
= dir.find_or_declare(['Contents', 'MacOS'])
57 def bundle_name_for_output(out
):
61 name
= name
[:k
] + '.app'
66 @feature('cprogram', 'cxxprogram')
67 @after_method('apply_link')
68 def create_task_macapp(self
):
70 To compile an executable into a Mac application (a .app), set its *mac_app* attribute::
73 bld.shlib(source='a.c', target='foo', mac_app=True)
75 To force *all* executables to be transformed into Mac applications::
79 bld.shlib(source='a.c', target='foo')
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
,
130 plist_ctx
= getattr(self
, 'plist_context', None)
132 plisttask
.context
.update(plist_ctx
)
134 if getattr(self
, 'mac_plist', False):
135 node
= self
.path
.find_resource(self
.mac_plist
)
137 plisttask
.inputs
.append(node
)
139 plisttask
.code
= self
.mac_plist
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::
153 bld.shlib(source='a.c', target='foo', mac_bundle = True)
155 To force *all* executables to be transformed into bundles::
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
176 self
.outputs
[0].parent
.mkdir()
177 shutil
.copy2(self
.inputs
[0].srcpath(), self
.outputs
[0].abspath())
179 class macplist(Task
.Task
):
186 if getattr(self
, 'code', None):
189 txt
= self
.inputs
[0].read()
190 context
= getattr(self
, 'context', {})
191 txt
= txt
.format(**context
)
192 self
.outputs
[0].write(txt
)