1# -*- Python -*-
2#
3# All the helper functions are defined in:
4#  - site_scons/talk.py
5# Use 'import talk' in any .scons file to get access to it.
6# Add any new helper functions to it; unittest are available
7# in talk_unittest.py.
8#
9# Each 'component' that is built is defined in a .scons file.
10# See talk.Components(...) for further info on file naming convention.
11#
12# To add a new platform clone and modify the root_env object. Remember to add
13# the new environment object to the envs list otherwise it will not be included
14# in the build.
15#
16#
17#
18import talk
19import os
20import platform
21
22#-------------------------------------------------------------------------------
23# The build files/directories to 'build'.
24# If the name is the name of a directory then that directory shall contain a
25# .scons file with the same name as the directory itself:
26#  Ex: The directory session/phone contains a file called phone.scons
27#
28components = talk.Components("libjingle.scons")
29
30#-------------------------------------------------------------------------------
31# Build environments
32#
33
34# The list of build environments.
35envs = []
36
37# The root of all builds.
38root_env = Environment(
39  tools = [
40    'component_bits',
41    'component_setup',
42    'replace_strings',
43    'talk_noops',
44    #'talk_linux',
45  ],
46  BUILD_SCONSCRIPTS = components,
47  DESTINATION_ROOT = '$MAIN_DIR/build',
48  CPPPATH = [
49    '$OBJ_ROOT',     # generated headers are relative to here
50    '$MAIN_DIR/..',  # TODO: how can we use GOOGLECLIENT instead?
51  ],
52  CPPDEFINES = [
53    # Temp flag while porting to hammer.
54    'HAMMER_TIME=1',
55    'LOGGING=1',
56
57    # Feature selection
58    'FEATURE_ENABLE_SSL',
59    'FEATURE_ENABLE_VOICEMAIL',
60    'FEATURE_ENABLE_PSTN',
61    'HAVE_SRTP',
62  ]
63)
64
65# This is where we set common environments
66#
67# Detect if running on 64 bit or 32 bit host.
68DeclareBit('platform_arch_64bit', 'Host Platform is 64 Bit')
69if platform.architecture()[0] == "64bit":
70  root_env.SetBits('platform_arch_64bit')
71
72DeclareBit('use_static_openssl', 'Build OpenSSL as a static library')
73
74
75#-------------------------------------------------------------------------------
76# W I N D O W S
77#
78win_env = root_env.Clone(
79  tools = [
80    'atlmfc_vc80',
81    #'code_signing',
82    'component_targets_msvs',
83    'directx_9_0_c',
84    #'grid_builder',
85    'midl',
86    'target_platform_windows',
87  ],
88  # Don't use default vc80 midl.exe.  It doesn't understand vista_sdk idl files.
89  MIDL = '$PLATFORM_SDK_VISTA_6_0_DIR/Bin/midl.exe ',
90  WIX_DIR = '$GOOGLECLIENT/third_party/wix/v3_0_2925/files',
91  # Flags for debug and optimization are added to CCFLAGS instead
92  CCPDBFLAGS = '',
93  CCFLAGS_DEBUG = '',
94  CCFLAGS_OPTIMIZED = '',
95  # We force a x86 target even when building on x64 Windows platforms.
96  TARGET_ARCH = 'x86',
97)
98
99win_env.Append(
100  COMPONENT_LIBRARY_PUBLISH = True,  # Put dlls in output dir too
101  CCFLAGS = [
102    '/Fd${TARGET}.pdb', # pdb per object allows --jobs=
103    '/WX',          # warnings are errors
104    '/Zc:forScope', # handle 'for (int i = 0 ...)' right
105    '/EHs-c-',      # disable C++ EH
106    '/GR-',         # disable RTTI
107    '/wd4996',      # ignore POSIX deprecated warnings
108
109    # promote certain level 4 warnings
110    '/w14701',     # potentially uninitialized var
111    '/w14702',     # unreachable code
112    '/w14706',     # assignment within a conditional
113    '/w14709',     # comma operator within array index
114    '/w14063',     # case 'identifier' is not a valid value for switch of enum
115    '/w14064',     # switch of incomplete enum 'enumeration'
116    '/w14057',     # 'identifier1' indirection to slightly different base
117                   #   types from 'identifier2'
118    '/w14263',     # member function does not override any base class virtual
119                   #   member function
120    '/w14266',     # no override available for virtual memberfunction from base
121                   #  'type'; function is hidden
122    '/w14296',     # expression is always false
123    '/w14355',     # 'this' : used in base member initializer list
124  ],
125  CPPDEFINES = [
126    '_ATL_CSTRING_EXPLICIT_CONSTRUCTORS',
127    # TODO: encapsulate all string operations that are not based
128    # on std::string/std::wstring and make sure we use the safest versions
129    # available on all platforms.
130    '_CRT_SECURE_NO_WARNINGS',
131    '_SCL_SECURE_NO_WARNINGS',
132    '_USE_32BIT_TIME_T',
133    '_UNICODE',
134    'UNICODE',
135    '_HAS_EXCEPTIONS=0',
136    'WIN32',
137    # TODO: remove this from logging.cc and enable here instead.
138    #'WIN32_LEAN_AND_MEAN',
139
140    'WINVER=0x0500',
141    '_WIN32_WINNT=0x0501',
142    '_WIN32_IE=0x0501',
143    # The Vista platform SDK 6.0 needs at least
144    # this NTDDI version or else the headers
145    # that LMI includes from it won't compile.
146    'NTDDI_VERSION=NTDDI_WINXP',
147
148    # npapi.h requires the following:
149    '_WINDOWS',
150  ],
151  CPPPATH = [
152    '$THIRD_PARTY/wtl_71/include',
153    '$PLATFORM_SDK_VISTA_6_0_DIR/Include',
154  ],
155  LIBPATH = [
156    '$PLATFORM_SDK_VISTA_6_0_DIR/Lib'
157  ],
158  LINKFLAGS = [
159    '-manifest' # TODO: Why do we need this?
160  ],
161  MIDLFLAGS = [
162    '/win32',
163    '/I$PLATFORM_SDK_VISTA_6_0_DIR/include'
164  ]
165)
166
167# TODO: Figure out what this does; found it in
168# omaha/main.scons. This fixes the problem with redefinition
169# of OS_WINDOWS symbol.
170win_env.FilterOut(CPPDEFINES = ['OS_WINDOWS=OS_WINDOWS'])
171
172# Set up digital signing
173DeclareBit('test_signing', 'Sign binaries with the test certificate')
174win_env.SetBitFromOption('test_signing', False)
175if win_env.Bit('test_signing'):
176   win_env.Replace(
177     CERTIFICATE_PATH = win_env.File(
178         '$GOOGLECLIENT/tools/test_key/testkey.pfx').abspath,
179     CERTIFICATE_PASSWORD = 'test',
180   )
181AddTargetGroup('signed_binaries', 'digitally signed binaries can be built')
182
183win_dbg_env = win_env.Clone(
184  BUILD_TYPE = 'dbg',
185  BUILD_TYPE_DESCRIPTION = 'Windows debug build',
186  BUILD_GROUPS = ['default', 'all'],
187  tools = ['target_debug'],
188)
189
190win_dbg_env.Prepend(
191  CCFLAGS = [
192      '/ZI',     # enable debugging
193      '/Od',     # disable optimizations
194      '/MTd',    # link with LIBCMTD.LIB debug lib
195      '/RTC1',   # enable runtime checks
196  ],
197)
198
199envs.append(win_dbg_env)
200
201win_coverage_env = win_dbg_env.Clone(
202  tools = ['code_coverage'],
203  BUILD_TYPE = 'coverage',
204  BUILD_TYPE_DESCRIPTION = 'Windows code coverage build',
205  BUILD_GROUPS = ['all'],
206)
207
208win_coverage_env.Append(
209  CPPDEFINES = [
210    'COVERAGE_ENABLED',
211  ],
212)
213
214envs.append(win_coverage_env)
215
216win_opt_env = win_env.Clone(
217  BUILD_TYPE = 'opt',
218  BUILD_TYPE_DESCRIPTION = 'Windows opt build',
219  BUILD_GROUPS = ['all'],
220  tools = ['target_optimized'],
221)
222
223win_opt_env.Prepend(
224  CCFLAGS=[
225      '/Zi',     # enable debugging
226      '/O1',     # optimize for size
227      '/MT',     # link with LIBCMT.LIB (multi-threaded, static linked crt)
228      '/GS',     # enable security checks
229  ],
230  LINKFLAGS = [
231    '/safeseh',
232  ],
233)
234
235envs.append(win_opt_env)
236
237
238#-------------------------------------------------------------------------------
239# P O S I X
240#
241posix_env = root_env.Clone()
242posix_env.Append(
243  CPPDEFINES = [
244    'HASHNAMESPACE=__gnu_cxx',
245    'HASH_NAMESPACE=__gnu_cxx',
246    'POSIX',
247    'DISABLE_DYNAMIC_CAST',
248    'HAVE_OPENSSL_SSL_H=1',
249    # The POSIX standard says we have to define this.
250    '_REENTRANT',
251  ],
252  CCFLAGS = [
253    '-Wall',
254    '-Werror',
255    '-Wno-switch',
256    '-fno-exceptions',
257  ],
258  CXXFLAGS = [
259    '-Wno-non-virtual-dtor',
260    '-Wno-ctor-dtor-privacy',
261    '-fno-rtti',
262  ],
263)
264
265#-------------------------------------------------------------------------------
266# M A C OSX
267#
268mac_env = posix_env.Clone(
269  tools = [
270    'target_platform_mac',
271    #'talk_mac',
272    #'fill_plist',
273  ],
274)
275mac_env.Append(
276  CPPDEFINES = [
277    'OSX',
278    'MAC_OS_X_VERSION_MIN_REQUIRED=1040',
279  ],
280  CCFLAGS = [
281    '-m32',
282    '-arch', 'i386',
283    '-isysroot', '/Developer/SDKs/MacOSX10.5.sdk',
284    '-fasm-blocks',
285  ],
286  LINKFLAGS = [
287    '-Wl,-search_paths_first',
288    # This flag makes all members of a static library be included in the
289    # final exe - that increases the size of the exe, but without it
290    # Obj-C categories aren't properly included in the exe.
291    # TODO: consider only defining for libs that actually have objc.
292    '-ObjC',
293    '-arch', 'i386',
294    '-m32',
295  ],
296  FRAMEWORKS = [
297    'CoreServices',
298    'Carbon',
299    'Security',
300    'SystemConfiguration',
301    'OpenGL',
302    'CoreAudio',
303    'Quartz',
304    'QuickTime',
305    'Cocoa',
306    'QTKit',
307  ]
308)
309
310mac_dbg_env = mac_env.Clone(
311  BUILD_TYPE = 'dbg',
312  BUILD_TYPE_DESCRIPTION = 'Mac debug build',
313  BUILD_GROUPS = ['default', 'all'],
314  tools = ['target_debug'],
315)
316mac_dbg_env.Append(
317  CCFLAGS = [
318    '-O0',
319  ]
320)
321envs.append(mac_dbg_env)
322
323mac_opt_env = mac_env.Clone(
324  BUILD_TYPE = 'opt',
325  BUILD_TYPE_DESCRIPTION = 'Mac opt build',
326  BUILD_GROUPS = ['all'],
327  tools = ['target_optimized'],
328)
329mac_opt_env.Append(
330  CCFLAGS = [
331    # TODO: Figure out how mk can compile without
332    # this flag, then remove.  Confirmed asserts are preprocessed
333    # out.  Maybe it's a different version of gcc?
334    '-Wno-unused-variable',
335  ],
336)
337envs.append(mac_opt_env)
338
339#-------------------------------------------------------------------------------
340# L I N U X
341#
342linux_common_env = posix_env.Clone(
343  tools = [
344    'target_platform_linux',
345    #'talk_linux',
346  ],
347)
348
349linux_common_env.Append(
350  CPPDEFINES = [
351    'LINUX',
352    'HAVE_GLIB',
353#   'HAVE_DBUS_GLIB',
354  ],
355  CCFLAGS = [
356    # TODO: Some or all of this may be desirable for Mac too.
357    # Needed for link-time dead-code removal to work properly.
358    '-ffunction-sections',
359    '-fdata-sections',
360    # Needed for a clean ABI and for link-time dead-code removal to work
361    # properly.
362    '-fvisibility=hidden',
363    # Generate debugging info in the DWARF2 format.
364    '-gdwarf-2',
365    # Generate maximal debugging information. (It is stripped from what we ship
366    # to users, so we want it for both dbg and opt.)
367    '-g3',
368  ],
369  LINKFLAGS = [
370    # Enable dead-code removal.
371    '-Wl,--gc-sections',
372    '-Wl,--start-group',
373  ],
374  _LIBFLAGS = ['-Wl,--end-group'],
375)
376
377# Remove default rpath set by Hammer. Hammer sets it to LIB_DIR, which is wrong.
378# The rpath is the _run-time_ library search path for the resulting binary, i.e.
379# the one used by ld.so at load time. Setting it equal to the path to build
380# output on the build machine is nonsense.
381linux_common_env.Replace(
382  RPATH = [],
383)
384
385#-------------------------------------------------------------------------------
386# L I N U X -- T R A D I T I O N A L
387#
388# Settings that are specific to our desktop Linux targets.
389linux_env = linux_common_env.Clone()
390# OpenSSL has infamously poor ABI stability, so that building against one
391# version and running against a different one often will not work. Since our
392# non-ChromeOS Linux builds are used on many different distros and distro
393# versions, this means we can't safely dynamically link to OpenSSL because the
394# product would end up being broken on any computer with a different version
395# installed. So instead we build it ourself and statically link to it.
396linux_env.SetBits('use_static_openssl')
397linux_env.Append(
398  CCFLAGS = [
399    '-m32',
400  ],
401  LINKFLAGS = [
402    '-m32',
403  ],
404)
405
406linux_dbg_env = linux_env.Clone(
407  BUILD_TYPE = 'dbg',
408  BUILD_TYPE_DESCRIPTION = 'Linux debug build',
409  BUILD_GROUPS = ['default', 'all'],
410  tools = ['target_debug'],
411)
412# Remove -g set by hammer, which is not what we want (we have set -g3 above).
413linux_dbg_env.FilterOut(CCFLAGS = ['-g'])
414envs.append(linux_dbg_env)
415
416linux_opt_env = linux_env.Clone(
417  BUILD_TYPE = 'opt',
418  BUILD_TYPE_DESCRIPTION = 'Linux optimized build',
419  BUILD_GROUPS = ['all'],
420  tools = ['target_optimized'],
421)
422# Remove -O2 set by hammer, which is not what we want.
423linux_opt_env.FilterOut(CCFLAGS = ['-O2'])
424linux_opt_env.Append(CCFLAGS = ['-Os'])
425envs.append(linux_opt_env)
426
427
428
429# TODO(): Clone linux envs for 64bit.  See 'variant' documentation.
430
431# Create a group for installers
432AddTargetGroup('all_installers', 'installers that can be built')
433
434# Parse child .scons files
435BuildEnvironments(envs)
436
437# Explicitly set which targets to build when not stated on commandline
438Default(None)
439# Build the following, which excludes unit test output (ie running them)
440# To run unittests, specify the test to run, or run_all_tests.  See -h option.
441Default(['all_libraries', 'all_programs', 'all_test_programs'])
442
443# .sln creation code lifted from googleclient/bar/main.scons.  Must be after
444# the call to BuildEnvironments for all_foo aliases to be defined.
445# Run 'hammer --mode=all --vsproj' to generate
446DeclareBit('vsproj', 'Generate Visual Studio projects and solution files.')
447win_env.SetBitFromOption('vsproj', False)
448
449if win_env.Bit('vsproj'):
450  vs_env = win_env.Clone()
451  vs_env.Append(
452    COMPONENT_VS_SOURCE_SUFFIXES = [
453      '.def',
454      '.grd',
455      '.html',
456      '.idl',
457      '.mk',
458      '.txt',
459      '.py',
460      '.scons',
461      '.wxs.template',
462    ]
463  )
464
465  # Source project
466  p = vs_env.ComponentVSDirProject(
467    'flute_source',
468    ['$MAIN_DIR',
469     '$THIRD_PARTY'],
470    COMPONENT_VS_SOURCE_FOLDERS = [
471      # Files are assigned to first matching folder. Folder names of None
472      # are filters.
473      (None, '$DESTINATION_ROOT'),
474      ('flute', '$MAIN_DIR'),
475      ('google3', '$GOOGLE3'),
476      ('third_party', '$THIRD_PARTY'),
477    ],
478    # Force source project to main dir, so that Visual Studio can find the
479    # source files corresponding to build errors.
480    COMPONENT_VS_PROJECT_DIR = '$MAIN_DIR',
481  )
482  vs_env.AlwaysBuild(p)
483
484  # Solution and target projects
485  s = vs_env.ComponentVSSolution(
486    # 'libjingle',  # Please uncomment this line if you build VS proj files.
487    ['all_libraries', 'all_programs', 'all_test_programs'],
488    projects = [p],
489  )
490
491  print '***Unfortunately the vsproj creator isn\'t smart enough to '
492  print '***automatically get the correct output locations.  It is very easy'
493  print '***though to change it in the properties pane to the following'
494  print '***($SolutionDir)/build/<foo>/staging/<bar>.exe'
495  Default(None)
496  Default([s])
497