From 4f4bce5301ffd8c12aed1b108affa1a75feefb67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 4 Jan 2012 00:31:27 +0100 Subject: Include waf as an extracted source directory, rather than as a one-in-a-file script. --- buildtools/wafadmin/Tools/osx.py | 188 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 buildtools/wafadmin/Tools/osx.py (limited to 'buildtools/wafadmin/Tools/osx.py') diff --git a/buildtools/wafadmin/Tools/osx.py b/buildtools/wafadmin/Tools/osx.py new file mode 100644 index 0000000000..561eca487d --- /dev/null +++ b/buildtools/wafadmin/Tools/osx.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy 2008 + +"""MacOSX related tools + +To compile an executable into a Mac application bundle (a .app), set its 'mac_app' attribute + obj.mac_app = True + +To make a bundled shared library (a .bundle), set the 'mac_bundle' attribute: + obj.mac_bundle = True +""" + +import os, shutil, sys, platform +import TaskGen, Task, Build, Options, Utils +from TaskGen import taskgen, feature, after, before +from Logs import error, debug + +# plist template +app_info = ''' + + + + + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Waf + CFBundleSignature + ???? + NOTE + THIS IS A GENERATED FILE, DO NOT MODIFY + CFBundleExecutable + %s + + +''' + +# see WAF issue 285 +# and also http://trac.macports.org/ticket/17059 +@feature('cc', 'cxx') +@before('apply_lib_vars') +def set_macosx_deployment_target(self): + if self.env['MACOSX_DEPLOYMENT_TARGET']: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env['MACOSX_DEPLOYMENT_TARGET'] + elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ: + if sys.platform == 'darwin': + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2]) + +@feature('cc', 'cxx') +@after('apply_lib_vars') +def apply_framework(self): + for x in self.to_list(self.env['FRAMEWORKPATH']): + frameworkpath_st = '-F%s' + self.env.append_unique('CXXFLAGS', frameworkpath_st % x) + self.env.append_unique('CCFLAGS', frameworkpath_st % x) + self.env.append_unique('LINKFLAGS', frameworkpath_st % x) + + for x in self.to_list(self.env['FRAMEWORK']): + self.env.append_value('LINKFLAGS', ['-framework', x]) + +@taskgen +def create_bundle_dirs(self, name, out): + bld = self.bld + dir = out.parent.get_dir(name) + + if not dir: + dir = out.__class__(name, out.parent, 1) + bld.rescan(dir) + contents = out.__class__('Contents', dir, 1) + bld.rescan(contents) + macos = out.__class__('MacOS', contents, 1) + bld.rescan(macos) + return dir + +def bundle_name_for_output(out): + name = out.name + k = name.rfind('.') + if k >= 0: + name = name[:k] + '.app' + else: + name = name + '.app' + return name + +@taskgen +@after('apply_link') +@feature('cprogram') +def create_task_macapp(self): + """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications + or use obj.mac_app = True to build specific targets as Mac apps""" + if self.env['MACAPP'] or getattr(self, 'mac_app', False): + apptask = self.create_task('macapp') + apptask.set_inputs(self.link_task.outputs) + + out = self.link_task.outputs[0] + + name = bundle_name_for_output(out) + dir = self.create_bundle_dirs(name, out) + + n1 = dir.find_or_declare(['Contents', 'MacOS', out.name]) + + apptask.set_outputs([n1]) + apptask.chmod = 0755 + apptask.install_path = os.path.join(self.install_path, name, 'Contents', 'MacOS') + self.apptask = apptask + +@after('apply_link') +@feature('cprogram') +def create_task_macplist(self): + """Use env['MACAPP'] to force *all* executables to be transformed into Mac applications + or use obj.mac_app = True to build specific targets as Mac apps""" + if self.env['MACAPP'] or getattr(self, 'mac_app', False): + # check if the user specified a plist before using our template + if not getattr(self, 'mac_plist', False): + self.mac_plist = app_info + + plisttask = self.create_task('macplist') + plisttask.set_inputs(self.link_task.outputs) + + out = self.link_task.outputs[0] + self.mac_plist = self.mac_plist % (out.name) + + name = bundle_name_for_output(out) + dir = self.create_bundle_dirs(name, out) + + n1 = dir.find_or_declare(['Contents', 'Info.plist']) + + plisttask.set_outputs([n1]) + plisttask.mac_plist = self.mac_plist + plisttask.install_path = os.path.join(self.install_path, name, 'Contents') + self.plisttask = plisttask + +@after('apply_link') +@feature('cshlib') +def apply_link_osx(self): + name = self.link_task.outputs[0].name + if not self.install_path: + return + if getattr(self, 'vnum', None): + name = name.replace('.dylib', '.%s.dylib' % self.vnum) + + path = os.path.join(Utils.subst_vars(self.install_path, self.env), name) + if '-dynamiclib' in self.env['LINKFLAGS']: + self.env.append_value('LINKFLAGS', '-install_name') + self.env.append_value('LINKFLAGS', path) + +@before('apply_link', 'apply_lib_vars') +@feature('cc', 'cxx') +def apply_bundle(self): + """use env['MACBUNDLE'] to force all shlibs into mac bundles + or use obj.mac_bundle = True for specific targets only""" + if not ('cshlib' in self.features or 'shlib' in self.features): return + if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False): + self.env['shlib_PATTERN'] = self.env['macbundle_PATTERN'] + uselib = self.uselib = self.to_list(self.uselib) + if not 'MACBUNDLE' in uselib: uselib.append('MACBUNDLE') + +@after('apply_link') +@feature('cshlib') +def apply_bundle_remove_dynamiclib(self): + if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False): + if not getattr(self, 'vnum', None): + try: + self.env['LINKFLAGS'].remove('-dynamiclib') + self.env['LINKFLAGS'].remove('-single_module') + except ValueError: + pass + +# TODO REMOVE IN 1.6 (global variable) +app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources'] + +def app_build(task): + env = task.env + shutil.copy2(task.inputs[0].srcpath(env), task.outputs[0].abspath(env)) + + return 0 + +def plist_build(task): + env = task.env + f = open(task.outputs[0].abspath(env), "w") + f.write(task.mac_plist) + f.close() + + return 0 + +Task.task_type_from_func('macapp', vars=[], func=app_build, after="cxx_link cc_link static_link") +Task.task_type_from_func('macplist', vars=[], func=plist_build, after="cxx_link cc_link static_link") + -- cgit