10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Copyright (C) 2009 Kevin Ollivier All rights reserved. 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Redistribution and use in source and binary forms, with or without 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# modification, are permitted provided that the following conditions 50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# are met: 60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 1. Redistributions of source code must retain the above copyright 70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# notice, this list of conditions and the following disclaimer. 80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 2. Redistributions in binary form must reproduce the above copyright 90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# notice, this list of conditions and the following disclaimer in the 100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# documentation and/or other materials provided with the distribution. 110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Helper functions for the WebKit build. 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockimport commands 270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport glob 280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport os 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockimport platform 30cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockimport re 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockimport shutil 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport sys 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport urllib 340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport urlparse 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef get_output(command): 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Windows-compatible function for getting output from a command. 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if sys.platform.startswith('win'): 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block f = os.popen(command) 42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return f.read().strip() 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block else: 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return commands.getoutput(command) 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef get_excludes(root, patterns): 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Get a list of exclude patterns going down several dirs. 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch TODO: Make this fully recursive. 500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch excludes = [] 520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for pattern in patterns: 540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch subdir_pattern = os.sep + '*' 550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for subdir in [subdir_pattern, subdir_pattern*2, subdir_pattern*3]: 560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch adir = root + subdir + os.sep + pattern 570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch files = glob.glob(adir) 580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for afile in files: 590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch excludes.append(os.path.basename(afile)) 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return excludes 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef get_dirs_for_features(root, features, dirs): 640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Find which directories to include in the list of build dirs based upon the 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch enabled port(s) and features. 670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch outdirs = dirs 690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for adir in dirs: 700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for feature in features: 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch relpath = os.path.join(adir, feature) 720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch featuredir = os.path.join(root, relpath) 730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if os.path.exists(featuredir) and not relpath in outdirs: 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch outdirs.append(relpath) 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return outdirs 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef download_if_newer(url, destdir): 790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Checks if the file on the server is newer than the one in the user's tree, 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch and if so, downloads it. 820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Returns the filename of the downloaded file if downloaded, or None if 840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch the existing file matches the one on the server. 850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch obj = urlparse.urlparse(url) 870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch filename = os.path.basename(obj.path) 880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch destfile = os.path.join(destdir, filename) 890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch urlobj = urllib.urlopen(url) 910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch size = long(urlobj.info().getheader('Content-Length')) 920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch def download_callback(downloaded, block_size, total_size): 940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch downloaded = block_size * downloaded 950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if downloaded > total_size: 960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch downloaded = total_size 970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch sys.stdout.write('%s %d of %d bytes downloaded\r' % (filename, downloaded, total_size)) 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch # NB: We don't check modified time as Python doesn't yet handle timezone conversion 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch # properly when converting strings to time objects. 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if not os.path.exists(destfile) or os.path.getsize(destfile) != size: 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch urllib.urlretrieve(url, destfile, download_callback) 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch print '' 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return destfile 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return None 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockdef update_wx_deps(conf, wk_root, msvc_version='msvc2008'): 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Download and update tools needed to build the wx port. 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch """ 112cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block import Logs 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Logs.info('Ensuring wxWebKit dependencies are up-to-date.') 1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch wklibs_dir = os.path.join(wk_root, 'WebKitLibraries') 116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch waf = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/waf', os.path.join(wk_root, 'Tools', 'wx')) 1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if waf: 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch # TODO: Make the build restart itself after an update. 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Logs.warn('Build system updated, please restart build.') 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch sys.exit(1) 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch # since this module is still experimental 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block wxpy_dir = os.path.join(wk_root, 'Source', 'WebKit', 'wx', 'bindings', 'python') 124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block swig_module = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/swig.py.txt', wxpy_dir) 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if swig_module: 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block shutil.copy(os.path.join(wxpy_dir, 'swig.py.txt'), os.path.join(wxpy_dir, 'swig.py')) 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if sys.platform.startswith('win'): 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Logs.info('downloading deps package') 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch archive = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/wxWebKitDeps-%s.zip' % msvc_version, wklibs_dir) 1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if archive and os.path.exists(archive): 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch os.system('unzip -o %s -d %s' % (archive, os.path.join(wklibs_dir, msvc_version))) 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch elif sys.platform.startswith('darwin'): 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block # export the right compiler for building the dependencies 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if platform.release().startswith('10'): # Snow Leopard 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block os.environ['CC'] = conf.env['CC'][0] 138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block os.environ['CXX'] = conf.env['CXX'][0] 139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch os.system('%s/Tools/wx/install-unix-extras' % wk_root) 1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef includeDirsForSources(sources): 1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch include_dirs = [] 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for group in sources: 1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for source in group: 1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch dirname = os.path.dirname(source) 1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if not dirname in include_dirs: 1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch include_dirs.append(dirname) 1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return include_dirs 1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef flattenSources(sources): 1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch flat_sources = [] 1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for group in sources: 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch flat_sources.extend(group) 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return flat_sources 157cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 158cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockdef git_branch_name(): 159cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block try: 160cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block branches = commands.getoutput("git branch --no-color") 161cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block match = re.search('^\* (.*)', branches, re.MULTILINE) 162cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if match: 163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return ".%s" % match.group(1) 164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block except: 165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block pass 166cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 167cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return "" 168cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 169cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockdef get_config(wk_root): 170cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block config_file = os.path.join(wk_root, 'WebKitBuild', 'Configuration') 171cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block config = 'Debug' 172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 173cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if os.path.exists(config_file): 174cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block config = open(config_file).read() 175cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return config 177cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockdef svn_revision(): 179643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if os.system("git-svn info") == 0: 180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block info = commands.getoutput("git-svn info ../..") 181cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block else: 182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block info = commands.getoutput("svn info") 183cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for line in info.split("\n"): 185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if line.startswith("Revision: "): 186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return line.replace("Revision: ", "").strip() 187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return "" 189