Initial implementation of Bare Metal Mode for NaCl.
[chromium-blink-merge.git] / build / landmines.py
blob7b4c5b5ecc623ff88b553f2ca5f8ffed4e8fa12f
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """
7 This script runs every build as a hook. If it detects that the build should
8 be clobbered, it will touch the file <build_dir>/.landmine_triggered. The
9 various build scripts will then check for the presence of this file and clobber
10 accordingly. The script will also emit the reasons for the clobber to stdout.
12 A landmine is tripped when a builder checks out a different revision, and the
13 diff between the new landmines and the old ones is non-null. At this point, the
14 build is clobbered.
15 """
17 import difflib
18 import gyp_helper
19 import logging
20 import optparse
21 import os
22 import sys
23 import subprocess
24 import time
26 import landmine_utils
29 SRC_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
32 def get_target_build_dir(build_tool, target, is_iphone=False):
33 """
34 Returns output directory absolute path dependent on build and targets.
35 Examples:
36 r'c:\b\build\slave\win\build\src\out\Release'
37 '/mnt/data/b/build/slave/linux/build/src/out/Debug'
38 '/b/build/slave/ios_rel_device/build/src/xcodebuild/Release-iphoneos'
40 Keep this function in sync with tools/build/scripts/slave/compile.py
41 """
42 ret = None
43 if build_tool == 'xcode':
44 ret = os.path.join(SRC_DIR, 'xcodebuild',
45 target + ('-iphoneos' if is_iphone else ''))
46 elif build_tool in ['make', 'ninja', 'ninja-ios']: # TODO: Remove ninja-ios.
47 ret = os.path.join(SRC_DIR, 'out', target)
48 elif build_tool in ['msvs', 'vs', 'ib']:
49 ret = os.path.join(SRC_DIR, 'build', target)
50 else:
51 raise NotImplementedError('Unexpected GYP_GENERATORS (%s)' % build_tool)
52 return os.path.abspath(ret)
55 def set_up_landmines(target, new_landmines):
56 """Does the work of setting, planting, and triggering landmines."""
57 out_dir = get_target_build_dir(landmine_utils.builder(), target,
58 landmine_utils.platform() == 'ios')
60 landmines_path = os.path.join(out_dir, '.landmines')
61 if not os.path.exists(out_dir):
62 os.makedirs(out_dir)
64 if not os.path.exists(landmines_path):
65 with open(landmines_path, 'w') as f:
66 f.writelines(new_landmines)
67 else:
68 triggered = os.path.join(out_dir, '.landmines_triggered')
69 with open(landmines_path, 'r') as f:
70 old_landmines = f.readlines()
71 if old_landmines != new_landmines:
72 old_date = time.ctime(os.stat(landmines_path).st_ctime)
73 diff = difflib.unified_diff(old_landmines, new_landmines,
74 fromfile='old_landmines', tofile='new_landmines',
75 fromfiledate=old_date, tofiledate=time.ctime(), n=0)
77 with open(triggered, 'w') as f:
78 f.writelines(diff)
79 elif os.path.exists(triggered):
80 # Remove false triggered landmines.
81 os.remove(triggered)
84 def process_options():
85 """Returns a list of landmine emitting scripts."""
86 parser = optparse.OptionParser()
87 parser.add_option(
88 '-s', '--landmine-scripts', action='append',
89 default=[os.path.join(SRC_DIR, 'build', 'get_landmines.py')],
90 help='Path to the script which emits landmines to stdout. The target '
91 'is passed to this script via option -t. Note that an extra '
92 'script can be specified via an env var EXTRA_LANDMINES_SCRIPT.')
93 parser.add_option('-v', '--verbose', action='store_true',
94 default=('LANDMINES_VERBOSE' in os.environ),
95 help=('Emit some extra debugging information (default off). This option '
96 'is also enabled by the presence of a LANDMINES_VERBOSE environment '
97 'variable.'))
99 options, args = parser.parse_args()
101 if args:
102 parser.error('Unknown arguments %s' % args)
104 logging.basicConfig(
105 level=logging.DEBUG if options.verbose else logging.ERROR)
107 extra_script = os.environ.get('EXTRA_LANDMINES_SCRIPT')
108 if extra_script:
109 return options.landmine_scripts + [extra_script]
110 else:
111 return options.landmine_scripts
114 def main():
115 landmine_scripts = process_options()
116 gyp_helper.apply_chromium_gyp_env()
118 for target in ('Debug', 'Release', 'Debug_x64', 'Release_x64'):
119 landmines = []
120 for s in landmine_scripts:
121 proc = subprocess.Popen([sys.executable, s, '-t', target],
122 stdout=subprocess.PIPE)
123 output, _ = proc.communicate()
124 landmines.extend([('%s\n' % l.strip()) for l in output.splitlines()])
125 set_up_landmines(target, landmines)
127 return 0
130 if __name__ == '__main__':
131 sys.exit(main())