|
1 # Copyright (C) 2009 Kevin Ollivier All rights reserved. |
|
2 # |
|
3 # Redistribution and use in source and binary forms, with or without |
|
4 # modification, are permitted provided that the following conditions |
|
5 # are met: |
|
6 # 1. Redistributions of source code must retain the above copyright |
|
7 # notice, this list of conditions and the following disclaimer. |
|
8 # 2. Redistributions in binary form must reproduce the above copyright |
|
9 # notice, this list of conditions and the following disclaimer in the |
|
10 # documentation and/or other materials provided with the distribution. |
|
11 # |
|
12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
|
13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
|
16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
21 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
23 # |
|
24 # Helper functions for the WebKit build. |
|
25 |
|
26 import commands |
|
27 import glob |
|
28 import os |
|
29 import platform |
|
30 import re |
|
31 import shutil |
|
32 import sys |
|
33 import urllib |
|
34 import urlparse |
|
35 |
|
36 def get_output(command): |
|
37 """ |
|
38 Windows-compatible function for getting output from a command. |
|
39 """ |
|
40 if sys.platform.startswith('win'): |
|
41 f = os.popen(command) |
|
42 return f.read().strip() |
|
43 else: |
|
44 return commands.getoutput(command) |
|
45 |
|
46 def get_excludes(root, patterns): |
|
47 """ |
|
48 Get a list of exclude patterns going down several dirs. |
|
49 TODO: Make this fully recursive. |
|
50 """ |
|
51 excludes = [] |
|
52 |
|
53 for pattern in patterns: |
|
54 subdir_pattern = os.sep + '*' |
|
55 for subdir in [subdir_pattern, subdir_pattern*2, subdir_pattern*3]: |
|
56 adir = root + subdir + os.sep + pattern |
|
57 files = glob.glob(adir) |
|
58 for afile in files: |
|
59 excludes.append(os.path.basename(afile)) |
|
60 |
|
61 return excludes |
|
62 |
|
63 def get_dirs_for_features(root, features, dirs): |
|
64 """ |
|
65 Find which directories to include in the list of build dirs based upon the |
|
66 enabled port(s) and features. |
|
67 """ |
|
68 outdirs = dirs |
|
69 for adir in dirs: |
|
70 for feature in features: |
|
71 relpath = os.path.join(adir, feature) |
|
72 featuredir = os.path.join(root, relpath) |
|
73 if os.path.exists(featuredir) and not relpath in outdirs: |
|
74 outdirs.append(relpath) |
|
75 |
|
76 return outdirs |
|
77 |
|
78 def download_if_newer(url, destdir): |
|
79 """ |
|
80 Checks if the file on the server is newer than the one in the user's tree, |
|
81 and if so, downloads it. |
|
82 |
|
83 Returns the filename of the downloaded file if downloaded, or None if |
|
84 the existing file matches the one on the server. |
|
85 """ |
|
86 obj = urlparse.urlparse(url) |
|
87 filename = os.path.basename(obj.path) |
|
88 destfile = os.path.join(destdir, filename) |
|
89 |
|
90 urlobj = urllib.urlopen(url) |
|
91 size = long(urlobj.info().getheader('Content-Length')) |
|
92 |
|
93 def download_callback(downloaded, block_size, total_size): |
|
94 downloaded = block_size * downloaded |
|
95 if downloaded > total_size: |
|
96 downloaded = total_size |
|
97 sys.stdout.write('%s %d of %d bytes downloaded\r' % (filename, downloaded, total_size)) |
|
98 |
|
99 # NB: We don't check modified time as Python doesn't yet handle timezone conversion |
|
100 # properly when converting strings to time objects. |
|
101 if not os.path.exists(destfile) or os.path.getsize(destfile) != size: |
|
102 urllib.urlretrieve(url, destfile, download_callback) |
|
103 print '' |
|
104 return destfile |
|
105 |
|
106 return None |
|
107 |
|
108 def update_wx_deps(conf, wk_root, msvc_version='msvc2008'): |
|
109 """ |
|
110 Download and update tools needed to build the wx port. |
|
111 """ |
|
112 import Logs |
|
113 Logs.info('Ensuring wxWebKit dependencies are up-to-date.') |
|
114 |
|
115 wklibs_dir = os.path.join(wk_root, 'WebKitLibraries') |
|
116 waf = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/waf', os.path.join(wk_root, 'WebKitTools', 'wx')) |
|
117 if waf: |
|
118 # TODO: Make the build restart itself after an update. |
|
119 Logs.warn('Build system updated, please restart build.') |
|
120 sys.exit(1) |
|
121 |
|
122 # since this module is still experimental |
|
123 wxpy_dir = os.path.join(wk_root, 'WebKit', 'wx', 'bindings', 'python') |
|
124 swig_module = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/swig.py.txt', wxpy_dir) |
|
125 if swig_module: |
|
126 shutil.copy(os.path.join(wxpy_dir, 'swig.py.txt'), os.path.join(wxpy_dir, 'swig.py')) |
|
127 |
|
128 if sys.platform.startswith('win'): |
|
129 Logs.info('downloading deps package') |
|
130 archive = download_if_newer('http://wxwebkit.wxcommunity.com/downloads/deps/wxWebKitDeps-%s.zip' % msvc_version, wklibs_dir) |
|
131 if archive and os.path.exists(archive): |
|
132 os.system('unzip -o %s -d %s' % (archive, os.path.join(wklibs_dir, msvc_version))) |
|
133 |
|
134 elif sys.platform.startswith('darwin'): |
|
135 # export the right compiler for building the dependencies |
|
136 if platform.release().startswith('10'): # Snow Leopard |
|
137 os.environ['CC'] = conf.env['CC'][0] |
|
138 os.environ['CXX'] = conf.env['CXX'][0] |
|
139 os.system('%s/WebKitTools/wx/install-unix-extras' % wk_root) |
|
140 |
|
141 def includeDirsForSources(sources): |
|
142 include_dirs = [] |
|
143 for group in sources: |
|
144 for source in group: |
|
145 dirname = os.path.dirname(source) |
|
146 if not dirname in include_dirs: |
|
147 include_dirs.append(dirname) |
|
148 |
|
149 return include_dirs |
|
150 |
|
151 def flattenSources(sources): |
|
152 flat_sources = [] |
|
153 for group in sources: |
|
154 flat_sources.extend(group) |
|
155 |
|
156 return flat_sources |
|
157 |
|
158 def git_branch_name(): |
|
159 try: |
|
160 branches = commands.getoutput("git branch --no-color") |
|
161 match = re.search('^\* (.*)', branches, re.MULTILINE) |
|
162 if match: |
|
163 return ".%s" % match.group(1) |
|
164 except: |
|
165 pass |
|
166 |
|
167 return "" |
|
168 |
|
169 def get_config(wk_root): |
|
170 config_file = os.path.join(wk_root, 'WebKitBuild', 'Configuration') |
|
171 config = 'Debug' |
|
172 |
|
173 if os.path.exists(config_file): |
|
174 config = open(config_file).read() |
|
175 |
|
176 return config |
|
177 |
|
178 def svn_revision(): |
|
179 if os.system("git-svn info") == 0: |
|
180 info = commands.getoutput("git-svn info ../..") |
|
181 else: |
|
182 info = commands.getoutput("svn info") |
|
183 |
|
184 for line in info.split("\n"): |
|
185 if line.startswith("Revision: "): |
|
186 return line.replace("Revision: ", "").strip() |
|
187 |
|
188 return "" |