Skip to content

Commit 8c2cfd3

Browse files
dprankeCommit bot
authored and
Commit bot
committed
Reland "Remove the 'gyp_config' concept from MB."
This re-lands #349043 with some fixes for win32; we weren't consistently using os.sep everywhere. This patch fixes that and consolidates the code so that all references to os.sep and os.path.join() happen in the same places. In addition, this patch updates the unittests to run cleanly on win32 and test a win32-specific example (to catch the case that broke). TBR=scottmg@chromium.org BUG=481692 Review URL: https://codereview.chromium.org/1348153003 Cr-Commit-Position: refs/heads/master@{#349477}
1 parent 13950c5 commit 8c2cfd3

File tree

4 files changed

+63
-68
lines changed

4 files changed

+63
-68
lines changed

tools/mb/docs/user_guide.md

+2-5
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@ value of the `mixins` key.
172172
Each mixin value is itself a dictionary that contains one or more of the
173173
following keys:
174174

175-
* `gyp_configs`: a list of the configurations to build, e.g.,
176-
['Release', 'Release_x64'].
177175
* `gyp_crosscompile`: a boolean; if true, GYP_CROSSCOMPILE=1 is set in
178176
the environment and passed to GYP.
179177
* `gyp_defines`: a string containing a list of GYP_DEFINES.
@@ -184,8 +182,8 @@ following keys:
184182

185183
When `mb gen` or `mb analyze` executes, it takes a config name, looks it
186184
up in the 'configs' dict, and then does a left-to-right expansion of the
187-
mixins; gyp_defines and gn_args values are concatenated, and type and
188-
gyp_configs values override each other.
185+
mixins; gyp_defines and gn_args values are concatenated, and the type values
186+
override each other.
189187

190188
For example, if you had:
191189

@@ -205,7 +203,6 @@ For example, if you had:
205203
},
206204
'gn': {'type': 'gn'},
207205
'gyp_release': {
208-
'gyp_config': 'Release'
209206
'mixins': ['release'],
210207
'type': 'gyp',
211208
},

tools/mb/mb.py

+35-52
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ def __init__(self):
3737
self.chromium_src_dir = p.normpath(d(d(d(p.abspath(__file__)))))
3838
self.default_config = p.join(self.chromium_src_dir, 'tools', 'mb',
3939
'mb_config.pyl')
40+
self.executable = sys.executable
4041
self.platform = sys.platform
42+
self.sep = os.sep
4143
self.args = argparse.Namespace()
4244
self.configs = {}
4345
self.masters = {}
@@ -146,7 +148,7 @@ def CmdLookup(self):
146148
elif vals['type'] == 'gyp':
147149
if vals['gyp_crosscompile']:
148150
self.Print('GYP_CROSSCOMPILE=1')
149-
cmd = self.GYPCmd('<path>', vals['gyp_defines'], vals['gyp_config'])
151+
cmd = self.GYPCmd('<path>', vals['gyp_defines'])
150152
else:
151153
raise MBErr('Unknown meta-build type "%s"' % vals['type'])
152154

@@ -285,7 +287,6 @@ def FlattenConfig(self, config):
285287
vals = {
286288
'type': None,
287289
'gn_args': [],
288-
'gyp_config': [],
289290
'gyp_defines': '',
290291
'gyp_crosscompile': False,
291292
}
@@ -311,8 +312,6 @@ def FlattenMixins(self, mixins, vals, visited):
311312
vals['gn_args'] += ' ' + mixin_vals['gn_args']
312313
else:
313314
vals['gn_args'] = mixin_vals['gn_args']
314-
if 'gyp_config' in mixin_vals:
315-
vals['gyp_config'] = mixin_vals['gyp_config']
316315
if 'gyp_crosscompile' in mixin_vals:
317316
vals['gyp_crosscompile'] = mixin_vals['gyp_crosscompile']
318317
if 'gyp_defines' in mixin_vals:
@@ -327,7 +326,7 @@ def FlattenMixins(self, mixins, vals, visited):
327326
def ClobberIfNeeded(self, vals):
328327
path = self.args.path[0]
329328
build_dir = self.ToAbsPath(path)
330-
mb_type_path = os.path.join(build_dir, 'mb_type')
329+
mb_type_path = self.PathJoin(build_dir, 'mb_type')
331330
needs_clobber = False
332331
new_mb_type = vals['type']
333332
if self.Exists(build_dir):
@@ -364,7 +363,7 @@ def RunGNGen(self, vals):
364363
# the compile targets to the matching GN labels.
365364
contents = self.ReadFile(self.args.swarming_targets_file)
366365
swarming_targets = contents.splitlines()
367-
gn_isolate_map = ast.literal_eval(self.ReadFile(os.path.join(
366+
gn_isolate_map = ast.literal_eval(self.ReadFile(self.PathJoin(
368367
self.chromium_src_dir, 'testing', 'buildbot', 'gn_isolate_map.pyl')))
369368
gn_labels = []
370369
for target in swarming_targets:
@@ -399,7 +398,7 @@ def RunGNGen(self, vals):
399398
runtime_deps_target = 'obj/%s.stamp' % label.replace(':', '/')
400399
else:
401400
runtime_deps_target = target
402-
if sys.platform == 'win32':
401+
if self.platform == 'win32':
403402
deps_path = self.ToAbsPath(path,
404403
runtime_deps_target + '.exe.runtime_deps')
405404
else:
@@ -426,9 +425,9 @@ def RunGNGen(self, vals):
426425
{
427426
'args': [
428427
'--isolated',
429-
self.ToSrcRelPath('%s%s%s.isolated' % (path, os.sep, target)),
428+
self.ToSrcRelPath('%s%s%s.isolated' % (path, self.sep, target)),
430429
'--isolate',
431-
self.ToSrcRelPath('%s%s%s.isolate' % (path, os.sep, target)),
430+
self.ToSrcRelPath('%s%s%s.isolate' % (path, self.sep, target)),
432431
],
433432
'dir': self.chromium_src_dir,
434433
'version': 1,
@@ -440,14 +439,12 @@ def RunGNGen(self, vals):
440439

441440
def GNCmd(self, subcommand, path, gn_args=''):
442441
if self.platform == 'linux2':
443-
gn_path = os.path.join(self.chromium_src_dir, 'buildtools', 'linux64',
444-
'gn')
442+
subdir = 'linux64'
445443
elif self.platform == 'darwin':
446-
gn_path = os.path.join(self.chromium_src_dir, 'buildtools', 'mac',
447-
'gn')
444+
subdir = 'mac'
448445
else:
449-
gn_path = os.path.join(self.chromium_src_dir, 'buildtools', 'win',
450-
'gn.exe')
446+
subdir = 'win'
447+
gn_path = self.PathJoin(self.chromium_src_dir, 'buildtools', subdir, 'gn')
451448

452449
cmd = [gn_path, subcommand, path]
453450
gn_args = gn_args.replace("$(goma_dir)", self.args.goma_dir)
@@ -458,12 +455,8 @@ def GNCmd(self, subcommand, path, gn_args=''):
458455
def RunGYPGen(self, vals):
459456
path = self.args.path[0]
460457

461-
output_dir, gyp_config = self.ParseGYPConfigPath(path)
462-
if gyp_config != vals['gyp_config']:
463-
raise MBErr('The last component of the path (%s) must match the '
464-
'GYP configuration specified in the config (%s), and '
465-
'it does not.' % (gyp_config, vals['gyp_config']))
466-
cmd = self.GYPCmd(output_dir, vals['gyp_defines'], config=gyp_config)
458+
output_dir = self.ParseGYPConfigPath(path)
459+
cmd = self.GYPCmd(output_dir, vals['gyp_defines'])
467460
env = None
468461
if vals['gyp_crosscompile']:
469462
if self.args.verbose:
@@ -474,19 +467,15 @@ def RunGYPGen(self, vals):
474467
return ret
475468

476469
def RunGYPAnalyze(self, vals):
477-
output_dir, gyp_config = self.ParseGYPConfigPath(self.args.path[0])
478-
if gyp_config != vals['gyp_config']:
479-
raise MBErr('The last component of the path (%s) must match the '
480-
'GYP configuration specified in the config (%s), and '
481-
'it does not.' % (gyp_config, vals['gyp_config']))
470+
output_dir = self.ParseGYPConfigPath(self.args.path[0])
482471
if self.args.verbose:
483472
inp = self.ReadInputJSON(['files', 'targets'])
484473
self.Print()
485474
self.Print('analyze input:')
486475
self.PrintJSON(inp)
487476
self.Print()
488477

489-
cmd = self.GYPCmd(output_dir, vals['gyp_defines'], config=gyp_config)
478+
cmd = self.GYPCmd(output_dir, vals['gyp_defines'])
490479
cmd.extend(['-f', 'analyzer',
491480
'-G', 'config_path=%s' % self.args.input_path[0],
492481
'-G', 'analyzer_output_path=%s' % self.args.output_path[0]])
@@ -504,15 +493,15 @@ def GetIsolateCommand(self, target, vals, gn_isolate_map):
504493
# This needs to mirror the settings in //build/config/ui.gni:
505494
# use_x11 = is_linux && !use_ozone.
506495
# TODO(dpranke): Figure out how to keep this in sync better.
507-
use_x11 = (sys.platform == 'linux2' and
496+
use_x11 = (self.platform == 'linux2' and
508497
not 'target_os="android"' in vals['gn_args'] and
509498
not 'use_ozone=true' in vals['gn_args'])
510499

511500
asan = 'is_asan=true' in vals['gn_args']
512501
msan = 'is_msan=true' in vals['gn_args']
513502
tsan = 'is_tsan=true' in vals['gn_args']
514503

515-
executable_suffix = '.exe' if sys.platform == 'win32' else ''
504+
executable_suffix = '.exe' if self.platform == 'win32' else ''
516505

517506
test_type = gn_isolate_map[target]['type']
518507
cmdline = []
@@ -580,38 +569,28 @@ def GetIsolateCommand(self, target, vals, gn_isolate_map):
580569
return cmdline, extra_files
581570

582571
def ToAbsPath(self, build_path, *comps):
583-
return os.path.join(self.chromium_src_dir,
584-
self.ToSrcRelPath(build_path),
585-
*comps)
572+
return self.PathJoin(self.chromium_src_dir,
573+
self.ToSrcRelPath(build_path),
574+
*comps)
586575

587576
def ToSrcRelPath(self, path):
588577
"""Returns a relative path from the top of the repo."""
589578
# TODO: Support normal paths in addition to source-absolute paths.
590579
assert(path.startswith('//'))
591-
return path[2:].replace('/', os.sep)
580+
return path[2:].replace('/', self.sep)
592581

593582
def ParseGYPConfigPath(self, path):
594583
rpath = self.ToSrcRelPath(path)
595-
output_dir, _, config = rpath.rpartition('/')
596-
self.CheckGYPConfigIsSupported(config, path)
597-
return output_dir, config
598-
599-
def CheckGYPConfigIsSupported(self, config, path):
600-
if config not in ('Debug', 'Release'):
601-
if (sys.platform in ('win32', 'cygwin') and
602-
config not in ('Debug_x64', 'Release_x64')):
603-
raise MBErr('Unknown or unsupported config type "%s" in "%s"' %
604-
config, path)
605-
606-
def GYPCmd(self, output_dir, gyp_defines, config):
584+
output_dir, _, _ = rpath.rpartition(self.sep)
585+
return output_dir
586+
587+
def GYPCmd(self, output_dir, gyp_defines):
607588
gyp_defines = gyp_defines.replace("$(goma_dir)", self.args.goma_dir)
608589
cmd = [
609-
sys.executable,
610-
os.path.join('build', 'gyp_chromium'),
590+
self.executable,
591+
self.PathJoin('build', 'gyp_chromium'),
611592
'-G',
612593
'output_dir=' + output_dir,
613-
'-G',
614-
'config=' + config,
615594
]
616595
for d in shlex.split(gyp_defines):
617596
cmd += ['-D', d]
@@ -667,7 +646,7 @@ def RunGNAnalyze(self, vals):
667646
if ret and not 'The input matches no targets' in out:
668647
self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out),
669648
output_path)
670-
build_dir = self.ToSrcRelPath(self.args.path[0]) + os.sep
649+
build_dir = self.ToSrcRelPath(self.args.path[0]) + self.sep
671650
for output in out.splitlines():
672651
build_output = output.replace(build_dir, '')
673652
if build_output in inp['targets']:
@@ -746,7 +725,7 @@ def WriteJSON(self, obj, path, force_verbose=False):
746725
(e, path))
747726

748727
def PrintCmd(self, cmd):
749-
if cmd[0] == sys.executable:
728+
if cmd[0] == self.executable:
750729
cmd = ['python'] + cmd[1:]
751730
self.Print(*[pipes.quote(c) for c in cmd])
752731

@@ -794,6 +773,10 @@ def MaybeMakeDirectory(self, path):
794773
if e.errno != errno.EEXIST:
795774
raise
796775

776+
def PathJoin(self, *comps):
777+
# This function largely exists so it can be overriden for testing.
778+
return os.path.join(*comps)
779+
797780
def ReadFile(self, path):
798781
# This function largely exists so it can be overriden for testing.
799782
with open(path) as fp:
@@ -804,7 +787,7 @@ def RemoveFile(self, path):
804787
os.remove(path)
805788

806789
def RemoveDirectory(self, abs_path):
807-
if sys.platform == 'win32':
790+
if self.platform == 'win32':
808791
# In other places in chromium, we often have to retry this command
809792
# because we're worried about other processes still holding on to
810793
# file handles, but when MB is invoked, it will be early enough in the

tools/mb/mb_config.pyl

-3
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@
159159

160160
'debug': {
161161
'gn_args': 'is_debug=true',
162-
'gyp_config': 'Debug',
163162
},
164163

165164
'debug_bot': {
@@ -254,12 +253,10 @@
254253
'official': {
255254
'gn_args': 'is_chrome_branded is_official_build=true is_debug=false is_component_build=false',
256255
'gyp_defines': 'branding="Chrome" buildtype="Official" component=static_library',
257-
'gyp_config': 'Release',
258256
},
259257

260258
'release': {
261259
'gn_args': 'is_debug=false',
262-
'gyp_config': 'Release',
263260
},
264261

265262
'release_bot': {

tools/mb/mb_unittest.py

+26-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import json
99
import StringIO
10+
import os
1011
import sys
1112
import unittest
1213

@@ -16,15 +17,20 @@
1617
class FakeMBW(mb.MetaBuildWrapper):
1718
def __init__(self):
1819
super(FakeMBW, self).__init__()
20+
21+
# Override vars for test portability.
22+
self.chromium_src_dir = '/fake_src'
23+
self.default_config = '/fake_src/tools/mb/mb_config.pyl'
24+
self.executable = 'python'
25+
self.platform = 'linux2'
26+
self.sep = '/'
27+
1928
self.files = {}
2029
self.calls = []
2130
self.cmds = []
2231
self.cross_compile = None
2332
self.out = ''
2433
self.err = ''
25-
self.platform = 'linux2'
26-
self.chromium_src_dir = '/fake_src'
27-
self.default_config = '/fake_src/tools/mb/mb_config.pyl'
2834
self.rmdirs = []
2935

3036
def ExpandUser(self, path):
@@ -36,6 +42,9 @@ def Exists(self, path):
3642
def MaybeMakeDirectory(self, path):
3743
self.files[path] = True
3844

45+
def PathJoin(self, *comps):
46+
return self.sep.join(comps)
47+
3948
def ReadFile(self, path):
4049
return self.files[path]
4150

@@ -121,11 +130,9 @@ def close(self):
121130
},
122131
'rel': {
123132
'gn_args': 'is_debug=false',
124-
'gyp_config': 'Release',
125133
},
126134
'debug': {
127135
'gn_args': 'is_debug=true',
128-
'gyp_config': 'Debug',
129136
},
130137
},
131138
'private_configs': ['private'],
@@ -166,7 +173,7 @@ def test_clobber(self):
166173
# The first time we run this, the build dir doesn't exist, so no clobber.
167174
self.check(['gen', '-c', 'gn_debug', '//out/Debug'], mbw=mbw, ret=0)
168175
self.assertEqual(mbw.rmdirs, [])
169-
self.assertTrue(mbw.files['/fake_src/out/Debug/mb_type'], 'gn')
176+
self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn')
170177

171178
# The second time we run this, the build dir exists and matches, so no
172179
# clobber.
@@ -294,7 +301,18 @@ def test_gyp_crosscompile(self):
294301
self.assertTrue(mbw.cross_compile)
295302

296303
def test_gyp_gen(self):
297-
self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0)
304+
self.check(['gen', '-c', 'gyp_rel_bot', '-g', '/goma', '//out/Release'],
305+
ret=0,
306+
out=("python build/gyp_chromium -G output_dir=out "
307+
"-D goma=1 -D gomadir=/goma\n"))
308+
309+
# simulate win32
310+
mbw = self.fake_mbw()
311+
mbw.sep = '\\'
312+
self.check(['gen', '-c', 'gyp_rel_bot', '-g', 'c:\\goma', '//out/Release'],
313+
mbw=mbw, ret=0,
314+
out=("python 'build\\gyp_chromium' -G output_dir=out "
315+
"-D goma=1 -D 'gomadir=c:\\goma'\n"))
298316

299317
def test_gyp_gen_fails(self):
300318
mbw = self.fake_mbw()
@@ -304,7 +322,7 @@ def test_gyp_gen_fails(self):
304322
def test_gyp_lookup_goma_dir_expansion(self):
305323
self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0,
306324
out=("python build/gyp_chromium -G 'output_dir=<path>' "
307-
"-G config=Release -D goma=1 -D gomadir=/foo\n"))
325+
"-D goma=1 -D gomadir=/foo\n"))
308326

309327
def test_help(self):
310328
orig_stdout = sys.stdout

0 commit comments

Comments
 (0)