Make landmines work on local builds too
Moves (some of) gyp environment setup out of gyp_chromium into separate module, and shares that between gyp_chromium and landmines.py. landmines.py is added as the first entry in DEPS hooks so that it can clobber the entire build directory before running other hooks that extract/generate into the build dir. R=iannucci@chromium.org BUG=400011 Review URL: https://codereview.chromium.org/457003004 git-svn-id: http://src.chromium.org/svn/trunk/src/build@289099 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
This commit is contained in:
Родитель
8f46fc3d14
Коммит
d95769ca0c
|
@ -8,7 +8,6 @@ This file emits the list of reasons why a particular build needs to be clobbered
|
|||
(or a list of 'landmines').
|
||||
"""
|
||||
|
||||
import optparse
|
||||
import sys
|
||||
|
||||
import landmine_utils
|
||||
|
@ -21,10 +20,9 @@ gyp_msvs_version = landmine_utils.gyp_msvs_version
|
|||
platform = landmine_utils.platform
|
||||
|
||||
|
||||
def print_landmines(target):
|
||||
def print_landmines():
|
||||
"""
|
||||
ALL LANDMINES ARE EMITTED FROM HERE.
|
||||
target can be one of {'Release', 'Debug', 'Debug_x64', 'Release_x64'}.
|
||||
"""
|
||||
if (distributor() == 'goma' and platform() == 'win32' and
|
||||
builder() == 'ninja'):
|
||||
|
@ -60,16 +58,7 @@ def print_landmines(target):
|
|||
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('-t', '--target',
|
||||
help=='Target for which the landmines have to be emitted')
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if args:
|
||||
parser.error('Unknown arguments %s' % args)
|
||||
|
||||
print_landmines(options.target)
|
||||
print_landmines()
|
||||
return 0
|
||||
|
||||
|
||||
|
|
33
gyp_chromium
33
gyp_chromium
|
@ -8,7 +8,7 @@
|
|||
# is invoked by Chromium beyond what can be done in the gclient hooks.
|
||||
|
||||
import glob
|
||||
import gyp_helper
|
||||
import gyp_environment
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
|
@ -197,10 +197,6 @@ if __name__ == '__main__':
|
|||
args.append('-Ganalyzer_output_path=' + args.pop(0))
|
||||
|
||||
if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)):
|
||||
# Check for landmines (reasons to clobber the build) in any case.
|
||||
print 'Running build/landmines.py...'
|
||||
subprocess.check_call(
|
||||
[sys.executable, os.path.join(script_dir, 'landmines.py')])
|
||||
print 'Skipping gyp_chromium due to GYP_CHROMIUM_NO_ACTION env var.'
|
||||
sys.exit(0)
|
||||
|
||||
|
@ -225,8 +221,6 @@ if __name__ == '__main__':
|
|||
p.communicate()
|
||||
sys.exit(p.returncode)
|
||||
|
||||
gyp_helper.apply_chromium_gyp_env()
|
||||
|
||||
# This could give false positives since it doesn't actually do real option
|
||||
# parsing. Oh well.
|
||||
gyp_file_specified = False
|
||||
|
@ -246,6 +240,8 @@ if __name__ == '__main__':
|
|||
else:
|
||||
args.append(os.path.join(script_dir, 'all.gyp'))
|
||||
|
||||
gyp_environment.SetEnvironment()
|
||||
|
||||
# There shouldn't be a circular dependency relationship between .gyp files,
|
||||
# but in Chromium's .gyp files, on non-Mac platforms, circular relationships
|
||||
# currently exist. The check for circular dependencies is currently
|
||||
|
@ -264,21 +260,6 @@ if __name__ == '__main__':
|
|||
print 'Error: make gyp generator not supported (check GYP_GENERATORS).'
|
||||
sys.exit(1)
|
||||
|
||||
# Default to ninja on linux and windows, but only if no generator has
|
||||
# explicitly been set.
|
||||
# Also default to ninja on mac, but only when not building chrome/ios.
|
||||
# . -f / --format has precedence over the env var, no need to check for it
|
||||
# . set the env var only if it hasn't been set yet
|
||||
# . chromium.gyp_env has been applied to os.environ at this point already
|
||||
if sys.platform.startswith(('linux', 'win', 'freebsd')) and \
|
||||
not os.environ.get('GYP_GENERATORS'):
|
||||
os.environ['GYP_GENERATORS'] = 'ninja'
|
||||
elif sys.platform == 'darwin' and not os.environ.get('GYP_GENERATORS') and \
|
||||
not 'OS=ios' in os.environ.get('GYP_DEFINES', []):
|
||||
os.environ['GYP_GENERATORS'] = 'ninja'
|
||||
|
||||
vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
|
||||
|
||||
# If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
|
||||
# to enfore syntax checking.
|
||||
syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK')
|
||||
|
@ -322,13 +303,7 @@ if __name__ == '__main__':
|
|||
gyp_rc = gyp.main(args)
|
||||
|
||||
if not use_analyzer:
|
||||
# Check for landmines (reasons to clobber the build). This must be run here,
|
||||
# rather than a separate runhooks step so that any environment modifications
|
||||
# from above are picked up.
|
||||
print 'Running build/landmines.py...'
|
||||
subprocess.check_call(
|
||||
[sys.executable, os.path.join(script_dir, 'landmines.py')])
|
||||
|
||||
vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
|
||||
if vs2013_runtime_dll_dirs:
|
||||
x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
|
||||
vs_toolchain.CopyVsRuntimeDlls(
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
"""
|
||||
Sets up various automatic gyp environment variables. These are used by
|
||||
gyp_chromium and landmines.py which run at different stages of runhooks. To
|
||||
make sure settings are consistent between them, all setup should happen here.
|
||||
"""
|
||||
|
||||
import gyp_helper
|
||||
import os
|
||||
import sys
|
||||
import vs_toolchain
|
||||
|
||||
def SetEnvironment():
|
||||
"""Sets defaults for GYP_* variables."""
|
||||
gyp_helper.apply_chromium_gyp_env()
|
||||
|
||||
# Default to ninja on linux and windows, but only if no generator has
|
||||
# explicitly been set.
|
||||
# Also default to ninja on mac, but only when not building chrome/ios.
|
||||
# . -f / --format has precedence over the env var, no need to check for it
|
||||
# . set the env var only if it hasn't been set yet
|
||||
# . chromium.gyp_env has been applied to os.environ at this point already
|
||||
if sys.platform.startswith(('linux', 'win', 'freebsd')) and \
|
||||
not os.environ.get('GYP_GENERATORS'):
|
||||
os.environ['GYP_GENERATORS'] = 'ninja'
|
||||
elif sys.platform == 'darwin' and not os.environ.get('GYP_GENERATORS') and \
|
||||
not 'OS=ios' in os.environ.get('GYP_DEFINES', []):
|
||||
os.environ['GYP_GENERATORS'] = 'ninja'
|
||||
|
||||
vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
|
59
landmines.py
59
landmines.py
|
@ -4,10 +4,8 @@
|
|||
# found in the LICENSE file.
|
||||
|
||||
"""
|
||||
This script runs every build as a hook. If it detects that the build should
|
||||
be clobbered, it will touch the file <build_dir>/.landmine_triggered. The
|
||||
various build scripts will then check for the presence of this file and clobber
|
||||
accordingly. The script will also emit the reasons for the clobber to stdout.
|
||||
This script runs every build as the first hook (See DEPS). If it detects that
|
||||
the build should be clobbered, it will remove the build directory.
|
||||
|
||||
A landmine is tripped when a builder checks out a different revision, and the
|
||||
diff between the new landmines and the old ones is non-null. At this point, the
|
||||
|
@ -16,9 +14,11 @@ build is clobbered.
|
|||
|
||||
import difflib
|
||||
import errno
|
||||
import gyp_environment
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
|
@ -29,35 +29,32 @@ import landmine_utils
|
|||
SRC_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
|
||||
def get_target_build_dir(build_tool, target, is_iphone=False):
|
||||
def get_build_dir(build_tool, is_iphone=False):
|
||||
"""
|
||||
Returns output directory absolute path dependent on build and targets.
|
||||
Examples:
|
||||
r'c:\b\build\slave\win\build\src\out\Release'
|
||||
'/mnt/data/b/build/slave/linux/build/src/out/Debug'
|
||||
'/b/build/slave/ios_rel_device/build/src/xcodebuild/Release-iphoneos'
|
||||
r'c:\b\build\slave\win\build\src\out'
|
||||
'/mnt/data/b/build/slave/linux/build/src/out'
|
||||
'/b/build/slave/ios_rel_device/build/src/xcodebuild'
|
||||
|
||||
Keep this function in sync with tools/build/scripts/slave/compile.py
|
||||
"""
|
||||
ret = None
|
||||
if build_tool == 'xcode':
|
||||
ret = os.path.join(SRC_DIR, 'xcodebuild',
|
||||
target + ('-iphoneos' if is_iphone else ''))
|
||||
ret = os.path.join(SRC_DIR, 'xcodebuild')
|
||||
elif build_tool in ['make', 'ninja', 'ninja-ios']: # TODO: Remove ninja-ios.
|
||||
ret = os.path.join(SRC_DIR, 'out', target)
|
||||
ret = os.path.join(SRC_DIR, 'out')
|
||||
elif build_tool in ['msvs', 'vs', 'ib']:
|
||||
ret = os.path.join(SRC_DIR, 'build', target)
|
||||
ret = os.path.join(SRC_DIR, 'build')
|
||||
else:
|
||||
raise NotImplementedError('Unexpected GYP_GENERATORS (%s)' % build_tool)
|
||||
return os.path.abspath(ret)
|
||||
|
||||
|
||||
def set_up_landmines(target, new_landmines):
|
||||
def clobber_if_necessary(new_landmines):
|
||||
"""Does the work of setting, planting, and triggering landmines."""
|
||||
out_dir = get_target_build_dir(landmine_utils.builder(), target,
|
||||
landmine_utils.platform() == 'ios')
|
||||
|
||||
landmines_path = os.path.join(out_dir, '.landmines')
|
||||
out_dir = get_build_dir(landmine_utils.builder())
|
||||
landmines_path = os.path.normpath(os.path.join(out_dir, '..', '.landmines'))
|
||||
try:
|
||||
os.makedirs(out_dir)
|
||||
except OSError as e:
|
||||
|
@ -65,7 +62,6 @@ def set_up_landmines(target, new_landmines):
|
|||
pass
|
||||
|
||||
if os.path.exists(landmines_path):
|
||||
triggered = os.path.join(out_dir, '.landmines_triggered')
|
||||
with open(landmines_path, 'r') as f:
|
||||
old_landmines = f.readlines()
|
||||
if old_landmines != new_landmines:
|
||||
|
@ -73,12 +69,13 @@ def set_up_landmines(target, new_landmines):
|
|||
diff = difflib.unified_diff(old_landmines, new_landmines,
|
||||
fromfile='old_landmines', tofile='new_landmines',
|
||||
fromfiledate=old_date, tofiledate=time.ctime(), n=0)
|
||||
sys.stdout.write('Clobbering due to:\n')
|
||||
sys.stdout.writelines(diff)
|
||||
|
||||
with open(triggered, 'w') as f:
|
||||
f.writelines(diff)
|
||||
elif os.path.exists(triggered):
|
||||
# Remove false triggered landmines.
|
||||
os.remove(triggered)
|
||||
# Clobber.
|
||||
shutil.rmtree(out_dir)
|
||||
|
||||
# Save current set of landmines for next time.
|
||||
with open(landmines_path, 'w') as f:
|
||||
f.writelines(new_landmines)
|
||||
|
||||
|
@ -119,14 +116,14 @@ def main():
|
|||
if landmine_utils.builder() in ('dump_dependency_json', 'eclipse'):
|
||||
return 0
|
||||
|
||||
for target in ('Debug', 'Release', 'Debug_x64', 'Release_x64'):
|
||||
landmines = []
|
||||
for s in landmine_scripts:
|
||||
proc = subprocess.Popen([sys.executable, s, '-t', target],
|
||||
stdout=subprocess.PIPE)
|
||||
output, _ = proc.communicate()
|
||||
landmines.extend([('%s\n' % l.strip()) for l in output.splitlines()])
|
||||
set_up_landmines(target, landmines)
|
||||
gyp_environment.SetEnvironment()
|
||||
|
||||
landmines = []
|
||||
for s in landmine_scripts:
|
||||
proc = subprocess.Popen([sys.executable, s], stdout=subprocess.PIPE)
|
||||
output, _ = proc.communicate()
|
||||
landmines.extend([('%s\n' % l.strip()) for l in output.splitlines()])
|
||||
clobber_if_necessary(landmines)
|
||||
|
||||
return 0
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче