# Copyright 2008, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import shutil import sys #TODO(rspangler): extra imports for testing #from SCons.Script.__init__ import * p = ARGUMENTS.get('PROGRESS') if p == 'spinner': Progress(['/\r', '|\r', '\\\r', '-\r'], interval=5, file=open('con', 'w')) elif p == 'name': Progress('$TARGET\r', overwrite=True, file=open('con', 'w')) SetOption('warn', ['no-missing-sconscript'] + GetOption('warn')) processors = int(os.environ.get('NUMBER_OF_PROCESSORS', 1)) SetOption('num_jobs', processors + 1) env = Environment( BUILD_TYPE = ARGUMENTS.get('BUILD_TYPE', 'Hammer'), TARGET_ROOT = '#/$BUILD_TYPE', OBJ_ROOT = '$TARGET_ROOT', LIBS_DIR = '#/$BUILD_TYPE/Libs', BASE_DIR = '#/$BUILD_TYPE/base', BREAKPAD_DIR = '#/$BUILD_TYPE/breakpad', CHROME_DIR = '#/$BUILD_TYPE/chrome', GEARS_DIR = '#/$BUILD_TYPE/gears', GOOGLE_UPDATE_DIR = '#/$BUILD_TYPE/google_update', # Work around a limitation (bug?) in SCons in that, when we build # from a different directory, it forces the build targets defined # the SConscript.googleurl file to be relative to that file (i.e., # here in the build/ directory with us), not relative to the # the SConstruct directory from which SCons was launched. When # we roll forward to a version of SCons that fixes this, we'll # need to revert to the $BUILD_TYPE definition of GOOGLEURL_DIR. #GOOGLEURL_DIR = '#/$BUILD_TYPE/googleurl', GOOGLEURL_DIR = '#/../build/googleurl', NET_DIR = '#/$BUILD_TYPE/net', RLZ_DIR = '#/$BUILD_TYPE/rlz', SANDBOX_DIR = '#/$BUILD_TYPE/sandbox', SKIA_DIR = '#/$BUILD_TYPE/skia', TESTING_DIR = '#/$BUILD_TYPE/testing', THIRD_PARTY_DIR = '#/$BUILD_TYPE/third_party', V8_DIR = '#/$BUILD_TYPE/v8', WEBKIT_DIR = '#/$BUILD_TYPE/webkit', GTEST_DIR = '$TESTING_DIR/gtest', BSDIFF_DIR = '$THIRD_PARTY_DIR/bsdiff', BSPATCH_DIR = '$THIRD_PARTY_DIR/bspatch', BZIP2_DIR = '$THIRD_PARTY_DIR/bzip2', ICU38_DIR = '$THIRD_PARTY_DIR/icu38', LIBJPEG_DIR = '$THIRD_PARTY_DIR/libjpeg', LIBPNG_DIR = '$THIRD_PARTY_DIR/libpng', LIBXML_DIR = '$THIRD_PARTY_DIR/libxml', LIBXSLT_DIR = '$THIRD_PARTY_DIR/libxslt', LZMA_SDK_DIR = '$THIRD_PARTY_DIR/lzma_sdk', MODP_B64_DIR = '$THIRD_PARTY_DIR/modp_b64', NPAPI_DIR = '$THIRD_PARTY_DIR/npapi', ZLIB_DIR = '$THIRD_PARTY_DIR/zlib', THIRD_PARTY_WEBKIT_DIR = '$THIRD_PARTY_DIR/webkit', PYTHON=sys.executable, LIBPATH = ['$LIBS_DIR'], ) def ChromeProgram(env, *args, **kw): return env.Program(*args, **kw) env.AddMethod(ChromeProgram, "ChromeProgram") def ChromeTestProgram(env, *args, **kw): return env.Program(*args, **kw) env.AddMethod(ChromeTestProgram, "ChromeTestProgram") def ChromeStaticLibrary(env, *args, **kw): result = env.StaticLibrary(*args, **kw) env.Install('$LIBS_DIR', result) return result env.AddMethod(ChromeStaticLibrary, "ChromeStaticLibrary") def ChromeSharedLibrary(env, *args, **kw): return env.SharedLibrary(*args, **kw) env.AddMethod(ChromeSharedLibrary, "ChromeSharedLibrary") if env['PLATFORM'] == 'win32': msvs_env = Environment(tools=['msvc', 'mslink', 'msvs'])['ENV'] env.Replace( CSCRIPT = 'c:\\Windows\\System32\\cscript', PLATFORMSDK_VISTA_REL = '../third_party/platformsdk_vista_6_0', PLATFORMSDK_VISTA = '#/$PLATFORMSDK_VISTA_REL', VISUAL_STUDIO = '/Program Files/Microsoft Visual Studio 8', CYGWIN_DIR = Dir('#../third_party/cygwin'), CYGWIN_BIN_DIR = '$CYGWIN_DIR/bin', PERL = '$CYGWIN_BIN_DIR/perl.exe', PERL_INCLUDE_FLAG = '-I ', PERL_INCLUDE_SUFFIX = '', _PERL_INCLUDE_FLAGS = ('${_concat(PERL_INCLUDE_FLAG, ' 'PERL_INCLUDE_PATH, ' 'PERL_INCLUDE_SUFFIX,' '__env__, RDirs, TARGET, SOURCE)}'), MSVS_ENV = msvs_env, YACC = '$CYGWIN_BIN_DIR/bison.exe', ARFLAGS = [ '/nologo', ], CCFLAGS = [ '/nologo', '/Od', # no optimization '/RTC1', '/MTd', # static link to crt, and debug version '/Gy', '/GR-', '/W3', '/Z7', '/errorReport:prompt', '/wd4503', '/wd4819', ], CPPDEFINES = [ '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_WARNINGS', '_CRT_NONSTDC_NO_DEPRECATE', '_SCL_SECURE_NO_DEPRECATE', '_DEBUG', '_CRT_RAND_S', ('_WIN32_WINNT', '0x0600'), ('WINVER', '0x0600'), 'WIN32', '_WINDOWS', ('_HAS_EXCEPTIONS', 0), 'NOMINMAX', '_UNICODE', 'UNICODE', 'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS', 'WIN32_LEAN_AND_MEAN', ], CPPPATH = [ '$PLATFORMSDK_VISTA/files/Include', '$PLATFORMSDK_VISTA/files/VC/INCLUDE', '$VISUAL_STUDIO/VC/atlmfc/include', ], LIBS = [ 'advapi32.lib', 'comdlg32.lib', 'gdi32.lib', 'kernel32.lib', 'msimg32.lib', 'odbc32.lib', 'odbccp32.lib', 'ole32.lib', 'oleaut32.lib', 'psapi.lib', 'shell32.lib', 'user32.lib', 'usp10.lib', 'uuid.lib', 'version.lib', 'wininet.lib', 'winspool.lib', 'ws2_32.lib', 'DelayImp.lib', ], LINKFLAGS = [ '/nologo', '/DEBUG', ], ) env.Append( LIBPATH = [ '$PLATFORMSDK_VISTA/files/Lib', '$PLATFORMSDK_VISTA/files/VC/LIB', '$VISUAL_STUDIO/VC/atlmfc/lib', ], ) # TODO(sgk): remove once we upgrade to SCons 0.98.4 for var in ['INCLUDE', 'LIB', 'PATH']: msvs_env[var] = msvs_env[var].split('|', 1)[0] env['ENV'][var] = env['ENV'][var].split('|', 1)[0] # Force scons to handle long include lines correctly. pchcom_fixed = env['PCHCOM'] pchcom_fixed = pchcom_fixed.replace('${TARGETS[0]}', '$TARGET') pchcom_fixed = pchcom_fixed.replace('${TARGETS[1]}', '$TARGETS1') env.Replace( CCCOM = "${TEMPFILE('%s')}" % env['CCCOM'], CXXCOM = "${TEMPFILE('%s')}" % env['CXXCOM'], SHCCCOM = "${TEMPFILE('%s')}" % env['SHCCCOM'], SHCXXCOM = "${TEMPFILE('%s')}" % env['SHCXXCOM'], PCHCOM = "${TEMPFILE('%s')}" % pchcom_fixed, TARGETS1 = '${TARGETS[1]}', ) env['ENV']['PROGRAMFILES'] = os.environ['PROGRAMFILES'] env['ENV']['SystemDrive'] = os.environ['SystemDrive'] env['ENV']['USERPROFILE'] = os.environ['USERPROFILE'] elif env['PLATFORM'] == 'posix': env.Replace() else: print "Unsupported SCons $PLATFORM value %s" % repr(env['PLATFORM']) Exit(1) if ARGUMENTS.get('VERBOSE') in (None, '0'): env['CCCOMSTR'] = 'Compiling $TARGET ...' env['CXXCOMSTR'] = 'Compiling $TARGET ...' env['ARCOMSTR'] = 'Archiving $TARGET ...' env['LINKCOMSTR'] = 'Linking $TARGET ...' # Place the .sconsign.dblite in the build directory. target_dir = env.Dir('$TARGET_ROOT') if not os.path.exists(target_dir.abspath): Execute(Mkdir(target_dir)) SConsignFile(target_dir.File('.sconsign').abspath) # Add --clobber (for the buildbot). # NOTE: seems to be crucial to do this before any builders are invoked. AddOption('--clobber', action='store_true', dest='clobber', default=False, help='Delete build directory before building.') if GetOption('clobber'): shutil.rmtree(env.Dir('$TARGET_ROOT').abspath, True) # Use timestamps change, followed by MD5 for speed env.Decider('MD5-timestamp') # Overlay things from a layer below. env.Dir('$TARGET_ROOT').addRepository(Dir('..')) load = ARGUMENTS.get('LOAD') if load: load = load.split(',') else: load = [] included = [c for c in load if not c.startswith('-')] excluded = [c[1:] for c in load if c.startswith('-')] if not included: included = ['all'] components = ['all'] def LoadComponent(c): components.append(c) return (not GetOption('help') and c in included or ('all' in included and not c in excluded)) sconscripts = [] if LoadComponent('base'): sconscripts.append('$BASE_DIR/SConscript') if LoadComponent('breakpad'): sconscripts.append('$BREAKPAD_DIR/SConscript') if LoadComponent('chrome'): sconscripts.append('$CHROME_DIR/SConscript') if LoadComponent('google_update'): sconscripts.append('$GOOGLE_UPDATE_DIR/SConscript') if LoadComponent('googleurl'): env.SConscript('SConscript.googleurl', duplicate=0, variant_dir='$GOOGLEURL_DIR', src_dir='../googleurl', exports=['env']) if LoadComponent('net'): sconscripts.append('$NET_DIR/SConscript') if LoadComponent('rlz'): sconscripts.append('$RLZ_DIR/SConscript') if LoadComponent('sandbox'): sconscripts.append('$SANDBOX_DIR/src/SConscript') if LoadComponent('skia'): sconscripts.append('$SKIA_DIR/SConscript') if LoadComponent('testing'): sconscripts.append('$TESTING_DIR/SConscript.gtest') if LoadComponent('third_party'): sconscripts.extend([ '$BSDIFF_DIR/SConscript', '$BSPATCH_DIR/SConscript', '$BZIP2_DIR/SConscript', '$ICU38_DIR/SConscript', '$LIBJPEG_DIR/SConscript', '$LIBPNG_DIR/SConscript', '$LIBXML_DIR/SConscript', '$LIBXSLT_DIR/SConscript', '$LZMA_SDK_DIR/SConscript', '$MODP_B64_DIR/SConscript', '$ZLIB_DIR/SConscript', ]) if LoadComponent('v8') and env.Dir('#/../v8').exists(): env.SConscript('SConscript.v8', exports=['env']) if LoadComponent('webkit'): sconscripts.append('$WEBKIT_DIR/SConscript') env.SConscript(sconscripts, exports=['env']) help_fmt = """ Usage: hammer [SCONS_OPTIONS] [VARIABLES] [TARGET] ... Supported build variables: BUILD_TYPE=type Build type. Also used as the subdirectory name in which the build occurs. LOAD=[module,...] Comma-separated list of components to load in the dependency graph ('-' prefix excludes): %s PROGRESS=type Display a progress indicator: name: print each evaluated target name spinner: print a spinner every 5 targets VERBOSE=1 Display full command lines """ if GetOption('help'): import textwrap tw = textwrap.TextWrapper( width = 78, initial_indent = ' '*32, subsequent_indent = ' '*32, ) components = tw.fill(', '.join(components)) Help(help_fmt % components) Import('build_component') Default(build_component)