[banshee] [build] bundling now supported in build profile



commit 6fa9b64de651c6fb225a4b429585864d6afd4d7c
Author: Aaron Bockover <abockover novell com>
Date:   Mon Jan 11 13:29:28 2010 -0500

    [build] bundling now supported in build profile
    
    The --bundle option can be passed to a build profile to create
    a bundle from the installed build root. Currently most of the
    Darwin/OS X bundle is implemented, with a few things left to do.
    
    Define a bundle profile for Banshee in profile.darwin.py, and
    added .app skeleton for Banshee.

 build/bundle/bockbuild/darwinprofile.py            |   70 ++++++++++++++++++++
 build/bundle/bockbuild/package.py                  |    2 +-
 build/bundle/bockbuild/profile.py                  |   42 +++++++++---
 build/bundle/mkbundle.osx                          |   53 ---------------
 build/bundle/profile.darwin.py                     |   52 +++++++++++++++
 build/bundle/skeleton.darwin/Contents/Info.plist   |   30 ++++++++
 .../Contents/Resources/Banshee.icns                |  Bin 0 -> 165218 bytes
 7 files changed, 185 insertions(+), 64 deletions(-)
---
diff --git a/build/bundle/bockbuild/darwinprofile.py b/build/bundle/bockbuild/darwinprofile.py
index d6ceb7b..1750989 100644
--- a/build/bundle/bockbuild/darwinprofile.py
+++ b/build/bundle/bockbuild/darwinprofile.py
@@ -1,4 +1,7 @@
 import os
+import shutil
+from plistlib import Plist
+from util import *
 from unixprofile import UnixProfile
 
 class DarwinProfile (UnixProfile):
@@ -23,3 +26,70 @@ class DarwinProfile (UnixProfile):
 
 		self.env.set ('CC',  'gcc-4.2')
 		self.env.set ('CXX', 'g++-4.2')
+
+	def bundle (self):
+		self.make_app_bundle ()
+
+	def make_app_bundle (self):
+		plist_path = os.path.join (self.bundle_skeleton_dir, 'Contents', 'Info.plist')
+		app_name = 'Unknown.app'
+		plist = None
+		if os.path.exists (plist_path):
+			plist = Plist.fromFile (plist_path)
+			app_name = plist['CFBundleExecutable']
+		else:
+			print 'Warning: no Contents/Info.plist in .app skeleton'
+
+		self.bundle_app_dir = os.path.join (self.bundle_output_dir, app_name + '.app')
+		self.bundle_contents_dir = os.path.join (self.bundle_app_dir, 'Contents')
+		self.bundle_res_dir = os.path.join (self.bundle_contents_dir, 'Resources')
+		self.bundle_macos_dir = os.path.join (self.bundle_contents_dir, 'MacOS')
+
+		# Create the .app tree, copying the skeleton
+		shutil.rmtree (self.bundle_app_dir, ignore_errors = True)
+		shutil.copytree (self.bundle_skeleton_dir, self.bundle_app_dir)
+		if not os.path.exists (self.bundle_contents_dir): os.makedirs (self.bundle_contents_dir)
+		if not os.path.exists (self.bundle_res_dir): os.makedirs (self.bundle_res_dir)
+		if not os.path.exists (self.bundle_macos_dir): os.makedirs (self.bundle_macos_dir)
+
+		# Generate the PkgInfo
+		pkginfo_path = os.path.join (self.bundle_contents_dir, 'PkgInfo')
+		if not os.path.exists (pkginfo_path) and not plist == None:
+			fp = open (pkginfo_path, 'w')
+			fp.write (plist['CFBundlePackageType'])
+			fp.write (plist['CFBundleSignature'])
+			fp.close ()
+
+		# Run solitary against the installation to collect files
+		files = ''
+		for file in self.bundle_from_build:
+			files = files + ' "%s"' % os.path.join (self.prefix, file)
+
+		run_shell ('mono --debug solitary/Solitary.exe '
+			'--mono-prefix="%s" --root="%s" --out="%s" %s' % \
+			(install_prefix, install_prefix, self.bundle_res_dir, files))
+
+	def configure_pango (self):
+		pango_querymodules = os.path.join (self.prefix, 'bin', 'pango-querymodules')
+		if not os.path.isfile (pango_querymodules):
+			print 'Could not find pango-querymodules in the build root'
+			return
+
+		pango_dir = os.path.join (self.bundle_res_dir, 'etc', 'pango')
+		if not os.path.exists (pango_dir):
+			os.makedirs (pango_dir)
+
+		fp = open (os.path.join (pango_dir, 'pango.modules'), 'w')
+		for line in backtick (pango_querymodules):
+			line = line.strip ()
+			if line.startswith ('#'):
+				continue
+			elif line.startswith (self.prefix):
+				line = line[len (self.prefix) + 1:]
+			fp.write (line + '\n')
+		fp.close ()
+
+		fp = open (os.path.join (pango_dir, 'pangorc'), 'w')
+		fp.write ('[Pango]\n')
+		fp.write ('ModulesPath=./pango.modules\n')
+		fp.close ()
diff --git a/build/bundle/bockbuild/package.py b/build/bundle/bockbuild/package.py
index 7ee744b..ab2fcd6 100644
--- a/build/bundle/bockbuild/package.py
+++ b/build/bundle/bockbuild/package.py
@@ -60,7 +60,7 @@ class Package:
 		profile = Package.profile
 
 		namever = '%s-%s' % (self.name, self.version)
-		package_dir = os.path.dirname (os.path.realpath (__file__))
+		package_dir = os.path.dirname (os.path.realpath (self._path))
 		package_dest_dir = os.path.join (profile.build_root, namever)
 		package_build_dir = os.path.join (package_dest_dir, '_build')
 		build_success_file = os.path.join (profile.build_root,
diff --git a/build/bundle/bockbuild/profile.py b/build/bundle/bockbuild/profile.py
index e9181bc..9957472 100644
--- a/build/bundle/bockbuild/profile.py
+++ b/build/bundle/bockbuild/profile.py
@@ -15,6 +15,9 @@ class Profile:
 		self.cpu_count = get_cpu_count ()
 		self.host = get_host ()
 
+	def bundle (self, output_dir):
+		sys.exit ('Bundle support not implemented for this profile')
+
 	def build (self):
 		default_run_phases = ['prep', 'build', 'install']
 
@@ -22,6 +25,15 @@ class Profile:
 		parser.add_option ('-b', '--build',
 			action = 'store_true', dest = 'do_build', default = False,
 			help = 'build the profile')
+		parser.add_option ('-z', '--bundle',
+			action = 'store_true', dest = 'do_bundle', default = False,
+			help = 'create a distributable bundle from a build')
+		parser.add_option ('-o', '--output-dir',
+			default = None, action = 'store', dest = 'output_dir',
+			help = 'output directory for housing the bundle (--bundle|-z)')
+		parser.add_option ('-k', '--skeleton-dir',
+			default = None, action = 'store',  dest = 'skeleton_dir',
+			help = 'skeleton directory containing misc files to copy into bundle (--bundle|-z)')
 		parser.add_option ('-v', '--verbose',
 			action = 'store_true', dest = 'verbose', default = False,
 			help = 'show all build output (e.g. configure, make)')
@@ -48,7 +60,7 @@ class Profile:
 			self.env.dump ()
 			sys.exit (0)
 
-		if not options.do_build:
+		if not options.do_build and not options.do_bundle:
 			parser.print_help ()
 			sys.exit (1)
 
@@ -77,12 +89,22 @@ class Profile:
 
 		Package.profile = self
 
-		pwd = os.getcwd ()
-		for path in self.packages:
-			os.chdir (pwd)
-			path = os.path.join (os.path.dirname (sys.argv[0]), path)
-			exec compile (open (path).read (), path, 'exec')
-			if Package.last_instance == None:
-				sys.exit ('%s does not provide a valid package.' % path)
-			Package.last_instance.start_build ()
-			Package.last_instance = None
+		if options.do_build:
+			pwd = os.getcwd ()
+			for path in self.packages:
+				os.chdir (pwd)
+				path = os.path.join (os.path.dirname (sys.argv[0]), path)
+				exec compile (open (path).read (), path, 'exec')
+				if Package.last_instance == None:
+					sys.exit ('%s does not provide a valid package.' % path)
+				Package.last_instance._path = path
+				Package.last_instance.start_build ()
+				Package.last_instance = None
+
+		if options.do_bundle:
+			if not options.output_dir == None:
+				self.bundle_output_dir = os.path.join (os.getcwd (), 'bundle')
+			if not options.skeleton_dir == None:
+				self.bundle_skeleton_dir = os.path.join (os.getcwd (), 'skeleton')
+			self.bundle ()
+			return
diff --git a/build/bundle/profile.darwin.py b/build/bundle/profile.darwin.py
index a5cc17c..e5ccc5e 100755
--- a/build/bundle/profile.darwin.py
+++ b/build/bundle/profile.darwin.py
@@ -1,5 +1,8 @@
 #!/usr/bin/python -B
 
+import os
+import sys
+
 from bockbuild.darwinprofile import DarwinProfile
 from packages import BansheePackages
 
@@ -8,4 +11,53 @@ class BansheeDarwinProfile (DarwinProfile, BansheePackages):
 		DarwinProfile.__init__ (self)
 		BansheePackages.__init__ (self)
 
+		self_dir = os.path.realpath (os.path.dirname (sys.argv[0]))
+		self.bundle_skeleton_dir = os.path.join (self_dir, 'skeleton.darwin')
+		self.bundle_output_dir = os.path.join (self_dir, 'bundle.darwin')
+
+		self.bundle_from_build = [
+			'bin/mono',
+			'bin/banshee-1',
+			'bin/pango-querymodules',
+			'bin/gtk-demo',
+			'lib/banshee-1',
+			'lib/pango',
+			'lib/gstreamer-0.10',
+			'share/banshee-1',
+			'etc/mono/config',
+			'etc/mono/1.0/machine.config',
+			'etc/mono/2.0/machine.config',
+			'etc/mono/2.0/settings.map'
+		]
+
+		self.bundle_from_build.extend ([
+			'share/icons/%s/%sx%s' % (theme, size, size)
+				for size in [16, 22, 32, 48]
+				for theme in ['hicolor', 'Tango']
+		])
+
+	def bundle (self):
+		banshee_path = os.path.join (self.prefix, 'lib', 'banshee-1')
+		os.environ['MONO_PATH'] = ':'.join ([
+			banshee_path,
+			os.path.join (banshee_path, 'Extensions'),
+			os.path.join (banshee_path, 'Backends')
+		])
+
+		DarwinProfile.bundle (self)
+		self.configure_pango ()
+
+		import shutil
+		import glob
+
+		bin_path = os.path.join (self.bundle_macos_dir, 'Banshee')
+		shutil.move (os.path.join (self.bundle_res_dir, 'bin', 'banshee-1'), bin_path)
+		os.chmod (bin_path, 0755)
+
+		for nuke in [ 'NotificationArea', 'AudioCd', 'Dap',
+			'Dap.MassStorage', 'MiniMode' ]:
+			for path in glob.glob (os.path.join (self.bundle_res_dir,
+				'lib', 'banshee-1', 'Extensions', 'Banshee.%s*' % nuke)):
+				os.unlink (path)
+
 BansheeDarwinProfile ().build ()
diff --git a/build/bundle/skeleton.darwin/Contents/Info.plist b/build/bundle/skeleton.darwin/Contents/Info.plist
new file mode 100644
index 0000000..e26923e
--- /dev/null
+++ b/build/bundle/skeleton.darwin/Contents/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
+<plist version="1.0">
+<dict>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>English</string>
+    <key>CFBundleExecutable</key>
+    <string>Banshee</string>
+    <key>CFBundleGetInfoString</key>
+    <string>1.5.3, Copyright 2005-2010 Novell Inc., and others</string>
+    <key>CFBundleIconFile</key>
+    <string>Banshee.icns</string>
+    <key>CFBundleIdentifier</key>
+    <string>fm.banshee.Banshee</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+    <key>CFBundleShortVersionString</key>
+    <string>0.3</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>CFBundleVersion</key>
+    <string>1.5.3</string>
+    <key>NSHumanReadableCopyright</key>
+    <string>Copyright 2005-2010 Novell Inc., and others.</string>
+    <key>LSMinimumSystemVersion</key>
+    <string>10.5</string>
+</dict>
+</plist>
diff --git a/build/bundle/skeleton.darwin/Contents/Resources/Banshee.icns b/build/bundle/skeleton.darwin/Contents/Resources/Banshee.icns
new file mode 100644
index 0000000..92d1c7d
Binary files /dev/null and b/build/bundle/skeleton.darwin/Contents/Resources/Banshee.icns differ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]