# Copyright (C) 2009 Kevin Ollivier All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Helper functions for the WebKit build.
import commands
import glob
import os
import platform
import re
import shutil
import sys
import urllib
import urlparse
def get_output(command):
"""
Windows-compatible function for getting output from a command.
"""
if sys.platform.startswith('win'):
f = os.popen(command)
return f.read().strip()
else:
return commands.getoutput(command)
def get_excludes(root, patterns):
"""
Get a list of exclude patterns going down several dirs.
TODO: Make this fully recursive.
"""
excludes = []
for pattern in patterns:
subdir_pattern = os.sep + '*'
for subdir in [subdir_pattern, subdir_pattern*2, subdir_pattern*3]:
adir = root + subdir + os.sep + pattern
files = glob.glob(adir)
for afile in files:
excludes.append(os.path.basename(afile))
return excludes
def get_dirs_for_features(root, features, dirs):
"""
Find which directories to include in the list of build dirs based upon the
enabled port(s) and features.
"""
outdirs = dirs
for adir in dirs:
for feature in features:
relpath = os.path.join(adir, feature)
featuredir = os.path.join(root, relpath)
if os.path.exists(featuredir) and not relpath in outdirs:
outdirs.append(relpath)
return outdirs
def download_if_newer(url, destdir):
"""
Checks if the file on the server is newer than the one in the user's tree,
and if so, downloads it.
Returns the filename of the downloaded file if downloaded, or None if
the existing file matches the one on the server.
"""
obj = urlparse.urlparse(url)
filename = os.path.basename(obj.path)
destfile = os.path.join(destdir, filename)
urlobj = urllib.urlopen(url)
size = long(urlobj.info().getheader('Content-Length'))
def download_callback(downloaded, block_size, total_size):
downloaded = block_size * downloaded
if downloaded > total_size:
downloaded = total_size
sys.stdout.write('%s %d of %d bytes downloaded\r' % (filename, downloaded, total_size))
# NB: We don't check modified time as Python doesn't yet handle timezone conversion
# properly when converting strings to time objects.
if not os.path.exists(destfile) or os.path.getsize(destfile) != size:
urllib.urlretrieve(url, destfile, download_callback)
print ''
return destfile
return None
def update_wx_deps(conf, wk_root, msvc_version='msvc2008'):
"""
Download and update tools needed to build the wx port.
"""
import Logs
Logs.info('Ensuring wxWebKit dependencies are up-to-date.')
wklibs_dir = os.path.join(wk_root, 'WebKitLibraries')
waf = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/waf', os.path.join(wk_root, 'Tools', 'wx'))
if waf:
# TODO: Make the build restart itself after an update.
Logs.warn('Build system updated, please restart build.')
sys.exit(1)
# since this module is still experimental
wxpy_dir = os.path.join(wk_root, 'Source', 'WebKit', 'wx', 'bindings', 'python')
swig_module = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/swig.py.txt', wxpy_dir)
if swig_module:
shutil.copy(os.path.join(wxpy_dir, 'swig.py.txt'), os.path.join(wxpy_dir, 'swig.py'))
if sys.platform.startswith('win'):
Logs.info('downloading deps package')
archive = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/wxWebKitDeps-%s.zip' % msvc_version, wklibs_dir)
if archive and os.path.exists(archive):
os.system('unzip -o %s -d %s' % (archive, os.path.join(wklibs_dir, msvc_version)))
elif sys.platform.startswith('darwin'):
# export the right compiler for building the dependencies
if platform.release().startswith('10'): # Snow Leopard
os.environ['CC'] = conf.env['CC'][0]
os.environ['CXX'] = conf.env['CXX'][0]
os.system('%s/Tools/wx/install-unix-extras' % wk_root)
def includeDirsForSources(sources):
include_dirs = []
for group in sources:
for source in group:
dirname = os.path.dirname(source)
if not dirname in include_dirs:
include_dirs.append(dirname)
return include_dirs
def flattenSources(sources):
flat_sources = []
for group in sources:
flat_sources.extend(group)
return flat_sources
def git_branch_name():
try:
branches = commands.getoutput("git branch --no-color")
match = re.search('^\* (.*)', branches, re.MULTILINE)
if match:
return ".%s" % match.group(1)
except:
pass
return ""
def get_config(wk_root):
config_file = os.path.join(wk_root, 'WebKitBuild', 'Configuration')
config = 'Debug'
if os.path.exists(config_file):
config = open(config_file).read()
return config
def svn_revision():
if os.system("git-svn info") == 0:
info = commands.getoutput("git-svn info ../..")
else:
info = commands.getoutput("svn info")
for line in info.split("\n"):
if line.startswith("Revision: "):
return line.replace("Revision: ", "").strip()
return ""