blob: e23f4815b4a162a1747f3c9b1dfc082ddbe96f80 [file] [log] [blame]
# -*- Python -*-
#
# All the helper functions are defined in:
# - site_scons/talk.py
# Use 'import talk' in any .scons file to get access to it.
# Add any new helper functions to it; unittest are available
# in talk_unittest.py.
#
# Each 'component' that is built is defined in a .scons file.
# See talk.Components(...) for further info on file naming convention.
#
# To add a new platform clone and modify the root_env object. Remember to add
# the new environment object to the envs list otherwise it will not be included
# in the build.
#
#
#
import talk
import os
import platform
#-------------------------------------------------------------------------------
# The build files/directories to 'build'.
# If the name is the name of a directory then that directory shall contain a
# .scons file with the same name as the directory itself:
# Ex: The directory session/phone contains a file called phone.scons
# This list must be in order of library dependencies. e.g., if
# session/phone/phone.scons defines a target that links to a library target
# defined in sound/sound.scons, then 'sound' must come first.
# When no particular order is imposed by library dependencies, try to keep in
# mostly alphabetical order.
#
components = talk.Components("libjingle.scons")
#-------------------------------------------------------------------------------
# Build environments
#
# The list of build environments.
envs = []
# The root of all builds.
root_env = Environment(
tools = [
'component_bits',
'component_setup',
'replace_strings',
'talk_noops',
#'talk_utils',
],
BUILD_SCONSCRIPTS = components,
DESTINATION_ROOT = '$MAIN_DIR/build',
CPPPATH = [
'$OBJ_ROOT', # generated headers are relative to here
'$MAIN_DIR/..', # TODO: how can we use GOOGLECLIENT instead?
],
CPPDEFINES = [
# Temp flag while porting to hammer.
'HAMMER_TIME=1',
'LOGGING=1',
# Feature selection
'FEATURE_ENABLE_SSL',
'FEATURE_ENABLE_VOICEMAIL',
'FEATURE_ENABLE_PSTN',
'HAVE_SRTP',
],
# Ensure the os environment is captured for any scripts we call out to
ENV = os.environ,
)
# This is where we set common environments
#
# Detect if building on 64-bit or 32-bit platform.
DeclareBit('build_platform_64bit', 'Platform of the build machine is 64-bit')
if platform.architecture()[0] == "64bit":
root_env.SetBits('build_platform_64bit')
# This bit denotes that an env is for 64-bit builds. When set, all build
# artifacts will be 64-bit. When unset, all build artifacts will be 32-bit.
DeclareBit('host_platform_64bit', 'Platform of the host machine (where artifacts will execute) is 64-bit')
def CrossBuilding(env):
return env.Bit('host_platform_64bit') != env.Bit('build_platform_64bit')
root_env.AddMethod(CrossBuilding)
DeclareBit('use_static_openssl', 'Build OpenSSL as a static library')
DeclareBit('have_dbus_glib',
'Whether the build system has the dbus-glib-1 package')
DeclareBit('have_libpulse',
'Whether the build system has the libpulse package')
# List all the locales we localize to.
root_env.AppendUnique(locales = [
'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en', 'en-GB', 'es',
'es-419', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'hi', 'hr', 'hu', 'id',
'is', 'it', 'iw', 'ja', 'kn', 'ko', 'lt', 'lv', 'ml', 'mr', 'ms', 'nl',
'no', 'or', 'pl', 'pt-BR', 'pt-PT', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv',
'ta', 'te', 'th', 'tl', 'tr', 'uk', 'ur', 'vi', 'zh-CN', 'zh-TW'])
#-------------------------------------------------------------------------------
# W I N D O W S
#
win_env = root_env.Clone(
tools = [
'atlmfc_vc80',
#'code_signing',
'component_targets_msvs',
'directx_9_0_c',
#'grid_builder',
'midl',
'target_platform_windows'
],
# Don't use default vc80 midl.exe. It doesn't understand vista_sdk idl files.
MIDL = '$PLATFORM_SDK_VISTA_6_0_DIR/Bin/midl.exe ',
WIX_DIR = '$GOOGLECLIENT/third_party/wix/v3_0_2925/files',
# Flags for debug and optimization are added to CCFLAGS instead
CCPDBFLAGS = '',
CCFLAGS_DEBUG = '',
CCFLAGS_OPTIMIZED = '',
# We force a x86 target even when building on x64 Windows platforms.
TARGET_ARCH = 'x86',
)
win_env.Append(
COMPONENT_LIBRARY_PUBLISH = True, # Put dlls in output dir too
CCFLAGS = [
'/Fd${TARGET}.pdb', # pdb per object allows --jobs=
'/WX', # warnings are errors
'/Zc:forScope', # handle 'for (int i = 0 ...)' right
'/EHs-c-', # disable C++ EH
'/GR-', # disable RTTI
'/Gy', # enable function level linking
'/wd4996', # ignore POSIX deprecated warnings
# promote certain level 4 warnings
'/w14701', # potentially uninitialized var
'/w14702', # unreachable code
'/w14706', # assignment within a conditional
'/w14709', # comma operator within array index
'/w14063', # case 'identifier' is not a valid value for switch of enum
'/w14064', # switch of incomplete enum 'enumeration'
'/w14057', # 'identifier1' indirection to slightly different base
# types from 'identifier2'
'/w14263', # member function does not override any base class virtual
# member function
'/w14266', # no override available for virtual memberfunction from base
# 'type'; function is hidden
'/w14296', # expression is always false
'/w14355', # 'this' : used in base member initializer list
],
CPPDEFINES = [
'_ATL_CSTRING_EXPLICIT_CONSTRUCTORS',
# TODO: encapsulate all string operations that are not based
# on std::string/std::wstring and make sure we use the safest versions
# available on all platforms.
'_CRT_SECURE_NO_WARNINGS',
'_SCL_SECURE_NO_WARNINGS',
'_USE_32BIT_TIME_T',
'_UNICODE',
'UNICODE',
'_HAS_EXCEPTIONS=0',
'WIN32',
# TODO: remove this from logging.cc and enable here instead.
#'WIN32_LEAN_AND_MEAN',
'WINVER=0x0500',
'_WIN32_WINNT=0x0501',
'_WIN32_IE=0x0501',
# The Vista platform SDK 6.0 needs at least
# this NTDDI version or else the headers
# that LMI includes from it won't compile.
'NTDDI_VERSION=NTDDI_WINXP',
# npapi.h requires the following:
'_WINDOWS',
],
CPPPATH = [
'$THIRD_PARTY/wtl_71/include',
'$PLATFORM_SDK_VISTA_6_0_DIR/Include',
],
LIBPATH = [
'$PLATFORM_SDK_VISTA_6_0_DIR/Lib'
],
LINKFLAGS = [
'-manifest' # TODO: Why do we need this?
],
MIDLFLAGS = [
'/win32',
'/I$PLATFORM_SDK_VISTA_6_0_DIR/include'
]
)
# TODO: Figure out what this does; found it in
# omaha/main.scons. This fixes the problem with redefinition
# of OS_WINDOWS symbol.
win_env.FilterOut(CPPDEFINES = ['OS_WINDOWS=OS_WINDOWS'])
# Set up digital signing
DeclareBit('test_signing', 'Sign binaries with the test certificate')
win_env.SetBitFromOption('test_signing', False)
if win_env.Bit('test_signing'):
win_env.Replace(
CERTIFICATE_PATH = win_env.File(
'$GOOGLECLIENT/tools/test_key/testkey.pfx').abspath,
CERTIFICATE_PASSWORD = 'test',
)
AddTargetGroup('signed_binaries', 'digitally signed binaries can be built')
win_dbg_env = win_env.Clone(
BUILD_TYPE = 'dbg',
BUILD_TYPE_DESCRIPTION = 'Windows debug build',
BUILD_GROUPS = ['default', 'all'],
tools = ['target_debug'],
)
win_dbg_env.Prepend(
CCFLAGS = [
'/ZI', # enable debugging
'/Od', # disable optimizations
'/MTd', # link with LIBCMTD.LIB debug lib
'/RTC1', # enable runtime checks
],
)
envs.append(win_dbg_env)
win_coverage_env = win_dbg_env.Clone(
tools = ['code_coverage'],
BUILD_TYPE = 'coverage',
BUILD_TYPE_DESCRIPTION = 'Windows code coverage build',
BUILD_GROUPS = ['all'],
)
win_coverage_env.Append(
CPPDEFINES = [
'COVERAGE_ENABLED',
],
)
envs.append(win_coverage_env)
win_opt_env = win_env.Clone(
BUILD_TYPE = 'opt',
BUILD_TYPE_DESCRIPTION = 'Windows opt build',
BUILD_GROUPS = ['all'],
tools = ['target_optimized'],
)
win_opt_env.Prepend(
CCFLAGS=[
'/Zi', # enable debugging
'/O1', # optimize for size
'/MT', # link with LIBCMT.LIB (multi-threaded, static linked crt)
'/GS', # enable security checks
],
LINKFLAGS = [
'/safeseh', # protect against attacks against exception handlers
'/opt:ref', # Remove unused references (functions/data).
],
)
envs.append(win_opt_env)
#-------------------------------------------------------------------------------
# P O S I X
#
posix_env = root_env.Clone()
posix_env.Append(
CPPDEFINES = [
'HASHNAMESPACE=__gnu_cxx',
'HASH_NAMESPACE=__gnu_cxx',
'POSIX',
'DISABLE_DYNAMIC_CAST',
'HAVE_OPENSSL_SSL_H=1',
# The POSIX standard says we have to define this.
'_REENTRANT',
],
CCFLAGS = [
'-Wall',
'-Werror',
'-Wno-switch',
'-fno-exceptions',
# Needed for a clean ABI and for link-time dead-code removal to work
# properly.
'-fvisibility=hidden',
# Generate debugging info in the DWARF2 format.
'-gdwarf-2',
# Generate maximal debugging information. (It is stripped from what we ship
# to users, so we want it for both dbg and opt.)
# Note that hammer automatically supplies "-g" for mac/linux dbg, so that
# flag must be filtered out of linux_dbg and mac_dbg envs below.
'-g3',
],
CXXFLAGS = [
'-Wno-non-virtual-dtor',
'-Wno-ctor-dtor-privacy',
'-fno-rtti',
],
)
#-------------------------------------------------------------------------------
# M A C OSX
#
mac_env = posix_env.Clone(
tools = [
'target_platform_mac',
#'talk_mac',
#'fill_plist',
],
)
mac_env.Append(
CPPDEFINES = [
'OSX',
],
CCFLAGS = [
'-m32',
'-arch', 'i386',
'-isysroot', '/Developer/SDKs/MacOSX10.5.sdk',
'-fasm-blocks',
],
LINKFLAGS = [
'-Wl,-search_paths_first',
# This flag makes all members of a static library be included in the
# final exe - that increases the size of the exe, but without it
# Obj-C categories aren't properly included in the exe.
# TODO: consider only defining for libs that actually have objc.
'-ObjC',
'-arch', 'i386',
'-mmacosx-version-min=10.5',
'-isysroot', '/Developer/SDKs/MacOSX10.5.sdk',
'-m32',
'-dead_strip',
],
FRAMEWORKS = [
'CoreServices',
'Carbon',
'Security',
'SystemConfiguration',
'OpenGL',
'CoreAudio',
'Quartz',
'QuickTime',
'Cocoa',
'QTKit',
]
)
mac_dbg_env = mac_env.Clone(
BUILD_TYPE = 'dbg',
BUILD_TYPE_DESCRIPTION = 'Mac debug build',
BUILD_GROUPS = ['default', 'all'],
tools = ['target_debug'],
)
mac_dbg_env.Append(
CCFLAGS = [
'-O0',
],
CPPDEFINES = [
'DEBUG=1',
],
)
# Remove -g set by hammer, which is not what we want (we have set -g3 above).
mac_dbg_env.FilterOut(CCFLAGS = ['-g'])
envs.append(mac_dbg_env)
mac_opt_env = mac_env.Clone(
BUILD_TYPE = 'opt',
BUILD_TYPE_DESCRIPTION = 'Mac opt build',
BUILD_GROUPS = ['all'],
tools = ['target_optimized'],
)
mac_opt_env.Append(
CCFLAGS = [
# TODO: Figure out how mk can compile without
# this flag, then remove. Confirmed asserts are preprocessed
# out. Maybe it's a different version of gcc?
'-Wno-unused-variable',
],
# Hammer automatically specifies -Os for mac opt.
)
envs.append(mac_opt_env)
#-------------------------------------------------------------------------------
# L I N U X
#
linux_common_env = posix_env.Clone(
tools = [
'target_platform_linux',
'talk_linux',
],
)
linux_common_env.Append(
CPPDEFINES = [
'LINUX',
],
CCFLAGS = [
# Needed for link-time dead-code removal to work properly.
'-ffunction-sections',
'-fdata-sections',
],
LINKFLAGS = [
# Enable dead-code removal.
'-Wl,--gc-sections',
# Elide dependencies on shared libraries that we're not actually using.
'-Wl,--as-needed',
'-Wl,--start-group',
],
_LIBFLAGS = ['-Wl,--end-group'],
)
# Remove default rpath set by Hammer. Hammer sets it to LIB_DIR, which is wrong.
# The rpath is the _run-time_ library search path for the resulting binary, i.e.
# the one used by ld.so at load time. Setting it equal to the path to build
# output on the build machine is nonsense.
linux_common_env.Replace(
RPATH = [],
)
# Enable the optional DBus-GLib code if the build machine has the required
# dependency.
linux_common_env.EnableFeatureWherePackagePresent('have_dbus_glib',
'HAVE_DBUS_GLIB',
'dbus-glib-1')
def linux_common_include_x86_32(env):
"""Include x86-32 settings into an env based on linux_common."""
env.Append(
CCFLAGS = [
'-m32',
],
LINKFLAGS = [
'-m32',
],
)
def linux_common_include_x86_64(env):
"""Include x86-64 settings into an env based on linux_common."""
env.Append(
CCFLAGS = [
'-m64',
'-fPIC',
],
LINKFLAGS = [
'-m64',
],
)
env.SetBits('host_platform_64bit')
#-------------------------------------------------------------------------------
# L I N U X -- T R A D I T I O N A L -- X 8 6
#
# Settings that are specific to our desktop Linux x86 targets.
linux_x86_32_env = linux_common_env.Clone()
linux_common_include_x86_32(linux_x86_32_env)
linux_x86_64_env = linux_common_env.Clone()
linux_common_include_x86_64(linux_x86_64_env)
def gen_linux_x86(base_env, type_suffix, desc_suffix):
linux_env = base_env.Clone()
# OpenSSL has infamously poor ABI stability, so that building against one
# version and running against a different one often will not work. Since our
# non-ChromeOS Linux builds are used on many different distros and distro
# versions, this means we can't safely dynamically link to OpenSSL because the
# product would end up being broken on any computer with a different version
# installed. So instead we build it ourself and statically link to it.
linux_env.SetBits('use_static_openssl')
# Enable the optional PulseAudio code if the build machine has the required
# dependency. (Not doing this for linux_common_env because we don't want
# PulseAudio used on ChromeOS.)
linux_env.EnableFeatureWherePackagePresent('have_libpulse',
'HAVE_LIBPULSE',
'libpulse')
groups = ['all']
if not linux_env.CrossBuilding():
groups = groups + ['all-native']
# The native-arch dbg build is the default.
dbg_groups = groups + ['default']
native_desc = ', native '
# No suffix for native modes.
type_suffix = ''
else:
groups = groups + ['all-cross']
dbg_groups = groups
native_desc = ', cross-built for '
linux_dbg_env = linux_env.Clone(
BUILD_TYPE = 'dbg' + type_suffix,
BUILD_TYPE_DESCRIPTION = 'Linux debug build%s%s' % (native_desc,
desc_suffix),
BUILD_GROUPS = dbg_groups,
tools = ['target_debug'],
)
# Remove -g set by hammer, which is not what we want (we have set -g3 above).
linux_dbg_env.FilterOut(CCFLAGS = ['-g'])
envs.append(linux_dbg_env)
linux_opt_env = linux_env.Clone(
BUILD_TYPE = 'opt' + type_suffix,
BUILD_TYPE_DESCRIPTION = 'Linux optimized build%s%s' % (native_desc,
desc_suffix),
BUILD_GROUPS = groups,
tools = ['target_optimized'],
)
# Remove -O2 set by hammer, which is not what we want.
linux_opt_env.FilterOut(CCFLAGS = ['-O2'])
linux_opt_env.Append(CCFLAGS = ['-Os'])
envs.append(linux_opt_env)
gen_linux_x86(linux_x86_32_env, '32', '32-bit')
gen_linux_x86(linux_x86_64_env, '64', '64-bit')
#-------------------------------------------------------------------------------
# L I N U X -- C R O S S -- B U I L D
# Cross build requires the following tool names be provided by the environment:
linux_cross_common_env = linux_common_env.Clone(
AR = os.environ.get("AR"),
AS = os.environ.get("AS"),
LD = os.environ.get("LD"),
NM = os.environ.get("NM"),
RANLIB = os.environ.get("RANLIB"),
CC = str(os.environ.get("CC")) +
' --sysroot=' + str(os.environ.get("SYSROOT")),
CXX = str(os.environ.get("CXX")) +
' --sysroot=' + str(os.environ.get("SYSROOT")),
)
# The rest of these paths and flags are optional:
if os.environ.get("CPPPATH"):
linux_cross_common_env.Append(
CPPPATH = os.environ.get("CPPPATH").split(':'),
)
if os.environ.get("LIBPATH"):
linux_cross_common_env.Append(
LIBPATH = os.environ.get("LIBPATH").split(':'),
)
if os.environ.get("CFLAGS"):
linux_cross_common_env.Append(
CFLAGS = os.environ.get("CFLAGS").split(' '),
)
if os.environ.get("CCFLAGS"):
linux_cross_common_env.Append(
CCFLAGS = os.environ.get("CCFLAGS").split(' '),
)
if os.environ.get("CXXFLAGS"):
linux_cross_common_env.Append(
CXXFLAGS = os.environ.get("CXXFLAGS").split(' '),
)
if os.environ.get("LIBFLAGS"):
linux_cross_common_env.Append(
_LIBFLAGS = os.environ.get("LIBFLAGS").split(' '),
)
#-------------------------------------------------------------------------------
# L I N U X -- C R O S S -- B U I L D -- A R M
linux_cross_arm_env = linux_cross_common_env.Clone()
linux_cross_arm_env.Append(
CPPDEFINES = [
'NACL_BUILD_ARCH=arm',
'DISABLE_EFFECTS=1',
],
CCFLAGS = [
'-fPIC',
],
)
DeclareBit('arm', 'ARM build')
linux_cross_arm_env.SetBits('arm')
# Detect NEON support from the -mfpu build flag.
DeclareBit('arm_neon', 'ARM supporting neon')
if '-mfpu=neon' in linux_cross_arm_env['CFLAGS'] or \
'-mfpu=neon' in linux_cross_arm_env['CCFLAGS'] or \
'-mfpu=neon' in linux_cross_arm_env['CXXFLAGS']:
print "Building with ARM NEON support."
linux_cross_arm_env.SetBits('arm_neon')
linux_cross_arm_dbg_env = linux_cross_arm_env.Clone(
BUILD_TYPE = 'arm-dbg',
BUILD_TYPE_DESCRIPTION = 'Cross-compiled ARM debug build',
BUILD_GROUPS = ['arm'],
tools = ['target_debug'],
)
envs.append(linux_cross_arm_dbg_env)
linux_cross_arm_opt_env = linux_cross_arm_env.Clone(
BUILD_TYPE = 'arm-opt',
BUILD_TYPE_DESCRIPTION = 'Cross-compiled ARM optimized build',
BUILD_GROUPS = ['arm'],
tools = ['target_optimized'],
)
envs.append(linux_cross_arm_opt_env)
# TODO(): Clone linux envs for 64bit. See 'variant' documentation.
# Create a group for installers
AddTargetGroup('all_installers', 'installers that can be built')
# Parse child .scons files
BuildEnvironments(envs)
# Explicitly set which targets to build when not stated on commandline
Default(None)
# Build the following, which excludes unit test output (ie running them)
# To run unittests, specify the test to run, or run_all_tests. See -h option.
Default(['all_libraries', 'all_programs', 'all_test_programs'])
# .sln creation code lifted from googleclient/bar/main.scons. Must be after
# the call to BuildEnvironments for all_foo aliases to be defined.
# Run 'hammer --mode=all --vsproj' to generate
DeclareBit('vsproj', 'Generate Visual Studio projects and solution files.')
win_env.SetBitFromOption('vsproj', False)
if win_env.Bit('vsproj'):
vs_env = win_env.Clone()
vs_env.Append(
COMPONENT_VS_SOURCE_SUFFIXES = [
'.def',
'.grd',
'.html',
'.idl',
'.mk',
'.txt',
'.py',
'.scons',
'.wxs.template',
]
)
# Source project
p = vs_env.ComponentVSDirProject(
'flute_source',
['$MAIN_DIR',
],
COMPONENT_VS_SOURCE_FOLDERS = [
# Files are assigned to first matching folder. Folder names of None
# are filters.
(None, '$DESTINATION_ROOT'),
('flute', '$MAIN_DIR'),
('google3', '$GOOGLE3'),
('third_party', '$THIRD_PARTY'),
],
# Force source project to main dir, so that Visual Studio can find the
# source files corresponding to build errors.
COMPONENT_VS_PROJECT_DIR = '$MAIN_DIR',
)
vs_env.AlwaysBuild(p)
# Solution and target projects
s = vs_env.ComponentVSSolution(
# 'libjingle', # Please uncomment this line if you build VS proj files.
['all_libraries', 'all_programs', 'all_test_programs'],
projects = [p],
)
print '***Unfortunately the vsproj creator isn\'t smart enough to '
print '***automatically get the correct output locations. It is very easy'
print '***though to change it in the properties pane to the following'
print '***$(SolutionDir)/build/<foo>/staging/<bar>.exe'
Default(None)
Default([s])