| #!/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]) |