# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import shutil import sys if sys.platform == 'win32': console = 'con' else: console = '/dev/tty' p = ARGUMENTS.get('PROGRESS') if p == 'spinner': Progress(['/\r', '|\r', '\\\r', '-\r'], interval=5, file=open(console, 'w')) elif p == 'name': Progress('$TARGET\r', overwrite=True, file=open(console, 'w')) default_warnings = ['no-missing-sconscript', 'no-no-parallel-support'] default_warnings = ['no-no-parallel-support'] SetOption('warn', default_warnings + GetOption('warn')) # Variables for controlling the build. # # The following variables can be set either on the command line # or in the external environment when executing SCons, with the # command line overriding any environment setting. # # BUILD_TARGET_DIR # Specifies the target subdirectory name in which we'll # build everything. This is intended to mimic the Visual # Visual Studio "Debug\" and "Release\" subdirectories. # The default value is "Hammer." # # # CHROME_BUILD_TYPE # When set, applies settings from the file # build\internal\release_impl${CHROME_BUILD_TYPE}.scons # to be applied to the construction environment. # # CHROMIUM_BUILD # When set, applies settings from the file # build\internal\chromium_build${CHROMIUM_BUILD}.scons # to be applied to the construction environment. # # INCREMENTAL # Controls whether or not libraries and executable programs are # linked incrementally. When set to any True value (1, T, y, True), # uses the /INCREMENTAL flag to the Microsoft linker. An # explicit False value (0, f, N, false) uses the /INCREMENTAL:NO. # When not set, the default is to link debug (developer) builds # incrementally, but release builds use full links. # clvars = Variables('scons.opts', ARGUMENTS) clvars.AddVariables( ('BUILD_TARGET_DIR', '', 'Hammer'), ('CHROME_BUILD_TYPE', '', os.environ.get('CHROME_BUILD_TYPE', '')), ('CHROMIUM_BUILD', '', os.environ.get('CHROMIUM_BUILD', '')), BoolVariable('INCREMENTAL', '', os.environ.get('INCREMENTAL')), ) root_env = Environment( # MSVSNew in the base environment? Yes, the point is we can (and # want to) generate Visual Studio project and solution files from # any platform. tools = ['component_setup', 'chromium_builders', 'chromium_load_component', 'MSVSNew'], variables = clvars, # Requested list of system (shared) libraries, from the comma separated # SYSTEM_LIBS command-line argument req_system_libs = [], # All supported system libraries, for the help message all_system_libs = [], CHROME_SRC_DIR = '$MAIN_DIR/..', DESTINATION_ROOT = '$MAIN_DIR/$BUILD_TARGET_DIR', # Where ComponentTestProgram() will build test executables. TESTS_DIR = '$DESTINATION_ROOT', # Where ComponentProgram() will build program executables. STAGING_DIR = '$DESTINATION_ROOT', # TODO(hammer): when Hammer supports this... # Have Hammer prefix all Library aliases with lib_ (to avoid # collisions with the component names themselves). #COMPONENT_LIBRARY_ALIAS = 'lib_$LIBNAME', # Disable running of tests thru scons for now. COMPONENT_TEST_RUNNABLE = False, BASE_DIR = '$OBJ_ROOT/base', BREAKPAD_DIR = '$OBJ_ROOT/breakpad', CHROME_DIR = '$OBJ_ROOT/chrome', GEARS_DIR = '$OBJ_ROOT/gears', GOOGLE_UPDATE_DIR = '$OBJ_ROOT/google_update', GOOGLEURL_DIR = '$OBJ_ROOT/googleurl', MEDIA_DIR = '$OBJ_ROOT/media', NET_DIR = '$OBJ_ROOT/net', PRINTING_DIR = '$OBJ_ROOT/printing', RLZ_DIR = '$OBJ_ROOT/rlz', SANDBOX_DIR = '$OBJ_ROOT/sandbox', SDCH_DIR = '$OBJ_ROOT/sdch', SKIA_DIR = '$OBJ_ROOT/skia', TESTING_DIR = '$OBJ_ROOT/testing', THIRD_PARTY_DIR = '$OBJ_ROOT/third_party', TOOLS_DIR = '$OBJ_ROOT/tools', V8_DIR = '$OBJ_ROOT/v8', WEBKIT_DIR = '$OBJ_ROOT/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', LIBEVENT_DIR = '$THIRD_PARTY_DIR/libevent', 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', SQLITE_DIR = '$THIRD_PARTY_DIR/sqlite', ZLIB_DIR = '$THIRD_PARTY_DIR/zlib', THIRD_PARTY_WEBKIT_DIR = '$THIRD_PARTY_DIR/WebKit', GTK_CLIP_DUMP_DIR = '$TOOLS_DIR/gtk_clipboard_dump', GRIT_DIR = '$TOOLS_DIR/grit', PYTHON=sys.executable, PERL = 'perl', PERL_INCLUDE_FLAG = '-I ', PERL_INCLUDE_SUFFIX = '', _PERL_INCLUDE_FLAGS = ('${_concat(PERL_INCLUDE_FLAG, ' 'PERL_INCLUDE_PATH, ' 'PERL_INCLUDE_SUFFIX,' '__env__, RDirs, TARGET, SOURCE)}'), ) root_env['req_system_libs'] = ARGUMENTS.get('SYSTEM_LIBS', '').split(',') root_env['_GYP'] = ARGUMENTS.get('GYP') and '_gyp' or '' def WantSystemLib(env, lib): """ Return true if lib has been requested as a system library in SYSTEM_LIBS. """ if lib not in env['all_system_libs']: env['all_system_libs'].append(lib) return (lib in env['req_system_libs']) root_env.AddMethod(WantSystemLib, "WantSystemLib") # TODO(bradnelson): pull this functionality into hammer. # Auto select the number of processors if root_env['PLATFORM'] in ['win32', 'cygwin']: cpus = int(os.environ.get('NUMBER_OF_PROCESSORS', 1)) elif root_env['PLATFORM'] in ['linux', 'linux2', 'posix']: # TODO(evanm): this is Linux-specific, not posix. # Parse /proc/cpuinfo for processor count. cpus = len([l for l in open('/proc/cpuinfo') if l.startswith('processor\t')]) else: cpus = 1 SetOption('num_jobs', cpus + 1) # Use timestamps change, followed by MD5 for speed root_env.Decider('MD5-timestamp') # Incorporate settings that should apply globally (primarily to provide # an obvious place for developmental experimentation). root_env.ApplySConscript(['$CHROME_SRC_DIR/build/common.scons']) # The list of all leaf (fully described) environments. environment_list = [] components = [] # Figure out what SConscript files to load based on the user's request. # Default is to load all SConscript files for a full-tree build. # The keyword arguments in the call below (base, breakpad, etc.) can be # specified in the LOAD= argument to cut down on the build. sconscript_map = dict( base = '$BASE_DIR/base_main${_GYP}.scons', breakpad = '$BREAKPAD_DIR/SConscript', chrome = '$CHROME_DIR/chrome_main${_GYP}.scons', gears = '$GEARS_DIR/SConscript', google_update = '$GOOGLE_UPDATE_DIR/SConscript', googleurl = '$GOOGLEURL_DIR/googleurl.scons', media = '$MEDIA_DIR/media.scons', net = '$NET_DIR/net_main${_GYP}.scons', printing = '$PRINTING_DIR/printing.scons', rlz = '$RLZ_DIR/SConscript', sandbox = '$SANDBOX_DIR/sandbox.scons', sdch = '$SDCH_DIR/SConscript', skia = '$SKIA_DIR/SConscript', testing = '$TESTING_DIR/SConscript.gtest', third_party = [ '$BSDIFF_DIR/bsdiff.scons', '$BSPATCH_DIR/bspatch.scons', '$BZIP2_DIR/bzip2.scons', '$ICU38_DIR/icu38_main${_GYP}.scons', '$LIBJPEG_DIR/libjpeg${_GYP}.scons', '$LIBPNG_DIR/libpng${_GYP}.scons', '$LIBXML_DIR/libxml.scons', '$LIBXSLT_DIR/libxslt.scons', '$LZMA_SDK_DIR/lzma_sdk.scons', '$MODP_B64_DIR/modp_b64.scons', '$ZLIB_DIR/zlib${_GYP}.scons', ], tools = '$GTK_CLIP_DUMP_DIR/gcd.scons', v8 = '$OBJ_ROOT/build/SConscript.v8', webkit = '$WEBKIT_DIR/webkit_main${_GYP}.scons', ) if root_env.get('_GYP'): Import('build_component') sconscripts = [sconscript_map[build_component]] components = [build_component] else: sconscripts = root_env.ChromiumLoadComponentSConscripts(**sconscript_map) # Add the final list into the root environment to be build in BuildComponents. root_env.Append(BUILD_SCONSCRIPTS = sconscripts) if not root_env.WantSystemLib('sqlite') and not root_env.get('_GYP'): root_env.Append(BUILD_SCONSCRIPTS = ['$SQLITE_DIR/SConscript']) # -------------------------------------------------------------------------- # Windows specific windows_env = root_env.Clone() # TODO(siggi) Remove this code once SCons plays well when the # Platform SDK 6.1 is installed with VS2005 but not VS2008. if root_env['PLATFORM'] in ['win32', 'cygwin']: windows_env['MSVS_VERSION'] = '8.0' windows_env.Tool('target_platform_windows') windows_env.Tool('component_targets_msvs') # Per target project support. # Hammer's target_platform_windows module added the stock SCons # MSVSProject() and MSVSSolution() Builders, which we're going to # replace with our newer, more flexible implementation. Wipe out the # older ones so they don't interfere with our initialization and so # SCons doesn't propagate them to cloned construction environments. del windows_env['BUILDERS']['MSVSProject'] del windows_env['BUILDERS']['MSVSSolution'] windows_env.Tool('MSVSNew') windows_env.Tool('midl') # TODO(bradnelson): target_platform_windows defines a whole bunch of # flags that we don't care about, including defining OS_WINDOWS in a # way that we don't want, and (most especially) adding *_DEBUG and # *_OPTIMIZED constructionv variables that add magic values to # CCFLAGS. We override the normal variables (CPPDEFINES, CCFLAGS, # LINKFLAGS, ARFLAGS) below, but get rid of the special Hammer ones # here, until Hammer can be made a little nicer about htis. del windows_env['CCFLAGS_DEBUG'] del windows_env['LINKFLAGS_DEBUG'] del windows_env['CCFLAGS_OPTIMIZED'] windows_env['PDB'] = '${TARGET.base}.pdb' windows_env['MSVC_BATCH'] = True # TODO(bradnelson): this should not need to be gated on host platform. if root_env['PLATFORM'] in ['win32', 'cygwin']: msvs_env = Environment(tools=['msvc', 'mslink'])['ENV'] msvs_drive = msvs_env['PATH'][0] else: msvs_env = {'PATH': '', 'INCLUDE': '', 'LIB': ''} msvs_drive = 'C' # Use the absolute path for MSVC because it might not be on the same drive # as our source checkout. visual_studio_path = msvs_drive + ':/Program Files/Microsoft Visual Studio 8' # If side-by-side platform sdk is not available try local copy. platform_sdk_path = '$CHROME_SRC_DIR/third_party/platformsdk_win2008_6_1/files' if (root_env['PLATFORM'] in ['win32', 'cygwin'] and not os.path.exists(windows_env.subst(platform_sdk_path))): platform_sdk_path = ( msvs_drive + ':\\Program Files\\Microsoft SDKs\\Windows\\v6.1') windows_env.Replace( CSCRIPT = 'c:\\Windows\\System32\\cscript', PLATFORMSDK_6_1 = platform_sdk_path, VISUAL_STUDIO = visual_studio_path, CYGWIN_DIR = windows_env.Dir('$CHROME_SRC_DIR/third_party/cygwin'), CYGWIN_BIN_DIR = '$CYGWIN_DIR/bin', PERL = '$CYGWIN_BIN_DIR/perl.exe', MSVS_ENV = msvs_env, YACC = '$CYGWIN_BIN_DIR/bison.exe', ARFLAGS = [ '/nologo', ], CCFLAGS = [ '/nologo', '/errorReport:prompt', ], CPPDEFINES = [ '_UNICODE', 'UNICODE', ], LIBS = [ 'advapi32.lib', 'comdlg32.lib', 'gdi32.lib', 'kernel32.lib', 'odbc32.lib', 'odbccp32.lib', 'ole32.lib', 'oleaut32.lib', 'shell32.lib', 'user32.lib', 'uuid.lib', 'winspool.lib', 'DelayImp.lib', ], LINKFLAGS = [ '/nologo', ], ICU_LIBS = ['icu'], ) # Force scons to handle long include lines correctly. pchcom_fixed = windows_env['PCHCOM'] pchcom_fixed = pchcom_fixed.replace('${TARGETS[0]}', '$TARGET') pchcom_fixed = pchcom_fixed.replace('${TARGETS[1]}', '$TARGETS1') # Below, we'll redefine $CXXFLAGS so its expansion doesn't include # $CCFLAGS. Modify $PCHCOM, which was relying on this fact, so # that $CCFLAGS still shows up in precompiled header compilations. pchcom_fixed = pchcom_fixed.replace('$CXXFLAGS', '$CXXFLAGS $CCFLAGS') windows_env.Replace( CCCOM = "${TEMPFILE('%s')}" % windows_env['CCCOM'], CXXCOM = "${TEMPFILE('%s')}" % windows_env['CXXCOM'], SHCCCOM = "${TEMPFILE('%s')}" % windows_env['SHCCCOM'], SHCXXCOM = "${TEMPFILE('%s')}" % windows_env['SHCXXCOM'], PCHCOM = "${TEMPFILE('%s')}" % pchcom_fixed, TARGETS1 = '${TARGETS[1]}', # The SCons default for $CXXFLAGS contains $CCFLAGS, which is # also on the $CCCOM command line string separately. Redefine # $CXXFLAGS to avoid the duplication CXXFLAGS = '$( /TP $)', ) windows_env['ENV']['PROGRAMFILES'] = os.environ.get('PROGRAMFILES', '') windows_env['ENV']['SystemDrive'] = os.environ.get('SystemDrive', '') windows_env['ENV']['USERPROFILE'] = os.environ.get('USERPROFILE', '') windows_env.AppendENVPath('PATH', ';C:\\WINDOWS\\system32') windows_dbg = windows_env.Clone() environment_list.append(windows_dbg) windows_dbg.Replace( BUILD_TYPE = 'dbg', BUILD_TYPE_DESCRIPTION = 'Windows debug build', ) windows_dbg.Tool('target_debug') windows_dbg.ApplySConscript(['$CHROME_SRC_DIR/build/debug.scons']) windows_dbg.Append(BUILD_GROUPS = ['default']) windows_opt = windows_env.Clone() environment_list.append(windows_opt) windows_opt.Replace( BUILD_TYPE = 'opt', BUILD_TYPE_DESCRIPTION = 'Windows optimized build', ) windows_opt.Tool('target_optimized') windows_opt.ApplySConscript(['$CHROME_SRC_DIR/build/release.scons']) # -------------------------------------------------------------------------- # Platform-independent "msvs" mode for generating Visual Studio # project and solution files from any platform. DeclareBit('msvs', 'Generate Visual Studio files') msvs_env = windows_env.Clone() msvs_env.Tool('target_platform_windows') msvs_env.Tool('component_targets_msvs') # Per target project support. del msvs_env['BUILDERS']['MSVSProject'] del msvs_env['BUILDERS']['MSVSSolution'] msvs_env.Tool('MSVSNew') msvs_env.Tool('midl') environment_list.append(msvs_env) msvs_env.Replace( BUILD_TYPE = 'msvs', BUILD_TYPE_DESCRIPTION = 'Generate Visual Studio files', HOST_PLATFORMS = ['*'], ICU_LIBS = [], ) msvs_env.SetBits('windows', 'msvs') # TODO(sgk): turn into separate debug + release env adding # to a common .sln file msvs_env.Tool('target_debug') # -------------------------------------------------------------------------- # Linux specific linux_env = root_env.Clone() linux_env.Tool('target_platform_linux') linux_env.Tool('yacc') # By default scons will depend on the first path element for any command line. # For example, it will resolve 'gcc' with $PATH and depend on that for any # action which runs gcc. This disables this behaviour: linux_env['IMPLICIT_COMMAND_DEPENDENCIES'] = False # TODO(bradnelson): this is needed for now because target_platform_linux has # OS_LINUX defined in a weird way. linux_env.FilterOut(CPPDEFINES = ['OS_LINUX=OS_LINUX']) # Copy some environment variables from the outer environment to the # SCons.Environment if they exist. for envvar in ('CC', 'CXX', 'LINK'): if envvar in os.environ: linux_env[envvar] = os.environ[envvar] # Copy these environment variables from the outer environment to the # environment that the build commands run in. # $HOME is needed by distcc so it can find its lock file. for envvar in ('HOME', 'DISTCC_DIR', 'DISTCC_HOSTS', 'CCACHE_DIR', 'INTERCEPTOR_SOCKET', 'ENFORGE_DIGEST_CACHE', 'ENFORGE_CACHE_HOST', 'ENFORGE_CACHE_PORT'): if envvar in os.environ: linux_env['ENV'][envvar] = os.environ[envvar] excluded_warnings = [ # TODO: Clean up uses of ext/hash_map and remove this. # (see unordered_map and base/hash_tables.h) '-Wno-deprecated', # Needed for using ext/hash_map on GCC 4.3 ] if not root_env.get('_GYP'): linux_env.Append( BUILD_SCONSCRIPTS = [ '$LIBEVENT_DIR/libevent${_GYP}.scons', ], ) linux_env.Append( ASFLAGS = ['-32'], CCFLAGS = ['-m32', '-pthread', '-march=i686', '-fno-exceptions'], # GCC will generate ident directives with the GCC version. Accumulate # these all up and you end up with ~80K repeated in a .comment section. CCFLAGS_OPTIMIZED = ['-fno-ident'], CXXFLAGS = ['-Wall', '-Werror', '-march=i686'] + excluded_warnings, LINKFLAGS = ['-m32', '-pthread'], ) linux_env.Replace( # Linking of large files uses lots of RAM, so serialize links # using the handy flock command from util-linux. LINK = 'flock $TARGET_ROOT/linker.lock ' + linux_env['LINK'], # We have several cases where archives depend on each other in a cyclic # fashion. (V8Bindings, libport and WebCore being the most significant # example.) Since the GNU linker does only a single pass over the archives # we need some extra trickery to deal with these unavoidable cycles. That # trickery is --start-group and --end-group (aka -( and -) ). That causes ld # to loop over the group until no more undefined symbols are found. In an # ideal world we would only make groups from those libraries which we knew # to be in cycles. However, that's tough with SCons, so we bodge it by # making all the archives a group by redefining the linking command here. SHLINKCOM = ('$SHLINK -o $TARGET $SHLINKFLAGS $SOURCES ' '$_LIBDIRFLAGS ' '-Wl,--start-group $_LIBFLAGS -Wl,--end-group'), LINKCOM = ('$LINK -o $TARGET $LINKFLAGS $SOURCES ' '$_LIBDIRFLAGS ' '-Wl,--start-group $_LIBFLAGS -Wl,--end-group'), ) linux_env.Replace( PERL = '/usr/bin/perl', PERL_INCLUDE_FLAG = '-I ', PERL_INCLUDE_SUFFIX = '', _PERL_INCLUDE_FLAGS = ('${_concat(PERL_INCLUDE_FLAG, ' 'PERL_INCLUDE_PATH, ' 'PERL_INCLUDE_SUFFIX,' '__env__, RDirs, TARGET, SOURCE)}'), ) linux_env.FilterOut( BUILD_SCONSCRIPTS = [ '$BSPATCH_DIR/bspatch.scons', '$BSDIFF_DIR/bsdiff.scons', '$GOOGLE_UPDATE_DIR/SConscript', '$RLZ_DIR/SConscript', '$SANDBOX_DIR/sandbox.scons', ], ) linux_env.Append( # We need rt for clock_gettime. LIBS = ['rt'], ICU_LIBS = ['icu'], ) # Build an "official" build (DCHECKs completely compiled out, etc). if ARGUMENTS.get('OFFICIAL') == '1': linux_env.Append(CPPDEFINES=['OFFICIAL_BUILD']) # Make sure units of code and data go in their own section, and then GC them # in the linker to remove unreferenced data and code. Currently gold doesn't # support --gc-sections, so you'll have to build with the original GNU ld. linux_env.Append(CCFLAGS_OPTIMIZED=['-ffunction-sections', '-fdata-sections']) linux_env.Append(LINKFLAGS_OPTIMIZED=['-Wl,--gc-sections']) # Build with support for gcov when COVERAGE=1. if ARGUMENTS.get('COVERAGE') == '1': linux_env.Append(CCFLAGS=['-fprofile-arcs', '-ftest-coverage']) linux_env.Append(LINKFLAGS=['-fprofile-arcs']) # Build with support for gprof when PROFILE=1. if ARGUMENTS.get('PROFILE') == '1': linux_env.Append(CCFLAGS=['-pg', '-g']) linux_env.Append(LINKFLAGS=['-pg']) # Build with symbols (useful for opt builds, for example) when SYMBOLS=1. if ARGUMENTS.get('SYMBOLS') == '1': linux_env.Append(CCFLAGS=['-g']) # Build shared libraries (useful for fast links) when SHARED=1. if ARGUMENTS.get('SHARED') == '1': linux_env.Replace(COMPONENT_STATIC=False) # Build with system-provided NSS and GTK. if root_env['PLATFORM'] in ['linux', 'linux2', 'posix']: try: linux_env.ParseConfig('pkg-config --cflags --libs nss') linux_env.ParseConfig('pkg-config --cflags --libs gtk+-2.0') linux_env.ParseConfig('pkg-config --cflags --libs pangoft2') except OSError, e: print ('\n' 'Failed to find a package dependency. Please install all the\n' 'packages listed at\n' 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions' '#Software_Requirements') sys.exit(1) # TODO: Factor the code here into aits own function. if root_env.WantSystemLib('libxml'): try: linux_env.ParseConfig('pkg-config --cflags --libs libxml-2.0') except OSError, e: print ('\n' 'libxml requested in SYSTEM_LIBS but not found\n') sys.exit(1) if root_env.WantSystemLib('libxslt'): try: linux_env.ParseConfig('pkg-config --cflags --libs libxslt') except OSError, e: print ('\n' 'libxslt requested in SYSTEM_LIBS but not found\n') sys.exit(1) if root_env.WantSystemLib('sqlite'): try: linux_env.ParseConfig('pkg-config --cflags --libs sqlite') except OSError, e: print ('\n' 'sqlite requested in SYSTEM_LIBS but not found\n') sys.exit(1) linux_dbg = linux_env.Clone() environment_list.append(linux_dbg) linux_dbg.Replace( BUILD_TYPE = 'dbg', BUILD_TYPE_DESCRIPTION = 'Linux debug build', ) linux_dbg.Tool('target_debug') linux_dbg.ApplySConscript(['$CHROME_SRC_DIR/build/debug.scons']) linux_dbg.Append(BUILD_GROUPS = ['default']) linux_opt = linux_env.Clone() environment_list.append(linux_opt) # Disable rpath for faster startup. linux_opt.Append(RPATH = []) linux_opt.Replace( BUILD_TYPE = 'opt', BUILD_TYPE_DESCRIPTION = 'Linux optimized build', ) linux_opt.Tool('target_optimized') linux_opt.ApplySConscript(['$CHROME_SRC_DIR/build/release.scons']) # -------------------------------------------------------------------------- # Mac specific mac_env = root_env.Clone() environment_list.append(mac_env) mac_env.Tool('target_platform_mac') mac_env.Tool('target_debug') mac_env.ApplySConscript(['$CHROME_SRC_DIR/build/debug.scons']) mac_env.Replace( BUILD_TYPE = 'debug-mac', BUILD_TYPE_DESCRIPTION = 'Mac debug build', ) mac_env.Append(BUILD_GROUPS = ['default']) mac_env.Replace( # Reproduce XCode's behavior of using gcc even to link C++, # and distinguishing it the -x c++ option. CC = 'gcc-4.2', CXX = 'g++-4.2', LINK = '$CXX', ) mac_env.FilterOut(SHCCFLAGS = ['-fPIC']) mac_env.FilterOut(SHLINKFLAGS = ['-fPIC']) mac_env.FilterOut( BUILD_SCONSCRIPTS = [ '$BREAKPAD_DIR/SConscript', '$BSDIFF_DIR/bsdiff.scons', '$BSPATCH_DIR/bspatch.scons', '$CHROME_DIR/chrome_main${_GYP}.scons', '$GOOGLE_UPDATE_DIR/SConscript', '$LIBJPEG_DIR/libjpeg.scons', '$LIBXML_DIR/libxml.scons', '$LIBXSLT_DIR/libxslt.scons', '$RLZ_DIR/SConscript', '$SANDBOX_DIR/sandbox.scons', '$WEBKIT_DIR/SConscript', 'build/SConscript.v8', ], ) # TODO(bradnelson): this is needed for now because target_platform_mac has # OS_MACOSX defined in a weird way. mac_env.FilterOut(CPPDEFINES = ['OS_MACOSX=OS_MACOSX']) if not root_env.WantSystemLib('libevent') and not root_env.get('_GYP'): mac_env.Append( BUILD_SCONSCRIPTS = [ '$LIBEVENT_DIR/libevent${_GYP}.scons', ], ) mac_env.Append( CFLAGS = [ '-std=c99', ], CXXFLAGS = [ '-fvisibility-inlines-hidden', '${str(SOURCE).endswith(".mm") and "-fobjc-gc" or ""}', ], CCFLAGS = [ '-fmessage-length=0', '-pipe', '-O0', '-mdynamic-no-pic', '-Werror', '-Wnewline-eof', '-fvisibility=hidden', '-gdwarf-2', '-Wall', '-Wendif-labels', '-fstack-protector', '-fstack-protector-all', ], CPPDEFINES = [ 'DEBUG', ], FRAMEWORKPATH = [ mac_env.Dir('${TARGET_ROOT}'), '/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks', ], FRAMEWORKS = [ 'AppKit', 'ApplicationServices', 'Foundation', ], ICU_LIBS = ['icui18n', 'icuuc', 'icudata'], ) # -------------------------------------------------------------------------- # Platform-independent "xcode" mode for generating XCode files # from any platform. DeclareBit('xcode', 'Generate XCode files') # TODO(sgk): remove this after we update Hammer modules. DeclareBit('mac', 'Target platform is mac.') xcode_env = mac_env.Clone() # TODO(sgk): uncomment when xcode generation becomes real. #environment_list.append(xcode_env) xcode_env.Replace( BUILD_TYPE = 'xcode', BUILD_TYPE_DESCRIPTION = 'Generate XCode files', HOST_PLATFORMS = ['*'], ICU_LIBS = [], ) xcode_env.SetBits('mac', 'xcode') # TODO(sgk): turn into separate debug + release env adding # to a common .sln file xcode_env.Tool('target_debug') # ------------------------------------------------------------------------- # Overlay things from a layer below. for env in environment_list: env.Dir('$OBJ_ROOT').addRepository(env.Dir('$CHROME_SRC_DIR')) env.Dir('$OBJ_ROOT/googleurl').addRepository(env.Dir('$CHROME_SRC_DIR/build')) # We pre-resolve some common targets. We end up spending lots of time # resolving these over and over again. env.Replace( CHROME_SRC_DIR = str(env.Dir('$CHROME_SRC_DIR')), DESTINATION_ROOT = str(env.Dir('$DESTINATION_ROOT')), TARGET_ROOT = str(env.Dir('$TARGET_ROOT')), OBJ_ROOT = str(env.Dir('$OBJ_ROOT')), WEBKIT_DIR = str(env.Dir('$WEBKIT_DIR')), ) help_fmt = """ Usage: hammer [SCONS_OPTIONS] [VARIABLES] [TARGET] ... Supported build variables: LOAD=[module,...] Comma-separated list of components to load in the dependency graph ('-' prefix excludes): %s SYSTEM_LIBS=[lib,...] Comma-separated list of system libraries to link dynamically (by default they are built in from included sources): %s PROGRESS=type Display a progress indicator: name: print each evaluated target name spinner: print a spinner every 5 targets GYP=1 Any non-null value uses GYP-generated files (*_gyp.scons). """ if GetOption('help'): import textwrap tw = textwrap.TextWrapper( width = 78, initial_indent = ' '*32, subsequent_indent = ' '*32, ) components = tw.fill(', '.join(components)) all_system_libs = tw.fill(', '.join(env['all_system_libs'])) Help(help_fmt % (components, all_system_libs)) # ------------------------------------------------------------------------- # Invoke all the SConscripts in each of the environments that make sense on # this host-platform. BuildComponents(environment_list) # ------------------------------------------------------------------------- Default(None) # Reset default target to empty. modes = GetTargetModes().keys() if set(modes) - set(['msvs', 'xcode']): # There's at least one mode being built besides the platform- # independent 'msvs' or 'xcode' modes. Build the current # build_component's Alias as default--that is, "base" when we're # in the base/ subdirectory, "chrome" under chrome/, etc. Import('build_component') Default(Alias(build_component)) # Set default target based on where built. if 'msvs' in modes: # We're in --mode=msvs, so add its Alias(es) to the default targets. Default(Alias('msvs')) # ------------------------------------------------------------------------- # This must occur after BuildComponents so that the dependency graph # will be populated. vs_env = windows_env.Clone() vs_env.Append(COMPONENT_VS_SOURCE_SUFFIXES = [ '.def', '.ini', '.txt', '.ui', '.xml', ]) # Source project p = vs_env.ComponentVSDirProject( 'chrome_src', [ # TODO(bradnelson): need to make sure we can use $CHROME_SRC_DIR here '$CHROME_SRC_DIR/base', '$CHROME_SRC_DIR/breakpad', '$CHROME_SRC_DIR/build', # '$CHROME_SRC_DIR/chrome', '.', '$CHROME_SRC_DIR/data', '$CHROME_SRC_DIR/gears', '$CHROME_SRC_DIR/google_update', '$CHROME_SRC_DIR/googleurl', '$CHROME_SRC_DIR/net', '$CHROME_SRC_DIR/rlz', '$CHROME_SRC_DIR/sandbox', '$CHROME_SRC_DIR/sdhc', '$CHROME_SRC_DIR/site_scons', '$CHROME_SRC_DIR/skia', '$CHROME_SRC_DIR/testing', '$CHROME_SRC_DIR/third_party', '$CHROME_SRC_DIR/tools', '$CHROME_SRC_DIR/v8', '$CHROME_SRC_DIR/webkit', ], COMPONENT_VS_SOURCE_FOLDERS = [ (None, '$DESTINATION_ROOT'), ('src', '$CHROME_SRC_DIR'), ], COMPONENT_VS_PROJECT_DIR = '$MAIN_DIR', ) # Always try to (re)build the project files when requested. vs_env.AlwaysBuild(p) vs_env.ComponentVSSolution( 'chrome_solution', [ 'all_libraries', 'all_languages', 'all_programs', 'all_test_programs', ], projects = [p], COMPONENT_VS_PROJECT_SCRIPT_PATH=( 'cd $$(ProjectDir)/$VS_PROJECT_TO_MAIN_DIR && hammer.bat'), ) # -------------------------------------------------------------------------