1 # Copyright (C) 2009 Kevin Ollivier All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
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.
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.
24 # Common elements of the waf build system shared by all projects.
35 from build_utils import *
36 from waf_extensions import *
38 # to be moved to wx when it supports more configs
39 from wxpresets import *
41 wk_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..'))
43 if sys.platform.startswith('win'):
44 if not 'WXWIN' in os.environ:
45 print "Please set WXWIN to the directory containing wxWidgets."
48 wx_root = os.environ['WXWIN']
50 wx_root = commands.getoutput('wx-config --prefix')
52 wtf_dir = os.path.join(wk_root, 'Source', 'WTF')
53 jscore_dir = os.path.join(wk_root, 'Source', 'JavaScriptCore')
54 webcore_dir = os.path.join(wk_root, 'Source', 'WebCore')
55 wklibs_dir = os.path.join(wk_root, 'WebKitLibraries')
62 common_frameworks = []
86 'wx': ['CURL', 'WXGC'],
108 '../WTF/wtf/unicode',
109 '../WTF/wtf/unicode/icu',
112 webcore_dirs_common = [
113 'Source/WebCore/Modules/websockets',
114 'Source/WebCore/accessibility',
115 'Source/WebCore/bindings',
116 'Source/WebCore/bindings/cpp',
117 'Source/WebCore/bindings/generic',
118 'Source/WebCore/bindings/js',
119 'Source/WebCore/bridge',
120 'Source/WebCore/bridge/c',
121 'Source/WebCore/bridge/jsc',
122 'Source/WebCore/css',
123 'Source/WebCore/DerivedSources',
124 'Source/WebCore/dom',
125 'Source/WebCore/dom/default',
126 'Source/WebCore/editing',
127 'Source/WebCore/fileapi',
128 'Source/WebCore/history',
129 'Source/WebCore/html',
130 'Source/WebCore/html/canvas',
131 'Source/WebCore/html/parser',
132 'Source/WebCore/html/shadow',
133 'Source/WebCore/inspector',
134 'Source/WebCore/loader',
135 'Source/WebCore/loader/appcache',
136 'Source/WebCore/loader/archive',
137 'Source/WebCore/loader/cache',
138 'Source/WebCore/loader/icon',
139 'Source/WebCore/Modules/filesystem',
140 'Source/WebCore/Modules/geolocation',
141 'Source/WebCore/Modules/indexeddb',
142 'Source/WebCore/Modules/webdatabase',
143 'Source/WebCore/notifications',
144 'Source/WebCore/page',
145 'Source/WebCore/page/animation',
146 'Source/WebCore/page/scrolling',
147 'Source/WebCore/platform',
148 'Source/WebCore/platform/animation',
149 'Source/WebCore/platform/graphics',
150 'Source/WebCore/platform/graphics/filters',
151 'Source/WebCore/platform/graphics/filters/arm',
152 'Source/WebCore/platform/graphics/transforms',
153 'Source/WebCore/platform/image-decoders',
154 'Source/WebCore/platform/image-decoders/bmp',
155 'Source/WebCore/platform/image-decoders/gif',
156 'Source/WebCore/platform/image-decoders/ico',
157 'Source/WebCore/platform/image-decoders/jpeg',
158 'Source/WebCore/platform/image-decoders/png',
159 'Source/WebCore/platform/image-decoders/webp',
160 'Source/WebCore/platform/mock',
161 'Source/WebCore/platform/network',
162 'Source/WebCore/platform/posix',
163 'Source/WebCore/platform/sql',
164 'Source/WebCore/platform/text',
165 'Source/WebCore/platform/text/transcoder',
166 'Source/WebCore/plugins',
167 'Source/WebCore/rendering',
168 'Source/WebCore/rendering/style',
169 'Source/WebCore/rendering/svg',
170 'Source/WebCore/storage',
171 'Source/WebCore/svg',
172 'Source/WebCore/svg/animation',
173 'Source/WebCore/svg/graphics',
174 'Source/WebCore/svg/graphics/filters',
175 'Source/WebCore/svg/properties',
176 'Source/WebCore/testing',
177 'Source/WebCore/testing/js',
178 'Source/WebCore/workers',
179 'Source/WebCore/xml',
180 'Source/WebCore/xml/parser',
183 config = get_config(wk_root)
184 arch = get_arch(wk_root)
187 output_dir = os.path.join(get_base_product_dir(wk_root), config_dir)
189 building_on_win32 = sys.platform.startswith('win')
192 if building_on_win32:
195 build_port = default_port
197 def get_port_excludes(thisport):
199 This function creates a list of file patterns to exclude
200 based on what port you are using and what USES it has defined.
202 exclude_patterns = []
205 if not port == thisport:
206 exclude = "*%s.cpp" % port
207 if port == 'Chromium':
208 exclude = "*Chromium*.cpp"
209 exclude_patterns.append(exclude)
213 if thisport not in port_uses or not use in port_uses[thisport]:
214 exclude_patterns.append("*%s.cpp" % use)
216 return exclude_patterns
219 waf_configname = config.upper().strip()
220 if building_on_win32:
221 isReleaseCRT = (config == 'Release')
222 if build_port == 'wx':
223 if Options.options.wxpython:
227 waf_configname = waf_configname + ' CRT_MULTITHREADED_DLL'
229 waf_configname = waf_configname + ' CRT_MULTITHREADED_DLL_DBG'
231 return waf_configname
233 create_hash_table = wk_root + "/Source/JavaScriptCore/create_hash_table"
234 if building_on_win32:
235 create_hash_table = get_output('cygpath --unix "%s"' % create_hash_table)
236 os.environ['CREATE_HASH_TABLE'] = create_hash_table
240 msvc_version = 'msvc2008'
242 msvclibs_dir = os.path.join(wklibs_dir, msvc_version, 'win')
245 def get_path_to_wxconfig():
246 if 'WX_CONFIG' in os.environ:
247 return os.environ['WX_CONFIG']
252 def common_set_options(opt):
254 Initialize common options provided to the user.
256 opt.tool_options('compiler_cxx')
257 opt.tool_options('compiler_cc')
258 opt.tool_options('python')
260 opt.add_option('--port', action='store', default=default_port, help='Which WebKit port to build.')
261 opt.add_option('--wxpython', action='store_true', default=False, help='Create the wxPython bindings.')
262 opt.add_option('--wx-compiler-prefix', action='store', default='vc',
263 help='Specify a different compiler prefix (do this if you used COMPILER_PREFIX when building wx itself)')
264 opt.add_option('--macosx-version', action='store', default='', help="Version of OS X to build for.")
265 opt.add_option('--msvc-version', action='store', default='', help="MSVC version to use to build. Use 8 for 2005, 9 for 2008")
266 opt.add_option('--mac_universal_binary', action='store_true', default=False, help='Build Mac as universal (i386, x86_64, ppc) binary.')
267 opt.add_option('--mac_archs', action='store', default='', help='Comma separated list of architectures (i386, x86_64, ppc) to build on Mac.')
268 opt.add_option('--cairo', action='store_true', default=sys.platform.startswith('linux'), help='Use cairo for drawing (experimental for Win/Mac')
270 def common_configure(conf):
272 Configuration used by all targets, called from the target's configure() step.
275 conf.env['MSVC_TARGETS'] = ['x86']
277 build_port = Options.options.port
279 feature_defines = ['ENABLE_DATABASE', 'ENABLE_SQL_DATABASE', 'ENABLE_XSLT', 'ENABLE_JAVASCRIPT_DEBUGGER',
280 'ENABLE_SVG', 'ENABLE_FILTERS', 'ENABLE_SVG_FONTS', 'ENABLE_INSPECTOR', 'ENABLE_WORKERS',
281 'BUILDING_%s' % build_port.upper()]
283 conf.env["FEATURE_DEFINES"] = ' '.join(feature_defines)
285 if Options.options.msvc_version and Options.options.msvc_version != '':
286 conf.env['MSVC_VERSIONS'] = ['msvc %s.0' % Options.options.msvc_version]
288 conf.env['MSVC_VERSIONS'] = ['msvc 9.0', 'msvc 8.0']
290 if sys.platform.startswith('cygwin'):
291 print "ERROR: You must use the Win32 Python from python.org, not Cygwin Python, when building on Windows."
294 conf.check_tool('compiler_cxx')
295 conf.check_tool('compiler_cc')
297 if sys.platform.startswith('darwin'):
298 conf.check_tool('osx')
305 if Options.options.cairo and build_port == 'wx':
306 if building_on_win32 and not "CAIRO_ROOT" in os.environ:
307 Logs.error("To build with Cairo on Windows, you must set the CAIRO_ROOT environment variable.")
310 if building_on_win32:
313 found = conf.get_msvc_versions()
315 for version in found:
316 found_versions.append(version[0])
318 if 'msvc 9.0' in conf.env['MSVC_VERSIONS'] and 'msvc 9.0' in found_versions:
319 msvc_version = 'msvc2008'
320 elif 'msvc 8.0' in conf.env['MSVC_VERSIONS'] and 'msvc 8.0' in found_versions:
321 msvc_version = 'msvc2005'
323 msvclibs_dir = os.path.join(wklibs_dir, msvc_version, 'win')
325 # Disable several warnings which occur many times during the build.
326 # Some of them are harmless (4099, 4344, 4396, 4800) and working around
327 # them in WebKit code is probably just not worth it. We can simply do
328 # nothing about the others (4503). A couple are possibly valid but
329 # there are just too many of them in the code so fixing them is
330 # impossible in practice and just results in tons of distracting output
331 # (4244, 4291). Finally 4996 is actively harmful as it is given for
332 # just about any use of standard C/C++ library facilities.
333 conf.env.append_value('CXXFLAGS', [
334 '/wd4099', # type name first seen using 'struct' now seen using 'class'
335 '/wd4244', # conversion from 'xxx' to 'yyy', possible loss of data:
336 '/wd4291', # no matching operator delete found (for placement new)
337 '/wd4344', # behaviour change in template deduction
338 '/wd4396', # inline can't be used in friend declaration
339 '/wd4503', # decorated name length exceeded, name was truncated
340 '/wd4800', # forcing value to bool 'true' or 'false'
341 '/wd4996', # deprecated function
344 # This one also occurs in C code, so disable it there as well.
345 conf.env.append_value('CCFLAGS', ['/wd4996'])
347 if build_port == "wx":
348 update_wx_deps(conf, wk_root, msvc_version)
350 conf.env.append_value('CXXDEFINES', ['BUILDING_WX__=1'])
352 if building_on_win32:
353 conf.env.append_value('LIBPATH', os.path.join(msvclibs_dir, 'lib'))
356 is_debug = (config == 'Debug')
357 wxdefines, wxincludes, wxlibs, wxlibpaths = get_wxmsw_settings(wx_root, shared=True, unicode=True, debug=is_debug, wxPython=Options.options.wxpython)
358 conf.env['CXXDEFINES_WX'] = wxdefines
359 conf.env['CPPPATH_WX'] = wxincludes
360 conf.env['LIB_WX'] = wxlibs
361 conf.env['LIBPATH_WX'] = wxlibpaths
362 if Options.options.cairo and 'CAIRO_ROOT' in os.environ:
363 conf.env.append_value('CPPPATH_WX', [os.path.join(os.environ['CAIRO_ROOT'], 'include', 'cairo')])
364 conf.env.append_value('LIBPATH_WX', [os.path.join(os.environ['CAIRO_ROOT'], 'lib')])
365 conf.env.append_value('LIB_WX', ['cairo'])
367 conf.check_cfg(path=get_path_to_wxconfig(), args='--cxxflags --libs', package='', uselib_store='WX', mandatory=True)
369 if sys.platform.startswith('darwin'):
370 conf.env['LIB_ICU'] = ['icucore']
372 port_uses[build_port].append('CF')
374 conf.env.append_value('CPPPATH', wklibs_dir)
375 conf.env.append_value('LIBPATH', wklibs_dir)
379 mac_target = 'MACOSX_DEPLOYMENT_TARGET'
380 if Options.options.macosx_version != '':
381 min_version = Options.options.macosx_version
383 # WebKit only supports 10.4+, but ppc systems often set this to earlier systems
385 min_version = commands.getoutput('sw_vers -productVersion')[:4]
386 if min_version in ['10.1', '10.2', '10.3']:
389 sdk_version = min_version
390 if min_version == "10.4":
392 conf.env.append_value('LIB_WKINTERFACE', ['WebKitSystemInterfaceTiger'])
393 elif min_version == "10.7":
394 conf.env.append_value('LIB_WKINTERFACE', ['WebKitSystemInterfaceLion'])
396 # NOTE: There is a WebKitSystemInterfaceSnowLeopard, but when we use that
397 # on 10.6, we get a strange missing symbol error, and this library seems to
398 # work fine for wx's purposes.
399 conf.env.append_value('LIB_WKINTERFACE', ['WebKitSystemInterfaceLeopard'])
400 conf.env.append_value('LINKFLAGS', ['-framework', 'QuartzCore'])
402 # match WebKit Mac's default here unless we're building on platforms that won't support 64-bit.
405 if Options.options.mac_archs != '':
406 arch_list = Options.options.mac_archs.replace("'", '').replace('"', '').split(",")
407 for arch in arch_list:
408 if arch.strip() != '':
409 archs.append(arch.strip())
410 elif Options.options.mac_universal_binary:
411 archs = ['i386', 'x86_64', 'ppc']
413 is_cocoa = "__WXOSX_COCOA__" in conf.env["CXXDEFINES_WX"]
414 if min_version == "10.4" or not is_cocoa:
420 sdkroot = '/Developer/SDKs/MacOSX%s.sdk' % sdk_version
421 if not os.path.exists(sdkroot):
422 Logs.error("Cannot find the specified SDK needed to build: %r" % sdkroot)
424 sdkflags = ['-isysroot', sdkroot]
426 sdkflags.extend(['-arch', arch])
428 conf.env.append_value('CPPFLAGS', sdkflags)
429 conf.env.append_value('LINKFLAGS', sdkflags)
431 conf.env.append_value('LINKFLAGS', ['-framework', 'Security'])
433 conf.env.append_value('CPPPATH_SQLITE3', [os.path.join(wklibs_dir, 'WebCoreSQLite3')])
434 conf.env.append_value('LIB_SQLITE3', ['WebCoreSQLite3'])
436 # NOTE: The order here is important, because python sets the MACOSX_DEPLOYMENT_TARGET to
437 # 10.3 even on intel. So we must first set the SDK and arch flags, then load Python's config,
438 # and finally override the value Python set for MACOSX_DEPLOYMENT_TARGET
439 if Options.options.wxpython:
440 conf.check_tool('python')
441 conf.check_python_headers()
443 if sys.platform.startswith('darwin'):
444 os.environ[mac_target] = conf.env[mac_target] = min_version
446 conf.env.append_value('CXXDEFINES', feature_defines)
447 if config == 'Release':
448 conf.env.append_value('CPPDEFINES', 'NDEBUG')
450 if building_on_win32:
451 conf.env.append_value('CPPPATH', [
452 os.path.join(jscore_dir, 'os-win32'),
453 os.path.join(msvclibs_dir, 'include'),
454 os.path.join(msvclibs_dir, 'include', 'pthreads'),
455 os.path.join(msvclibs_dir, 'lib'),
458 conf.env.append_value('LIB', ['libpng', 'libjpeg', 'pthreadVC2'])
460 conf.env.append_value('LIB', [
461 'kernel32', 'user32', 'gdi32', 'comdlg32', 'winspool', 'winmm',
462 'shell32', 'shlwapi', 'comctl32', 'ole32', 'oleaut32', 'uuid', 'advapi32',
463 'wsock32', 'gdiplus', 'usp10', 'version'])
465 conf.env['LIB_ICU'] = ['icudt', 'icule', 'iculx', 'icuuc', 'icuin', 'icuio', 'icutu']
468 conf.env['LIB_CURL'] = ['libcurl']
471 conf.env['CPPPATH_SQLITE3'] = [os.path.join(msvclibs_dir, 'include', 'SQLite')]
472 conf.env['LIB_SQLITE3'] = ['sqlite3']
475 conf.env['LIB_XML'] = ['libxml2']
478 conf.env['LIB_XSLT'] = ['libxslt']
480 conf.env.append_value('CXXFLAGS', ['-fvisibility=hidden'])
481 if build_port == 'wx':
482 port_uses['wx'].append('PTHREADS')
483 conf.env.append_value('LIB', ['jpeg', 'png', 'pthread'])
484 conf.env.append_value('LIBPATH', os.path.join(wklibs_dir, 'unix', 'lib'))
485 conf.env.append_value('CPPPATH', os.path.join(wklibs_dir, 'unix', 'include'))
486 conf.env.append_value('CXXFLAGS', ['-fPIC', '-DPIC'])
487 conf.env.append_value('CXXFLAGS', ['-g'])
488 conf.check_cfg(msg='Checking for libxslt', path='xslt-config', args='--cflags --libs', package='', uselib_store='XSLT', mandatory=True)
489 conf.check_cfg(path='xml2-config', args='--cflags --libs', package='', uselib_store='XML', mandatory=True)
490 if sys.platform.startswith('darwin') and min_version and min_version == '10.4':
491 conf.check_cfg(path=os.path.join(wklibs_dir, 'unix', 'bin', 'curl-config'), args='--cflags --libs', package='', uselib_store='CURL', mandatory=True)
493 conf.check_cfg(path='curl-config', args='--cflags --libs', package='', uselib_store='CURL', mandatory=True)
495 if not sys.platform.startswith('darwin'):
496 # this is needed to keep ld from hitting the 4gb process limit under Linux/Unix.
497 conf.env.append_value('LINKFLAGS', ['-Wl,--no-keep-memory'])
498 conf.check_cfg(package='cairo', args='--cflags --libs', uselib_store='WX', mandatory=True)
499 conf.check_cfg(package='pango', args='--cflags --libs', uselib_store='WX', mandatory=True)
500 conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='WX', mandatory=True)
501 conf.check_cfg(package='sqlite3', args='--cflags --libs', uselib_store='SQLITE3', mandatory=True)
502 conf.check_cfg(path='icu-config', args='--cflags --ldflags', package='', uselib_store='ICU', mandatory=True)
504 if build_port in port_uses:
505 for use in port_uses[build_port]:
506 conf.env.append_value('CXXDEFINES', ['WTF_USE_%s' % use])