def create_appbundle(destdir, name, extension='.app', module=py2app.apptemplate, platform='MacOS', copy=mergecopy, mergetree=mergetree, condition=skipscm, plist={}): kw = module.plist_template.infoPlistDict( plist.get('CFBundleExecutable', name), plist) app = os.path.join(destdir, kw['CFBundleName'] + extension) contents = os.path.join(app, 'Contents') resources = os.path.join(contents, 'Resources') platdir = os.path.join(contents, platform) dirs = [contents, resources, platdir] plist = plistlib.Plist() plist.update(kw) plistPath = os.path.join(contents, 'Info.plist') if os.path.exists(plistPath): if plist != plistlib.Plist.fromFile(plistPath): for d in dirs: shutil.rmtree(d, ignore_errors=True) for d in dirs: makedirs(d) plist.write(plistPath) srcmain = module.setup.main() destmain = os.path.join(platdir, kw['CFBundleExecutable']) open(os.path.join(contents, 'PkgInfo'), 'w').write( kw['CFBundlePackageType'] + kw['CFBundleSignature'] ) copy(srcmain, destmain) make_exec(destmain) mergetree( resource_filename(module.__name__, 'lib'), resources, condition=condition, copyfn=copy, ) return app, plist
def create_appbundle(destdir, name, extension='.app', module=py2app.apptemplate, platform='MacOS', copy=mergecopy, mergetree=mergetree, condition=skipscm, plist={}, arch=None, redirect_stdout=False): kw = module.plist_template.infoPlistDict( plist.get('CFBundleExecutable', name), plist) app = os.path.join(destdir, kw['CFBundleName'] + extension) if os.path.exists(app): # Remove any existing build artifacts to ensure that # we're getting a clean build shutil.rmtree(app) contents = os.path.join(app, 'Contents') resources = os.path.join(contents, 'Resources') platdir = os.path.join(contents, platform) dirs = [contents, resources, platdir] plist = plistlib.Plist() plist.update(kw) plistPath = os.path.join(contents, 'Info.plist') if os.path.exists(plistPath): if plist != plistlib.Plist.fromFile(plistPath): for d in dirs: shutil.rmtree(d, ignore_errors=True) for d in dirs: makedirs(d) plist.write(plistPath) srcmain = module.setup.main(arch=arch, redirect_asl=redirect_stdout) if sys.version_info[0] == 2 \ and isinstance(kw['CFBundleExecutable'], unicode): destmain = os.path.join(platdir, kw['CFBundleExecutable'].encode('utf-8')) else: destmain = os.path.join(platdir, kw['CFBundleExecutable']) with open(os.path.join(contents, 'PkgInfo'), 'w') as fp: fp.write(kw['CFBundlePackageType'] + kw['CFBundleSignature']) print("Copy %r -> %r" % (srcmain, destmain)) copy(srcmain, destmain) make_exec(destmain) mergetree( resource_filename(module.__name__, 'lib'), resources, condition=condition, copyfn=copy, ) return app, plist
def run(self): # Nothing to do? if self.frameworks is None: return frameworks = self.frameworks if type(frameworks) is not dict and type(frameworks) is not list: frameworks = [dict(framework=frameworks)] frameworks = map(lambda i: type(i) is not dict and dict(framework=i) or i, frameworks) # Find xcodebuild self.xcodebuild = d_spawn.find_executable('xcodebuild') if not self.xcodebuild: raise DistutilsExecError('Could not find the xcodebuild command, ' \ 'have you installed Xcode?') # Build things for framework in frameworks: self.execute(self.__build, [framework], 'Building Framework: %s' % (framework['framework'])) # If we are doing an alias build, we have to get py2app to link in the # framework if self.alias: # (At least some) py2app(s) generate bad symlinks for frameworks in # alias builds. Therefore we'll do it ourselves. py2app = self.get_finalized_command('py2app') app_path = os.path.join( self.dist_dir, py2app.get_appname() + '.app') app_framework_path = os.path.join( app_path, 'Contents', 'Frameworks') from py2app.util import makedirs makedirs(app_framework_path) for framework in frameworks: # FIXME: Move somewhere else, ie into a Frameworks class, like the # Extensions class name = framework.get('name', self.name) if not name: framework_name = os.path.split(framework['framework']) if framework_name[1] == '': framework_name = os.path.split(framework_name[0])[1] else: framework_name = framework_name[1] else: framework_name = name framework_name = framework_name + '.framework' src = os.path.join(self.framework_dir, framework_name) dst = os.path.join(app_framework_path, framework_name) try: os.remove(dst) except: pass os.symlink( os.path.abspath(src), dst)
def create_appbundle(destdir, name, extension='.app', module=py2app.apptemplate, platform='MacOS', copy=mergecopy, mergetree=mergetree, condition=skipscm, plist={}, arch=None, redirect_stdout=False): kw = module.plist_template.infoPlistDict( plist.get('CFBundleExecutable', name), plist) app = os.path.join(destdir, kw['CFBundleName'] + extension) if os.path.exists(app): # Remove any existing build artifacts to ensure that # we're getting a clean build shutil.rmtree(app) contents = os.path.join(app, 'Contents') resources = os.path.join(contents, 'Resources') platdir = os.path.join(contents, platform) dirs = [contents, resources, platdir] plist = plistlib.Plist() plist.update(kw) plistPath = os.path.join(contents, 'Info.plist') if os.path.exists(plistPath): if plist != plistlib.Plist.fromFile(plistPath): for d in dirs: shutil.rmtree(d, ignore_errors=True) for d in dirs: makedirs(d) plist.write(plistPath) srcmain = module.setup.main(arch=arch, secondary=not redirect_stdout) if sys.version_info[0] == 2 and isinstance(kw['CFBundleExecutable'], unicode): destmain = os.path.join(platdir, kw['CFBundleExecutable'].encode('utf-8')) else: destmain = os.path.join(platdir, kw['CFBundleExecutable']) with open(os.path.join(contents, 'PkgInfo'), 'w') as fp: fp.write( kw['CFBundlePackageType'] + kw['CFBundleSignature'] ) copy(srcmain, destmain) make_exec(destmain) mergetree( resource_filename(module.__name__, 'lib'), resources, condition=condition, copyfn=copy, ) return app, plist
def build_alias_executable(self, target, script): # Build an alias executable for the target appdir, resdir, plist = self.create_bundle(target, script) # symlink python executable execdst = os.path.join(appdir, 'Contents', 'MacOS', 'python') self.symlink(sys.executable, execdst) # make PYTHONHOME pyhome = os.path.join(resdir, 'lib', 'python' + sys.version[:3]) realhome = os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3]) makedirs(pyhome) self.symlink('../../site.py', os.path.join(pyhome, 'site.py')) self.symlink( os.path.join(realhome, 'config'), os.path.join(pyhome, 'config')) # symlink data files # XXX: fixme: need to integrate automatic data conversion for src, dest in self.iter_data_files(): dest = os.path.join(resdir, dest) if src == dest: continue makedirs(os.path.dirname(dest)) self.symlink(os.path.abspath(src), dest) # symlink frameworks for src in self.iter_frameworks(): dest = os.path.join( appdir, 'Contents', 'Frameworks', os.path.basename(src)) if src == dest: continue makedirs(os.path.dirname(dest)) self.symlink(os.path.abspath(src), dest) self.compile_datamodels(resdir) self.compile_mappingmodels(resdir) from Carbon.File import FSRef aliasdata = FSRef(script).FSNewAliasMinimal().data bootfn = '__boot__' bootfile = file(os.path.join(resdir, bootfn + '.py'), 'w') for fn in target.prescripts: bootfile.write(self.get_bootstrap_data(fn)) bootfile.write('\n\n') bootfile.write('try:\n') bootfile.write(' _run((%r, %r))\n' % ( aliasdata, os.path.realpath(script), )) bootfile.write('except KeyboardInterrupt:\n') bootfile.write(' pass\n') bootfile.close() target.appdir = appdir return appdir
def build_alias_executable(self, target, script): # Build an alias executable for the target appdir, resdir, plist = self.create_bundle(target, script) # symlink python executable execdst = os.path.join(appdir, 'Contents', 'MacOS', 'python') self.symlink(sys.executable, execdst) # make PYTHONHOME pyhome = os.path.join(resdir, 'lib', 'python' + sys.version[:3]) realhome = os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3]) makedirs(pyhome) self.symlink('../../site.py', os.path.join(pyhome, 'site.py')) self.symlink(os.path.join(realhome, 'config'), os.path.join(pyhome, 'config')) # symlink data files # XXX: fixme: need to integrate automatic data conversion for src, dest in self.iter_data_files(): dest = os.path.join(resdir, dest) if src == dest: continue makedirs(os.path.dirname(dest)) self.symlink(os.path.abspath(src), dest) # symlink frameworks for src in self.iter_frameworks(): dest = os.path.join(appdir, 'Contents', 'Frameworks', os.path.basename(src)) if src == dest: continue makedirs(os.path.dirname(dest)) self.symlink(os.path.abspath(src), dest) self.compile_datamodels(resdir) self.compile_mappingmodels(resdir) from Carbon.File import FSRef aliasdata = FSRef(script).FSNewAliasMinimal().data bootfn = '__boot__' bootfile = file(os.path.join(resdir, bootfn + '.py'), 'w') for fn in target.prescripts: bootfile.write(self.get_bootstrap_data(fn)) bootfile.write('\n\n') bootfile.write('try:\n') bootfile.write(' _run((%r, %r))\n' % ( aliasdata, os.path.realpath(script), )) bootfile.write('except KeyboardInterrupt:\n') bootfile.write(' pass\n') bootfile.close() target.appdir = appdir return appdir
def create_appbundle( destdir, name, extension=".app", module=py2app.apptemplate, platform="MacOS", copy=mergecopy, mergetree=mergetree, condition=skipscm, plist=None, arch=None, use_old_sdk=False, redirect_stdout=False, ): if plist is None: plist = {} kw = module.plist_template.infoPlistDict( plist.get("CFBundleExecutable", name), plist) app = os.path.join(destdir, kw["CFBundleName"] + extension) if os.path.exists(app): # Remove any existing build artifacts to ensure that # we're getting a clean build shutil.rmtree(app) contents = os.path.join(app, "Contents") resources = os.path.join(contents, "Resources") platdir = os.path.join(contents, platform) dirs = [contents, resources, platdir] plist = {} plist.update(kw) plistPath = os.path.join(contents, "Info.plist") if os.path.exists(plistPath): with open(plistPath, "rb") as fp: if hasattr(plistlib, "load"): contents = plistlib.load(fp) else: # 2.7 contents = plistlib.readPlist(fp) if plist != contents: for d in dirs: shutil.rmtree(d, ignore_errors=True) for d in dirs: makedirs(d) with open(plistPath, "wb") as fp: if hasattr(plistlib, "dump"): plistlib.dump(plist, fp) else: plistlib.writePlist(plist, fp) srcmain = module.setup.main(arch=arch, redirect_asl=redirect_stdout, use_old_sdk=use_old_sdk) if sys.version_info[0] == 2 and isinstance( kw["CFBundleExecutable"], unicode # noqa: F821 ): destmain = os.path.join(platdir, kw["CFBundleExecutable"].encode("utf-8")) else: destmain = os.path.join(platdir, kw["CFBundleExecutable"]) with open(os.path.join(contents, "PkgInfo"), "w") as fp: fp.write(kw["CFBundlePackageType"] + kw["CFBundleSignature"]) print("Copy %r -> %r" % (srcmain, destmain)) copy(srcmain, destmain) make_exec(destmain) mergetree( resource_filename(module.__name__, "lib"), resources, condition=condition, copyfn=copy, ) return app, plist
def create_pluginbundle(destdir, name, extension='.plugin', module=py2app.bundletemplate, platform='MacOS', copy=mergecopy, mergetree=mergetree, condition=skipscm, plist={}, arch=None): kw = module.plist_template.infoPlistDict( plist.get('CFBundleExecutable', name), plist) plugin = os.path.join(destdir, kw['CFBundleName'] + extension) if os.path.exists(plugin): # Remove any existing build artifacts to ensure # we're getting a clean build shutil.rmtree(plugin) contents = os.path.join(plugin, 'Contents') resources = os.path.join(contents, 'Resources') platdir = os.path.join(contents, platform) dirs = [contents, resources, platdir] plist = {} plist.update(kw) plistPath = os.path.join(contents, 'Info.plist') if os.path.exists(plistPath): with open(plistPath, 'rb') as fp: if hasattr(plistlib, 'load'): contents = plistlib.load(fp) else: # 2.7 contents = plistlib.readPlist(fp) if plist != contents: for d in dirs: shutil.rmtree(d, ignore_errors=True) for d in dirs: makedirs(d) with open(plistPath, 'wb') as fp: if hasattr(plistlib, 'dump'): plistlib.dump(plist, fp) else: plistlib.writePlist(plist, fp) srcmain = module.setup.main(arch=arch) if sys.version_info[0] == 2 and \ isinstance(kw['CFBundleExecutable'], unicode): destmain = os.path.join(platdir, kw['CFBundleExecutable'].encode('utf-8')) else: destmain = os.path.join(platdir, kw['CFBundleExecutable']) with open(os.path.join(contents, 'PkgInfo'), 'w') as fp: fp.write(kw['CFBundlePackageType'] + kw['CFBundleSignature']) copy(srcmain, destmain) make_exec(destmain) mergetree( resource_filename(module.__name__, 'lib'), resources, condition=condition, copyfn=copy, ) return plugin, plist