blob: f12eafead8458028e42b2ee9829049a79c70a5ca [file] [log] [blame]
#!/usr/bin/python2.4
#
# Copyright 2009-2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========================================================================
# This main.scons file is the root description of the build specified in this
# directory and those under it. Individual components and the source files
# used to build them are described in subsidiary files called 'build.scons'.
#
# To build this project change the current directory to googleclient/Omaha.
# Then run hammer.bat
#
# A number of command line options can be specified. For a full list, use the
# -h and -H command options.
#
# Some useful options include:
# -h : Prints a list of which modules and build variants are available
# in this project.
# -H : Print SCons specific help. SCons is a build tool which this
# project uses in tandem with the Software Construction Toolkit
# to build.
# -c : Clean the project. I.e. delete all build output.
# -j3 : Run up to 3 build steps at once.
#
# Some useful build targets include:
# all_programs : Build all programs generated by this project.
# all_libraries : Build all libraries generated by this project.
# all_tests : Build all tests generated by this project.
# run_all_tests : Build and run all tests generated by this project.
#
# Some examples:
# Build all programs and libraries in debug mode:
# hammer
# Build and run all tests in debug mode on windows:
# hammer MODE=dbg-win run_all_tests
# Build arbitrary library in the default mode:
# hammer <library name>
import os
# To switch the build, simply change the value of the msc_ver variable below.
# VC2003/VC71 is 1310 but not supported by the current build.
# VC2005/VC80 is 1400.
# VC2008/VC90 is 1500.
_msc_ver = 1400
# TODO(Omaha) - Change this to match the official product name
_PUBLISHER_NAME = 'Google'
_PRODUCT_NAME = 'Update'
_ACTIVEX_NAME = 'npGoogleOneClick'
_BHO_NAME = 'GoopdateBho'
# The hash comes from the Thumbprint item in the Details tab of the file
# properties for the public key .cer file.
# TODO(omaha): Can we automate reading this and/or pass it on the command line?
_BUILD_SERVER_CERTIFICATE_HASH = 'fe5008fe0da7a2033816752d6eafe95214f5a7e1'
# COM proxy setting.
# The proxy clsid needs to be changed anytime the interfaces in
# google_update_idl.idl change, or when a new interface is added. Use
# guidgen.exe to generate new clsids in the format 'static const struct GUID'.
# PROXY_CLSID_IS = {29A96789-9595-4947-BEDB-0FCC776F7DB8}
_PROXY_CLSID_IS = ('{0x29a96789, 0x9595, 0x4947, '
'{0xbe, 0xdb, 0xf, 0xcc, 0x77, 0x6f, 0x7d, 0xb8}}')
#
# Set up version info
#
execfile('VERSION')
# Windows is the only environment we bulid for, so create a specialized base
# environment for Windows.
win_env = Environment()
# Make sure we use the Vista SDK.
# NOTE: This must be set before the 'component_setup' tool is used.
win_env['PLATFORM_SDK_DIR'] = '$PLATFORM_SDK_VISTA_6_0_DIR'
win_env.Tool('component_setup')
win_env.Tool('target_platform_windows')
# Need to use 'masm' to override the 'as' tool currently used
# by default in 'target_platform_windows'
win_env.Tool('masm')
win_env.Tool('atlmfc_vc80')
# Visual Studio 2008 does not ship the sign tool. Use the sign tool from
# the Platform SDK.
win_env.Tool('code_signing')
_signtool_path = os.path.join(os.environ['OMAHA_VISTASDK_DIR'],
'bin\\signtool.exe')
win_env['SIGNTOOL'] = '"' + _signtool_path + '"'
# Remove this value because it conflicts with a #define
# in shlwapi.h in the Vista SDK
win_env.FilterOut(CPPDEFINES = ['OS_WINDOWS=OS_WINDOWS'])
win_env.Tool('component_targets_msvs')
# We pre-generate our own manifests, so make sure hammer does not generate
# default ones for us
del win_env['MANIFEST_FILE']
# Hack to work around bug in Hammer (http://b/1585388).
# TODO(Omaha): Remove when bug is fixed.
if win_env['ENV'].has_key('SYSTEMROOT'):
if win_env['ENV'].has_key('SystemRoot'):
del win_env['ENV']['SYSTEMROOT']
del os.environ['SYSTEMROOT']
# Work around http://code.google.com/p/swtoolkit/issues/detail?id=10.
win_env['COMPONENT_TEST_SUBSYSTEM_WINDOWS'] = 1
# Declare command line options relating to code signing
# authenticode_file and authenticode_password are used by the normal signing
# tool and to sign manifests for ClickOnce.
# patching_certificate is used to create patchable MSI installers and MSPs.
# authenticode_file and authenticode_password are only used if !build_server.
# patching_certificate is used in all cases.
AddOption(
'--authenticode_file',
action='store',
nargs=1,
type='string',
default='$MAIN_DIR/data/OmahaTestCert.pfx'
)
default_cert_password = 'test'
AddOption(
'--authenticode_password',
action='store',
nargs=1,
type='string',
default=default_cert_password
)
AddOption(
'--patching_certificate',
action='store',
nargs=1,
type='string',
default='$MAIN_DIR/data/OmahaTestCert.cer'
)
# Declare option for specifying path to new official build files
AddOption(
'--official_build_path',
action='store',
nargs=1,
type='string',
default=None
)
# Declare various boolean states.
DeclareBit('use_precompiled_headers', 'Use precompiled headers in build')
DeclareBit('official_installers', 'Building using checked-in binaries')
DeclareBit('build_server', 'Running on the build server')
DeclareBit('test_certificate', 'Files will be signed with the test certificate')
DeclareBit('bin', 'Building from pre-built binaries')
DeclareBit('min', 'Building minimal set of projects')
DeclareBit('all', 'Building all Projects')
DeclareBit('msvs', 'Building Visual Studio solution files')
# Build official installers if --official_installers is on the command line.
win_env.SetBitFromOption('official_installers', False)
# Build as a build server if --build_server is on the command line.
win_env.SetBitFromOption('build_server', False)
# Store new versions of pre-built binaries if --bin is on the command line.
win_env.SetBitFromOption('bin', False)
# Build minimal set of libs if --min is on the command line.
win_env.SetBitFromOption('min', False)
# Build all libs if --all is on the command line.
win_env.SetBitFromOption('all', False)
# Build Visual Studio solution files if --msvs is on the command line.
win_env.SetBitFromOption('msvs', False)
# Also build all directories if this is the build server.
if win_env.Bit('build_server'):
win_env.SetBits('all')
# Make sure 'all' overrides 'min'.
if win_env.Bit('all'):
win_env.ClearBits('min')
# Allow use of command-line-specified certificates to sign with, but
# only if we're not on the build server.
if not win_env.Bit('build_server'):
win_env.Replace(
CERTIFICATE_PATH=GetOption('authenticode_file'),
CERTIFICATE_PASSWORD=GetOption('authenticode_password'),
)
# Store whether we're using the default test cert separately, because
# we won't always know what the default password was.
if GetOption('authenticode_password') is default_cert_password:
win_env.SetBits('test_certificate')
# The precompiled headers are to be used as an optional build speed up
# build facility. Individual compilation units in the project must build with
# or without precompiled headers. Building without precompiled headers is sort
# of meaningless, since all the time we should build with it. However,
# eliminating the dependency is desirable from a few reasons:
# 1. making sure the files in the project include all the definitions they need
# 2. creating different precompile headers if needed.
# 3. making sure the precompile headers do not add to the size bloat.
# There are two current limitations with the current setup.
# First, due to pushing the warning level to W4 and WAll, we rely on the
# common precompile.h to properly turn off the warnings inside system and
# library code.
# Second, to override the ATLASSERT, a file must be included before any of
# the atl headers. To do this on a case by case basis is impractical and
# error prone.
# Therefore, when building with precompile headers off, the code is
# building on W3 and it is not taking over the ATL asserts.
win_env.SetBitFromOption('use_precompiled_headers', True)
if win_env.Bit('use_precompiled_headers'):
print 'Using precompiled headers.'
def _EnablePrecompile(self_env, target_name):
if self_env.Bit('use_precompiled_headers'):
# We enable all warnings on all levels. The goal is to fix the code that
# we have written and to programmatically disable the warnings for the
# code we do not control. This list of warnings should shrink as the code
# gets fixed.
self_env.FilterOut(CCFLAGS=['/W3'])
self_env.Append(
CCFLAGS = [
'/W4',
'/Wall',
],
INCLUDES = [
'$MAIN_DIR/precompile/precompile.h'
],
)
self_env['PCHSTOP'] = '$MAIN_DIR/precompile/precompile.h'
pch_env = self_env.Clone()
# Must manually force-include the header, as the precompilation step does
# not evaluate $INCLUDES
pch_env.Append(CCFLAGS = ['/FI$MAIN_DIR/precompile/precompile.h'])
# Append '_pch' to the target base name to prevent target name collisions.
# One case where this might have occurred is when a .cc file has the same
# base name as the target program/library.
pch_output = pch_env.PCH(
target=target_name.replace('.', '_') + '_pch' + '.pch',
source='$MAIN_DIR/precompile/precompile.cc',
)
self_env['PCH'] = pch_output[0]
# Return the pch .obj file that is created, so it can be
# included with the inputs of a module
return [pch_output[1]]
win_env.AddMethod(_EnablePrecompile, 'EnablePrecompile')
def _SignDotNetManifest(self_env, target, unsigned_manifest):
sign_manifest_cmd =('@mage -Sign $SOURCE -ToFile $TARGET -TimestampUri '
'http://timestamp.verisign.com/scripts/timstamp.dll ')
if self_env.Bit('build_server'):
# If signing fails with the following error, the hash may not match any
# certificates: "Internal error, please try again. Object reference not set
# to an instance of an object."
sign_manifest_cmd += ('-CertHash ' +
self_env['build_server_certificate_hash'])
else:
sign_manifest_cmd += '-CertFile %s -Password %s' % (
GetOption('authenticode_file'), GetOption('authenticode_password'))
signed_manifest = self_env.Command(
target=target,
source=unsigned_manifest,
action=sign_manifest_cmd
)
return signed_manifest
win_env.AddMethod(_SignDotNetManifest, 'SignDotNetManifest')
def _SetProductVersion(self_env,
version_major,
version_minor,
version_build,
version_patch):
build_two_versions = False
if (self_env.Bit('build_server') or
'OMAHA_BUILD_TWO_VERSIONS' in os.environ.keys()):
build_two_versions = True
if build_two_versions:
self_env['product_version_series'] = [0, 1]
else:
self_env['product_version_series'] = [0]
if version_patch > 0:
original_value = version_patch
value_name = 'patch'
else:
original_value = version_build
value_name = 'build'
if 2 * (original_value / 2) == original_value:
raise Exception('ERROR: By convention, the %s number in VERSION '
'(currently %d) should be odd.' % (value_name, original_value))
ver_descriptions = []
versions = []
for delta in self_env['product_version_series']:
# If we're doing a patch, increment that; else, increment build
vp = version_patch
vb = version_build
if vp > 0:
vp = vp + delta
else:
vb = vb + delta
v = (version_major, version_minor, vb, vp)
versions.append(v)
ver_descriptions.append('%d.%d.%d.%d' %
(version_major, version_minor, vb, vp))
self_env['product_version'] = versions
# print the version string so we know what build are we building on the
# build server
print 'Working on versions: %s' % ', '.join(ver_descriptions)
win_env.AddMethod(_SetProductVersion, 'SetProductVersion')
win_env.SetProductVersion(version_major, version_minor, version_build, version_patch)
win_env['msc_ver'] = _msc_ver;
win_env['build_server_certificate_hash'] = _BUILD_SERVER_CERTIFICATE_HASH
# Plug-in versioning. Firefox Plug-in needs a different filename for each
# version of the plug-in. If the filename is the same, even though the path
# is different, Firefox decides not to load the new DLL if it has the old DLL
# loaded in memory.
def _SetActiveXFilenames(self_env, activex_version):
activex_name = _ACTIVEX_NAME + activex_version
self_env['ACTIVEX_FILENAME'] = activex_name + '.dll'
self_env['ACTIVEX_UNSIGNED_FILENAME'] = activex_name + '_unsigned.dll'
win_env.AddMethod(_SetActiveXFilenames, 'SetActiveXFilenames')
win_env.SetActiveXFilenames(oneclick_plugin_version)
# BHO settings.
win_env['BHO_FILENAME'] = '%s.dll' % (_BHO_NAME)
win_env['BHO_UNSIGNED_FILENAME'] = '%s_unsigned.dll' % (_BHO_NAME)
win_env.Append(
# Add windows specific compiler flags.
CCFLAGS = [
'/nologo',
'/c',
'/Zc:forScope',
'/D_HAS_EXCEPTIONS=0',
'/DCOMPILER_MSVC',
'/J',
'/DSTL_MSVC',
'/GR-',
'/D_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES=1',
'/D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1',
'/D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1',
'/WX', # warnings as errors
#
# Disable the following level 4 warnings below.
#
'/wd4127', # conditional expression is constant
'/wd4189', # local variable is initialized but not referenced
'/wd4505', # unreferenced local function has been removed
#
# Disable the pedantic warnings below.
#
'/wd4191', # unsafe conversion from 'type of expression' to
# 'type required'
'/wd4217', # member template functions cannot be used for
# copy-assignment...
'/wd4365', # conversion from 'type_1' to 'type_2',
# signed/unsigned mismatch
'/wd4512', # assignment operator could not be generated
'/wd4514', # unreferenced inline function has been removed
'/wd4555', # expression has no effect
'/wd4619', # #pragma warning : there is no warning number 'number'
'/wd4623', # default constructor could not be generated...
'/wd4625', # copy constructor could not be generated...
'/wd4626', # assignment operator could not be generated...
'/wd4668', # not defined as a preprocessor macro, replacing with '0'.
'/wd4710', # function not inlined
'/wd4711', # function 'function' selected for inline expansion
'/wd4738', # storing 32-bit float result in memory...
'/wd4820', # bytes padding added after construct 'member_name'
],
# Where to look for include files.
CPPPATH = [
'$MAIN_DIR',
'$MAIN_DIR/..',
'$MAIN_DIR/third_party/chrome',
],
# Defines for windows environment.
CPPDEFINES = [
'WIN32', '_WINDOWS',
'UNICODE', '_UNICODE',
'WIN32_LEAN_AND_MEAN',
'STRICT',
'SECURITY_WIN32',
'_ATL_ALL_WARNINGS',
'_ATL_CSTRING_EXPLICIT_CONSTRUCTORS',
'_ATL_CSTRING_NO_CRT',
'_ATL_NO_ACLAPI',
'_ATL_NO_DEFAULT_LIBS',
'_ATL_NO_EXCEPTIONS',
'_ATL_NO_GLOBAL_SOCKET_STARTUP',
'_ATL_NO_PERF_SUPPORT',
'_ATL_NO_TRACK_HEAP',
'_ATL_NO_UUIDOF',
'_CRT_RAND_S', # rand_s support available in Windows XP only.
'_WTL_NO_CSTRING', # WTL uses ATL CString instead.
# '_ATL_NO_CONNECTION_POINTS',
# '_ATL_NO_DOCHOSTUIHANDLER',
# '_ATL_NO_HOSTING',
# Set these C_DEFINES when APPVER=5.0
# (see win32.mak in Platform SDK)
# Target Windows XP and IE 6.0 and above.
'WINVER=0x0501',
'_WIN32_WINNT=0x0501',
'_WIN32_IE=0x0600',
'_RICHEDIT_VER=0x0010',
# don't define min and max in windef.h
'NOMINMAX',
# Logging is enabled in all modes for
# diagnostics purposes.
'LOGGING',
'PUBLISHER_NAME_ANSI=\\"%s\\"' % _PUBLISHER_NAME,
'PRODUCT_NAME_ANSI=\\"%s\\"' % _PRODUCT_NAME,
'ACTIVEX_NAME=_T(\\"%s\\")' % _ACTIVEX_NAME,
'PROXY_CLSID_IS=%s' % _PROXY_CLSID_IS,
'OFFICIAL_BUILD=%d' % win_env.Bit('build_server'),
'TEST_CERTIFICATE=%d' % win_env.Bit('test_certificate'),
'ACTIVEX_FILENAME=_T(\\"%s\\")' % win_env['ACTIVEX_FILENAME'],
'ACTIVEX_VERSION_ANSI=\\"%s\\"' % oneclick_plugin_version,
'BHO_NAME=_T(\\"%s\\")' % _BHO_NAME,
'BHO_FILENAME=_T(\\"%s\\")' % win_env['BHO_FILENAME'],
],
# Link in some windows libraries.
LIBS = [
'advapi32',
'comdlg32',
'gdi32',
'kernel32',
'odbc32',
'odbccp32',
'ole32',
'oleaut32',
'shell32',
'user32',
'uuid',
'winspool',
],
# Common linker flags.
LINKFLAGS = [
'/nologo',
'/SUBSYSTEM:WINDOWS',
'/MACHINE:X86',
'/RELEASE',
'/MAP',
'/NODEFAULTLIB',
],
# Shared library specific linker flags.
SHLINKFLAGS = [
'/nologo',
'/SUBSYSTEM:WINDOWS',
'/MACHINE:x86',
],
# Resource compiler flags.
RCFLAGS = [
'/l 1033', # /l == default language ID
'/DOFFICIAL_BUILD=%d' % win_env.Bit('build_server'),
'/DPUBLISHER_NAME_ANSI=\\"%s\\"' % _PUBLISHER_NAME,
'/DPRODUCT_NAME_ANSI=\\"%s\\"' % _PRODUCT_NAME,
'/DACTIVEX_NAME=_T(\\"%s\\")' % _ACTIVEX_NAME,
'/DACTIVEX_FILENAME=_T(\\"%s\\")' % win_env['ACTIVEX_FILENAME'],
'/DACTIVEX_VERSION_ANSI=\\"%s\\"' % oneclick_plugin_version,
'/DBHO_NAME=_T(\\"%s\\")' % _BHO_NAME,
'/DBHO_FILENAME=_T(\\"%s\\")' % win_env['BHO_FILENAME'],
],
)
# Allow verification of these settings in the build log.
if win_env.Bit('build_server'):
print 'OFFICIAL_BUILD=1'
print 'TEST_CERTIFICATE=%d' % win_env.Bit('test_certificate')
# List of languages that are fully supported.
win_env['languages'] = [
'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',
'tr',
'uk',
'ur',
'vi',
'zh-CN',
'zh-TW',
]
# The shell and goopdate.dll contain additional languages.
# 'userdefault' addresses apps that don't look up the resource for the OS
# language. See http://b/1328652.
win_env['additional_shell_languages'] = [
'am',
'sw',
'userdefault',
'zh-HK',
]
# Make sure python.exe can be located.
win_env.AppendENVPath('PATH', os.environ['OMAHA_PYTHON_DIR'])
# Make sure Vista SDK in all the important paths earlier in path than VC80.
_sdk_path = os.environ['OMAHA_VISTASDK_DIR']
for mid_dir in ['', 'vc']:
for env_var, sub_dir in [('PATH', 'bin'),
('INCLUDE', 'include'),
('LIB', 'lib')]:
var_path = os.path.join(_sdk_path, mid_dir, sub_dir)
if os.path.exists(var_path):
win_env.PrependENVPath(env_var, var_path)
if not win_env.Bit('official_installers'):
win_env.Append(CPPPATH = os.environ['OMAHA_WTL_DIR'])
# Make sure csc.exe can be located.
win_env.AppendENVPath('PATH', os.environ['OMAHA_NET_DIR'])
# WiX path has to be added before the WiX tool can be called.
win_env.AppendENVPath('PATH', os.environ['OMAHA_WIX_DIR'])
win_env.Tool('wix')
_base_dirs = [
'.', # ./build.scons is used to copy some files to staging.
'common',
'core',
'goopdate',
'google_update',
'mi_exe_stub',
'net',
'recovery',
'service',
'setup',
'statsreport',
'testing',
'third_party',
'tools',
'worker',
]
_normal_dirs = [
'bho',
'clickonce',
'installers',
'plugins',
]
_official_installers_dirs = [
'enterprise',
'installers',
]
_extra_dirs = [
'enterprise',
'standalone',
'test',
]
#
# Need to decide which subdirs need to be built.
#
_dirs_to_build = set()
if win_env.Bit('official_installers'):
# Only want to build very specific subdirs.
_dirs_to_build.update(_official_installers_dirs)
elif not win_env.Bit('bin'):
# All other configs get the base dirs.
_dirs_to_build.update(_base_dirs)
if win_env.Bit('min'):
print '*** Building Minimal Set of Projects ***'
else:
_dirs_to_build.update(_normal_dirs)
if win_env.Bit('all'):
_dirs_to_build.update(_extra_dirs)
# Build Google application-specific metainstallers.
if os.path.exists(win_env.Dir('$MAIN_DIR/internal').abspath):
_dirs_to_build.update(['internal'])
# Instruct Hammer which dirs to build.
win_env['BUILD_SCONSCRIPTS'] = list(_dirs_to_build)
# Create the leaf debug Windows environment.
windows_debug_env = win_env.Clone(
# Give this build a name and a description.
BUILD_TYPE = 'dbg-win',
BUILD_TYPE_DESCRIPTION = 'Windows debug build',
)
# Use common debug settings.
windows_debug_env.Tool('target_debug')
windows_debug_env.Append(
CCFLAGS = [
'/RTC1',
'/Od',
'/MTd',
],
CPPDEFINES = [
'_DEBUG',
'DEBUG',
],
)
# Create the leaf optimized Windows environment.
windows_optimized_env = win_env.Clone(
# Give this build a name and a description.
BUILD_TYPE = 'opt-win',
BUILD_TYPE_DESCRIPTION = 'Windows optimized build',
)
# Use common optimized settings.
windows_optimized_env.Tool('target_optimized')
windows_optimized_env.Append(
CCFLAGS = [
'/O1', # Optimize for small size.
'/GS',
'/FD',
'/GL', # Global optimization goes with link flag '/LTCG'
'/MT',
],
CPPDEFINES = [
'NDEBUG',
'SHIPPING' # code in 'common' needs this
],
ARFLAGS = [
'/LTCG', # Set LTCG for creation of .lib files too.
],
LINKFLAGS = [
'/incremental:no',
'/opt:ref',
'/opt:icf=32',
'/opt:nowin98',
'/LTCG', # Link-time code generation goes with cl flag '/GL'
],
)
# Create an environment for coverage test builds, based on the dbg build.
windows_coverage_env = windows_debug_env.Clone(
BUILD_TYPE = 'coverage-win',
BUILD_TYPE_DESCRIPTION = 'Windows coverage build',
)
# The Coverage build require additional tools that not everyone has. Therefore,
# it should build as part of the all group.
windows_coverage_env.FilterOut(BUILD_GROUPS=['all'])
windows_coverage_env.Tool('code_coverage')
# Coverage will run omaha_unittest.exe, which requires some extra environment.
for env_var in os.environ:
if not env_var in windows_coverage_env['ENV']:
windows_coverage_env['ENV'][env_var] = os.environ[env_var]
# Create a target that covers everything in the staging dir, as many of those
# files will be required for the unittests to run successfully.
windows_coverage_env.Alias(
'run_omaha_unittest',
'$STAGING_DIR',
'$STAGING_DIR/omaha_unittest.exe'
)
windows_coverage_env.Append(
# TODO(omaha): We cannot run our unit tests on the new build system. Ensure
# coverage works with the new test execution system.
# COVERAGE_TARGETS=['run_omaha_unittest'],
COVERAGE_INSTRUMENTATION_PATHS=['$STAGING_DIR'],
# This value should only be used in code if absolutely necessary.
CPPDEFINES=['COVERAGE_ENABLED'],
)
# TODO(omaha): Prevent the analyzer, which will fail, from running until we can
# run unit tests on the build system. See the TODO above.
windows_coverage_env['COVERAGE_START_CMD'] = '@echo Not starting coverage'
windows_coverage_env['COVERAGE_STOP_CMD'] = '@echo Not ending coverage'
# Skip signing in coverage build until the last step.
windows_coverage_env['SIGNTOOL_ORIG'] = windows_coverage_env['SIGNTOOL']
windows_coverage_env['SIGNTOOL'] = '@echo Signing deferred: '
def SigningCommand(env, filename):
# Only do signing if there is a certificate file or certificate name.
if env.subst('$CERTIFICATE_PATH') or env.subst('$CERTIFICATE_NAME'):
# The command used to do signing (target added on below).
signing_cmd = '$SIGNTOOL_ORIG sign '
# Add in certificate file if any.
if env.subst('$CERTIFICATE_PATH'):
signing_cmd += ' /f "$CERTIFICATE_PATH"'
# Add certificate password if any.
if env.subst('$CERTIFICATE_PASSWORD'):
signing_cmd += ' /p "$CERTIFICATE_PASSWORD"'
# Add certificate store if any.
if env.subst('$CERTIFICATE_NAME'):
# The command used to do signing (target added on below).
signing_cmd += ' /s "$CERTIFICATE_STORE" /n "$CERTIFICATE_NAME"'
# Add timestamp server if any.
if env.subst('$TIMESTAMP_SERVER'):
signing_cmd += ' /t "$TIMESTAMP_SERVER"'
# Add in target name
signing_cmd += ' "%s"' % filename
return signing_cmd
else:
return 'echo no signing needed'
def _IsInstrumentableFileType(file):
if (file.endswith('.exe') or
file.endswith('.dll')):
return True
return False
def _IsSignableFileType(file):
if (file.endswith('.exe') or
file.endswith('.dll') or
file.endswith('.msi') or
file.endswith('.msp')):
return True
return False
# Sign files during the install stage, since instrumentation invalidates the
# signature. Signing within the individual build files was disabled above.
# Do not sign intermediate "_unsigned" or "_unittest" files.
# Instrumented files must be signed after installing becuase install is what
# does the instrumentation. This also seems to be required to avoid
# unnecessarily rebuilding non-instrumentable files.
def _PostCoverageSigningInstall(dest, source, env):
if _IsInstrumentableFileType(dest) or not _IsSignableFileType(dest):
# Install the file to staging. Includes instrumentation if appropriate.
env['PRECOVERAGE_SIGN_INSTALL'](dest, source, env)
else:
# For signable but not instrumentable files, copy the files rather than
# using PRECOVERAGE_SIGN_INSTALL as this works around unnecessary rebuilds
# caused by http://code.google.com/p/swtoolkit/issues/detail?id=13.
env.Execute('copy "%s" "%s"' % (source, dest))
if (_IsSignableFileType(dest) and
(-1 == dest.find('_unsigned')) and
(-1 == dest.find('_unittest')) and
os.path.split(os.path.split(dest)[0])[1] == 'staging'):
env.Execute(SigningCommand(env, dest))
windows_coverage_env['PRECOVERAGE_SIGN_INSTALL'] = (
windows_coverage_env['INSTALL'])
windows_coverage_env['INSTALL'] = _PostCoverageSigningInstall
# Make debug the default build after any copies of it have been made.
windows_debug_env.Append(BUILD_GROUPS = ['default'])
# ----------------------------------------------------------
# Build the variants listed above.
# This step will call each of the SConscripts (build.scons) listed,
# once for each variant currently being built.
BuildEnvironments(
[ windows_debug_env,
windows_optimized_env,
windows_coverage_env,
]
)
if win_env.Bit('msvs'):
source_project = win_env.ComponentVSDirProject('all_source', ['$MAIN_DIR'])
# 'all_*' values do not appear to be populated until after BuildEnvironments
# is called. Thus, the solution will be specific to either debug or optimized.
# ComponentVSSourceProject() might be more desirable, but it does not appear
# to work.
windows_debug_env.ComponentVSSolution('omaha_dbg',
['all_programs', 'all_libraries'],
projects=[source_project])