1
#! /usr/bin/env python
2
3
# Copyright (C) 2009 Kevin Ollivier  All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
# 1. Redistributions of source code must retain the above copyright
9
#    notice, this list of conditions and the following disclaimer.
10
# 2. Redistributions in binary form must reproduce the above copyright
11
#    notice, this list of conditions and the following disclaimer in the
12
#    documentation and/or other materials provided with the distribution.
13
#
14
# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25
#
26
# WebCore build script for the waf build system
27
28
import glob
29
import os
30
import subprocess
31
32
import Options
33
34
from settings import *
35
import wxpresets
36
37
import TaskGen
38
from TaskGen import taskgen, feature, after
39
import Task, ccroot
40
41
def clean_derived_sources(ds_cmd):
42
    # the below command does not produce the desired output under Cygwin, so for now,
43
    # disable this under Windows.
44
    if building_on_win32:
45
        return
46
        
47
    cmd = ds_cmd + " -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'"
48
    output = subprocess.check_output(cmd, shell=True)
49
    
50
    targets = []
51
    lines = output.split("\n")
52
    for line in lines:
53
        line = line.replace(":", "")
54
        base = os.path.splitext(os.path.basename(line))[0]
55
        if not base in targets:
56
            targets.append(base)
57
            if base == "UserAgentsStyleSheet":
58
                targets.append("UserAgentsStyleSheetData")
59
    
60
    # we're in the DerivedSources directory when this command is run.
61
    ds_files = glob.glob("*.*")
62
    for ds_file in ds_files:
63
        filename = os.path.basename(ds_file)
64
        basename = os.path.splitext(filename)[0]
65
        # For now, just remove JS*.h/.cpp and WebDOM*.h/.cpp when there are no longer targets
66
        # for them. Other targets may generate supplemental files so we can't reliably clean them.
67
        if not basename in targets and (basename.startswith("JS") or basename.startswith("WebDOM")):
68
            print "INFO: %s is no longer generated but present in generated files directory. Removing." % filename
69
            os.remove(ds_file)
70
    
71
def generate_webcore_derived_sources(conf):
72
    # build the derived sources
73
    derived_sources_dir = os.path.join(webcore_dir, 'DerivedSources')
74
    wc_dir = webcore_dir
75
    if building_on_win32:
76
        wc_dir = get_output('cygpath --unix "%s"' % wc_dir)
77
    if not os.path.exists(derived_sources_dir):
78
        os.mkdir(derived_sources_dir)
79
80
    olddir = os.getcwd()
81
    os.chdir(derived_sources_dir)
82
    
83
    # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead.
84
    if building_on_win32:
85
        oldpath = os.environ["PATH"]
86
        os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"]
87
    command = 'make -f %s/DerivedSources.make WebCore=%s SOURCE_ROOT=%s all FEATURE_DEFINES="%s"' % (wc_dir, wc_dir, wc_dir, conf.env["FEATURE_DEFINES"])
88
    clean_derived_sources(command)
89
    os.system(command)
90
    if building_on_win32:
91
        os.environ["PATH"] = oldpath
92
    
93
    os.chdir(olddir)
94
95
def generate_jscore_derived_sources(conf):
96
    # build the derived sources
97
    js_dir = jscore_dir
98
    if building_on_win32:
99
        js_dir = get_output('cygpath --unix "%s"' % js_dir)
100
    derived_sources_dir = os.path.join(jscore_dir, 'DerivedSources')
101
    if not os.path.exists(derived_sources_dir):
102
        os.mkdir(derived_sources_dir)
103
104
    olddir = os.getcwd()
105
    os.chdir(derived_sources_dir)
106
107
    # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead.
108
    if building_on_win32:
109
        oldpath = os.environ["PATH"]
110
        os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"]
111
    command = 'make -f %s/DerivedSources.make JavaScriptCore=%s BUILT_PRODUCTS_DIR=%s all FEATURE_DEFINES="%s"' % (js_dir, js_dir, js_dir, conf.env["FEATURE_DEFINES"])
112
    os.system(command)
113
    if building_on_win32:
114
        os.environ["PATH"] = oldpath
115
    os.chdir(olddir)
116
117
def set_options(opt):
118
    common_set_options(opt)
119
120
def configure(conf):
121
    common_configure(conf)
122
    generate_jscore_derived_sources(conf)
123
    generate_webcore_derived_sources(conf)
124
    if Options.options.port == "wx" and sys.platform.startswith('win'):
125
        graphics_dir = os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics')
126
        # we used to copy these files into the graphics/wx directory due to 
127
        # both wx and win directories having FontPlatformData.h. That is no 
128
        # longer the case, so we remove the old files if they exist.
129
        for afile in ['UniscribeController.h', 'UniscribeController.cpp', 'GlyphPageTreeNodeCairoWin.cpp']:
130
            wx_copy = os.path.join(graphics_dir, 'wx', afile)
131
            if os.path.exists(wx_copy):
132
                os.remove(wx_copy)
133
134
    webcore_out_dir = os.path.join(output_dir, 'WebCore')
135
    if not os.path.exists(webcore_out_dir):
136
        os.makedirs(webcore_out_dir)
137
    shutil.copy('Source/WebCore/platform/mac/WebCoreSystemInterface.h', os.path.join(output_dir, 'WebCore', 'WebCoreSystemInterface.h'))
138
    jscore_out_dir = os.path.join(output_dir, 'JavaScriptCore')
139
    if not os.path.exists(jscore_out_dir):
140
        os.makedirs(jscore_out_dir)
141
    for api_file in glob.glob(os.path.join(jscore_dir, 'API/*.h')):
142
        shutil.copy(api_file, os.path.join(jscore_out_dir, os.path.basename(api_file)))
143
144
    if Options.options.port == "wx" and Options.options.wxpython:
145
        common_configure(conf)
146
        conf.check_tool('swig', tooldir='Source/WebKit/wx/bindings/python')
147
        conf.check_swig_version('1.3.29')
148
149
def build(bld):
150
151
    webcore_dirs = list(webcore_dirs_common)
152
153
    # auto-generate WebKitVersion.h if needed before we start the build.
154
    # Also, remove the file from the old location where we generated it before running
155
    wk_version_h = 'Source/WebCore/DerivedSources/WebKitVersion.h'
156
    if os.path.exists(wk_version_h):
157
        os.remove(wk_version_h)
158
    bld.new_task_gen(source = "Source/WebKit/mac/Configurations/Version.xcconfig",
159
                     target = wk_version_h,
160
                     rule = 'perl %s/Source/WebKit/scripts/generate-webkitversion.pl --outputDir=${TGT[0].dir(env)} --config ${SRC}' % wk_root)
161
    bld.add_group()
162
163
    if Options.options.port == "wx":
164
        webcore_dirs.extend(['Source/WebKit/wx', 'Source/WebKit/wx/WebKitSupport'])
165
    
166
    wk_includes = ['.',
167
                    os.path.join(wk_root, 'Source', 'WTF'),
168
                    os.path.join(wk_root, 'Source', 'WTF', 'wtf'),
169
                    os.path.join(wk_root, 'Source', 'JavaScriptCore'),
170
                    os.path.join(wk_root, 'Source', 'WebCore'),
171
                    os.path.join(wk_root, 'Source', 'WebCore', 'DerivedSources'),
172
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'image-decoders'),
173
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'win'),
174
                    os.path.join(wk_root, 'Source', 'WebCore', 'workers'),
175
                    os.path.join(output_dir),
176
            ]
177
    
178
    if Options.options.port == "wx":
179
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebKit', 'wx'))
180
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'wx', 'wxcode'))
181
    
182
    if sys.platform.startswith("win"):
183
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'win'))
184
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics', 'win'))
185
    
186
    windows_deps = [
187
                    'lib/pthreadVC2.dll',
188
                    'bin/icuuc40.dll', 'bin/icudt40.dll', 'bin/icuin40.dll',
189
                    'bin/libcurl.dll', 'bin/libeay32.dll', 'bin/ssleay32.dll', 'bin/zlib1.dll',
190
                    'lib/sqlite3.dll', 'bin/libxml2.dll', 'bin/libxslt.dll', 'bin/iconv.dll',
191
                    ]
192
    
193
    webcore_sources = {}
194
    
195
    if Options.options.port == "wx":
196
        webcore_sources['wx'] = [
197
            'Source/WebCore/bindings/cpp/WebDOMEventTarget.cpp',
198
            'Source/WebCore/platform/KillRingNone.cpp',
199
            'Source/WebCore/platform/text/LocalizedDateNone.cpp',
200
            'Source/WebCore/platform/text/LocalizedNumberNone.cpp',
201
            'Source/WebCore/page/scrolling/ScrollingCoordinatorNone.cpp',
202
        ]  
203
    
204
        if building_on_win32:
205
            # make sure platform/wx comes after this so we get the right
206
            # FontPlatformData.h
207
            webcore_dirs.extend(['Source/WebCore/platform/wx/wxcode/win', 'Source/WebCore/plugins/win'])
208
            webcore_sources['wx-win'] = [
209
                   'Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp',
210
                   'Source/WebCore/platform/graphics/win/TransformationMatrixWin.cpp',
211
                   'Source/WebCore/platform/graphics/win/UniscribeController.cpp',
212
                   'Source/WebCore/platform/ScrollAnimatorNone.cpp',
213
                   # wxTimer on Windows has a bug that causes it to eat crashes in callbacks
214
                   # so we need to use the Win port's implementation until the wx bug fix is
215
                   # widely available (it was fixed in 2.8.10).
216
                   'Source/WebCore/platform/win/SharedTimerWin.cpp',
217
                   'Source/WebCore/platform/win/SystemInfo.cpp',
218
                   'Source/WebCore/platform/win/WebCoreInstanceHandle.cpp',
219
                   # Use the Windows plugin architecture
220
                   #'Source/WebCore/plugins/win/PluginDataWin.cpp',
221
                   'Source/WebCore/plugins/win/PluginDatabaseWin.cpp',
222
                   'Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp',
223
                   'Source/WebCore/plugins/win/PluginPackageWin.cpp',
224
                   'Source/WebCore/plugins/win/PluginViewWin.cpp',
225
            ]
226
            if Options.options.cairo:
227
                webcore_dirs.append('Source/WebCore/platform/wx/wxcode/cairo')
228
            else:
229
                webcore_dirs.append('Source/WebCore/platform/wx/wxcode/gdiplus')
230
        elif sys.platform.startswith('darwin'):
231
            webcore_dirs.append('Source/WebCore/plugins/mac')
232
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/mac/carbon')
233
            webcore_dirs.append('Source/WebCore/platform/text/mac')
234
            webcore_sources['wx-mac'] = [
235
                   'Source/WebCore/platform/mac/PurgeableBufferMac.cpp',
236
                   'Source/WebCore/platform/mac/WebCoreNSStringExtras.mm',
237
                   'Source/WebCore/platform/mac/WebCoreSystemInterface.mm',
238
                   'Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp',
239
                   'Source/WebCore/platform/graphics/mac/ComplexTextController.cpp',
240
                   'Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm',
241
                   'Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp',
242
                   'Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp',
243
                   'Source/WebCore/platform/graphics/mac/SimpleFontDataATSUI.mm',
244
                   'Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp',
245
                   'Source/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm',
246
                   'Source/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm',
247
                   'Source/WebCore/plugins/mac/PluginPackageMac.cpp',
248
                   'Source/WebCore/plugins/mac/PluginViewMac.mm'
249
            ]
250
        else:
251
            webcore_sources['wx-gtk'] = [
252
                   'Source/WebCore/plugins/PluginViewNone.cpp',
253
                   'Source/WebCore/plugins/PluginPackageNone.cpp'
254
            ]
255
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/gtk')
256
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/cairo')
257
        
258
259
    import TaskGen
260
261
    bld.add_subdirs('Source/JavaScriptCore')
262
263
    if sys.platform.startswith('darwin'):
264
        TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cxx']
265
        TaskGen.task_gen.mappings['.m'] = TaskGen.task_gen.mappings['.cxx']
266
267
    features = [Options.options.port.lower()]
268
    thisport = Options.options.port
269
    
270
    exclude_patterns = ['*AllInOne.cpp', '*None.cpp',]
271
272
    if sys.platform.startswith('darwin'):
273
        features.append('cf')
274
275
    # exclude the filename patterns for all other ports.
276
    exclude_patterns.extend(get_port_excludes(Options.options.port))
277
            
278
    if Options.options.port == 'wx':
279
        features.append('curl')
280
        exclude_patterns.extend(['*CFNet.cpp', 'test*bindings.*', "WebDOMCanvas*.cpp", "WebDOMSVG*.cpp"])
281
        
282
    full_dirs = get_dirs_for_features(wk_root, features=features, dirs=webcore_dirs)
283
284
    # make sure we don't use the CF networking engine
285
    if Options.options.port == 'wx' and sys.platform.startswith('darwin'):
286
        full_dirs.remove('Source/WebCore/platform/network/cf')
287
        
288
    jscore_dir = os.path.join(wk_root, 'Source', 'JavaScriptCore')
289
    for item in os.listdir(jscore_dir):
290
        fullpath = os.path.join(jscore_dir, item)
291
        if os.path.isdir(fullpath) and not item == "os-win32" and not item == 'icu':
292
            wk_includes.append(fullpath)
293
294
    wk_includes.append('Source')
295
    wk_includes.append(os.path.join(jscore_dir, 'collector', 'handles'))
296
    wk_includes += common_includes + full_dirs
297
    if sys.platform.startswith('darwin'):
298
        wk_includes.append(os.path.join(webcore_dir, 'icu'))
299
300
    cxxflags = []
301
    if building_on_win32:
302
        cxxflags.append('/FIWebCorePrefix.h')
303
        # FIXME: We do this because in waf, local include dirs take precedence
304
        # over global ones. This makes sense, but because unicode/utf8.h is both
305
        # an ICU header name and a WebKit header name (in Source/JavaScriptCore/wtf)
306
        # we have to make sure <unicode/utf8.h> picks up the ICU one first.
307
        global msvclibs_dir
308
        wk_includes.append(os.path.join(msvclibs_dir, 'include'))
309
        wk_includes.append('Source/WebCore/platform/graphics/win')
310
    else:
311
        cxxflags.extend(['-include', 'WebCorePrefix.h'])
312
313
    webcore = bld.new_task_gen(
314
        features = 'cc cxx cshlib',
315
        includes = ' '.join(wk_includes),
316
        source = ' '.join(flattenSources(webcore_sources.values())),
317
        cxxflags = cxxflags,
318
        defines = ['WXMAKINGDLL_WEBKIT', 'BUILDING_WebCore'],
319
        libpath = [output_dir],
320
        target = 'wxwebkit',
321
        uselib = 'WX ICU XML XSLT CURL SQLITE3 WKINTERFACE ' + get_config(),
322
        uselib_local = 'jscore',
323
        install_path = output_dir,
324
        )
325
        
326
    excludes = []
327
    
328
    if Options.options.port == 'wx':
329
        excludes = get_excludes(webcore_dir, exclude_patterns)
330
        excludes.extend(['UserStyleSheetLoader.cpp', 'RenderMediaControls.cpp'])
331
332
        # intermediate sources
333
        excludes.append('DocTypeStrings.cpp')
334
        excludes.append('HTMLEntityNames.cpp')
335
336
        # Qt specific file in common sources
337
        excludes.append('ContextShadow.cpp')
338
339
        # FIXME: these require headers that I can't seem to find in trunk.
340
        # Investigate how to resolve these issues.
341
        excludes.append('JSAbstractView.cpp')
342
        excludes.append('JSIntentConstructor.cpp')
343
        excludes.append('JSPositionCallback.cpp')
344
        excludes.append('JSInspectorController.cpp')
345
        
346
        # The bindings generator seems to think these are ref-counted, while they aren't in trunk.
347
        excludes.append('JSElementTimeControl.cpp')
348
        excludes.append('JSSVGAnimatedPathData.cpp')
349
        excludes.append('JSSVGAnimatedPoints.cpp')
350
        excludes.append('JSSVGExternalResourcesRequired.cpp')
351
        excludes.append('JSSVGFilterPrimitiveStandardAttributes.cpp')
352
        excludes.append('JSSVGLocatable.cpp')
353
        excludes.append('JSSVGStyleTable.cpp')
354
        excludes.append('JSSVGTests.cpp')
355
        excludes.append('JSSVGStylable.cpp')
356
        
357
        # These are files that expect methods not in the base C++ class, usually XYZAnimated methods.
358
        excludes.append('JSSVGFitToViewBox.cpp')
359
        excludes.append('JSSVGLangSpace.cpp')
360
        excludes.append('JSSVGTransformable.cpp')
361
        excludes.append('JSSVGURIReference.cpp')
362
        
363
        # These are C++ DOM Bindings that won't compile because they look for things not in trunk.
364
        excludes.append('WebDOMEventTarget.cpp')
365
        excludes.append('WebDOMAbstractView.cpp')
366
        excludes.append('WebDOMBlobBuilder.cpp')
367
        excludes.append('WebDOMEventListenerCustom.cpp')
368
        excludes.append('WebDOMElementTimeControl.cpp')
369
        excludes.append('WebDOMImageData.cpp')
370
        excludes.append('WebDOMInspectorBackend.cpp')
371
        excludes.append('WebDOMScriptProfile.cpp')
372
        excludes.append('WebDOMScriptProfileNode.cpp')
373
        excludes.append('WebNativeEventListener.cpp')
374
        
375
        # FIXME: It appears these are no longer needed by any port, once this is confirmed,
376
        # we should remove these sources from the tree.
377
        excludes.append('WebDOMDOMWindowCustom.cpp')
378
        excludes.append('WebDOMHTMLOptionsCollectionCustom.cpp')
379
        excludes.append('WebDOMNodeCustom.cpp')
380
        excludes.append('WebDOMHTMLDocumentCustom.cpp')
381
        excludes.append('WebDOMHTMLCollectionCustom.cpp')
382
        excludes.append('WebNativeNodeFilterCondition.cpp')
383
        excludes.append('WebDOMNodeFilterCustom.cpp')
384
        
385
        # this file is unused by any port, not sure why it was
386
        # left in the tree
387
        excludes.append('GeneratedImage.cpp')
388
        
389
        # features we don't build / use
390
        excludes.append('JSNavigatorCustom.cpp')
391
        excludes.append('WebGLContextEvent.cpp')
392
        excludes.append('FileSystemPOSIX.cpp')
393
        excludes.append('LocaleICU.cpp')
394
        excludes.append('LocalizedDateICU.cpp')
395
        excludes.append('PlatformGestureRecognizer.cpp')
396
        excludes.append('SharedBufferPOSIX.cpp')
397
        excludes.append('TouchAdjustment.cpp')
398
        excludes.append('DNSResolveQueue.cpp')
399
        excludes.append('WebDOMRadioNodeList.cpp')
400
        
401
        # These files appear not to build with older versions of ICU
402
        excludes.append('LocalizedNumberICU.cpp')
403
        excludes.append('LocaleToScriptMappingICU.cpp')
404
        
405
        if building_on_win32:
406
            excludes.append('SharedTimerWx.cpp')
407
            excludes.append('RenderThemeWin.cpp')
408
            excludes.append('KeyEventWin.cpp')
409
            
410
        if building_on_win32 or sys.platform.startswith('darwin'):
411
            excludes.append('GlyphMapWx.cpp')
412
        excludes.append('AuthenticationCF.cpp')
413
        excludes.append('LoaderRunLoopCF.cpp')
414
        excludes.append('ResourceErrorCF.cpp')
415
        excludes.append('RunLoopCF.cpp')
416
        
417
        # once we move over to the new FPD implementation, remove this.
418
        excludes.append('FontPlatformData.cpp')
419
        
420
        # we need a better system to exclude CF stuff
421
        excludes.append('HyphenationCF.cpp')
422
        
423
        if sys.platform.startswith('darwin'):
424
            webcore.includes += ' Source/WebKit/mac/WebCoreSupport Source/WebCore/platform/mac'
425
            webcore.source += ' Source/WebKit/mac/WebCoreSupport/WebSystemInterface.mm'
426
            
427
        if building_on_win32:
428
            for wxlib in bld.env['LIB_WX']:
429
                wx_version = wxpresets.get_wx_version(os.environ['WXWIN'])
430
                if int(wx_version[1]) % 2 == 1:
431
                    wxlib = wxlib.replace(''.join(wx_version[:2]), ''.join(wx_version))
432
                wxlibname = os.path.join(bld.env['LIBPATH_WX'][0], wxlib + '_vc.dll')
433
                print "Copying %s" % wxlibname
434
                if os.path.exists(wxlibname):
435
                    bld.install_files(webcore.install_path, [wxlibname])
436
        
437
            for dep in windows_deps:
438
                bld.install_files(webcore.install_path, [os.path.join(msvclibs_dir, dep)])
439
            
440
            if "CAIRO_ROOT" in os.environ and Options.options.cairo:
441
                cairo_bin_dir = os.path.join(os.environ["CAIRO_ROOT"], "bin") 
442
                for dep in glob.glob(os.path.join(cairo_bin_dir, "*.dll")):
443
                    bld.install_files(webcore.install_path, [os.path.join(cairo_bin_dir, dep)])
444
                    
445
    webcore.find_sources_in_dirs(full_dirs, excludes = excludes, exts=['.c', '.cpp'])
446
447
    bld.add_group()
448
    
449
    if Options.options.port == "wx":    
450
        bld.add_subdirs(['Tools/DumpRenderTree', 'Tools/wx/browser', 'Source/WebKit/wx/bindings/python'])