Skip to content

Commit be4ecdf

Browse files
committed
src: fix multi-output-actions bug in make
1 parent 949e8bb commit be4ecdf

File tree

8 files changed

+167
-159
lines changed

8 files changed

+167
-159
lines changed

pylib/gyp/MakefileWriter.py

Lines changed: 119 additions & 116 deletions
Large diffs are not rendered by default.

pylib/gyp/common.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ def RelativePath(path, relative_to, follow_path_symlink=True):
152152
return path
153153

154154
rel = os.path.relpath(path, relative_to)
155+
if rel == '.':
156+
rel = ''
155157
return rel
156158

157159

pylib/gyp/generator/make.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from __future__ import print_function
2424

2525
import os
26+
import posixpath as path
2627
import re
2728
import subprocess
2829
import gyp
@@ -221,7 +222,7 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files,
221222

222223
gyp_binary = gyp.common.FixIfRelativePath(params['gyp_binary'], options.toplevel_dir)
223224
if not gyp_binary.startswith(os.sep):
224-
gyp_binary = os.path.join('.', gyp_binary)
225+
gyp_binary = path.join('.', gyp_binary)
225226

226227
root_makefile.write(
227228
"quiet_cmd_regen_makefile = ACTION Regenerating $@\n"
@@ -261,12 +262,12 @@ def CalculateMakefilePath(build_file_arg, base_name):
261262
# paths relative to the source root for the master makefile. Grab
262263
# the path of the .gyp file as the base to relativize against.
263264
# E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp".
264-
base_makefile_path = gyp.common.RelativePath(os.path.dirname(build_file_arg), options.depth)
265+
base_makefile_path = gyp.common.RelativePath(path.dirname(build_file_arg), options.depth)
265266
# We write the file in the base_makefile_path directory.
266-
output_makefile = os.path.join(options.depth, base_makefile_path, base_name)
267+
output_makefile = path.join(options.depth, base_makefile_path, base_name)
267268
if options.generator_output:
268-
output_makefile = os.path.join(options.depth, options.generator_output, base_makefile_path, base_name)
269-
base_makefile_path = gyp.common.RelativePath(os.path.dirname(build_file_arg), options.toplevel_dir)
269+
output_makefile = path.join(options.depth, options.generator_output, base_makefile_path, base_name)
270+
base_makefile_path = gyp.common.RelativePath(path.dirname(build_file_arg), options.toplevel_dir)
270271
return base_makefile_path, output_makefile
271272

272273
# TODO: search for the first non-'Default' target. This can go
@@ -284,9 +285,9 @@ def CalculateMakefilePath(build_file_arg, base_name):
284285

285286
srcdir = '.'
286287
makefile_name = 'Makefile' + options.suffix
287-
makefile_path = os.path.join(options.toplevel_dir, makefile_name)
288+
makefile_path = path.join(options.toplevel_dir, makefile_name)
288289
if options.generator_output:
289-
makefile_path = os.path.join(options.toplevel_dir, options.generator_output, makefile_name)
290+
makefile_path = path.join(options.toplevel_dir, options.generator_output, makefile_name)
290291
srcdir = gyp.common.RelativePath(srcdir, options.generator_output)
291292
Sourceify.srcdir_prefix = '$(srcdir)/'
292293

@@ -407,7 +408,7 @@ def CalculateMakefilePath(build_file_arg, base_name):
407408
WriteRootHeaderSuffixRules(root_makefile)
408409

409410
# Put build-time support tools next to the root Makefile.
410-
dest_path = os.path.dirname(makefile_path)
411+
dest_path = path.dirname(makefile_path)
411412
gyp.common.CopyTool(flavor, dest_path)
412413

413414
# Find the list of targets that derive from the gyp file(s) being built.
@@ -437,7 +438,7 @@ def CalculateMakefilePath(build_file_arg, base_name):
437438
gyp.common.UnrelativePath(included_file, build_file),
438439
options.toplevel_dir
439440
)
440-
abs_include_file = os.path.abspath(relative_include_file)
441+
abs_include_file = path.abspath(relative_include_file)
441442
# If the include file is from the ~/.gyp dir, we should use absolute path
442443
# so that relocating the src dir doesn't break the path.
443444
if params['home_dot_gyp'] and abs_include_file.startswith(params['home_dot_gyp']):
@@ -458,7 +459,7 @@ def CalculateMakefilePath(build_file_arg, base_name):
458459

459460
# Our root_makefile lives at the source root. Compute the relative path
460461
# from there to the output_file for including.
461-
mkfile_rel_path = gyp.common.RelativePath(output_file, os.path.dirname(makefile_path))
462+
mkfile_rel_path = gyp.common.RelativePath(output_file, path.dirname(makefile_path))
462463
include_list.add(mkfile_rel_path)
463464

464465
assert writer
@@ -468,14 +469,14 @@ def CalculateMakefilePath(build_file_arg, base_name):
468469
# The paths in build_files were relativized above, so undo that before
469470
# testing against the non-relativized items in target_list and before
470471
# calculating the Makefile path.
471-
build_file_path = os.path.join(depth_rel_path, build_file)
472+
build_file_path = path.join(depth_rel_path, build_file)
472473
related_gyp_targets = [t for t in target_list if t.startswith(build_file) and t in needed_targets]
473474
# Only generate Makefiles for gyp files with targets.
474475
if not related_gyp_targets:
475476
continue
476-
build_file_name = "%s.Makefile" % os.path.splitext(os.path.basename(build_file))[0]
477+
build_file_name = "%s.Makefile" % path.splitext(path.basename(build_file))[0]
477478
_, submake_output_file = CalculateMakefilePath(build_file_path, build_file_name)
478-
makefile_rel_path = gyp.common.RelativePath(os.path.dirname(makefile_path), os.path.dirname(submake_output_file))
479+
makefile_rel_path = gyp.common.RelativePath(path.dirname(makefile_path), path.dirname(submake_output_file))
479480
gyp_targets_names = [target_dicts[t]['target_name'] for t in related_gyp_targets]
480481
writer.WriteSubMake(submake_output_file, makefile_rel_path, gyp_targets_names, builddir_name)
481482

@@ -547,7 +548,7 @@ def CalculateGeneratorInputInfo(params):
547548
output_dir = params['options'].generator_output or \
548549
params['options'].toplevel_dir
549550
builddir_name = generator_flags.get('output_dir', 'out')
550-
qualified_out_dir = os.path.normpath(os.path.join(
551+
qualified_out_dir = path.normpath(path.join(
551552
output_dir, builddir_name, 'gypfiles'))
552553

553554
global generator_filelist_paths

test/actions-multiple-outputs-with-dependencies/gyptest-action.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# found in the LICENSE file.
66

77
"""
8-
Verifies actions with multiple outputs & dependncies will correctly rebuild.
8+
Verifies actions with multiple outputs & dependencies will correctly rebuild.
99
1010
This is a regression test for crrev.com/1177163002.
1111
"""
@@ -17,10 +17,6 @@
1717
import sys
1818
import time
1919

20-
if sys.platform in ('darwin', 'win32'):
21-
print("This test is currently disabled: https://crbug.com/483696.")
22-
sys.exit(0)
23-
2420
test = TestGyp.TestGyp()
2521

2622
TESTDIR='relocate/src'
@@ -30,6 +26,7 @@
3026
def build_and_check(content):
3127
test.write(TESTDIR + '/input.txt', content)
3228
test.build('action.gyp', 'upper', chdir=TESTDIR)
29+
test.up_to_date('action.gyp', 'upper', chdir=TESTDIR)
3330
test.built_file_must_match('result.txt', content, chdir=TESTDIR)
3431

3532
build_and_check('Content for first build.')

test/actions-multiple-outputs-with-dependencies/src/action.gyp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@
1717
{
1818
'target_name': 'lower',
1919
'type': 'none',
20-
'actions': [{
21-
'action_name': 'lower_action',
22-
'inputs': ['input.txt'],
23-
'outputs': ['<(PRODUCT_DIR)/out1.txt', '<(PRODUCT_DIR)/out2.txt'],
24-
'action': ['python', 'rcopy.py', '<@(_inputs)', '<@(_outputs)'],
25-
}],
20+
'actions': [
21+
{
22+
'action_name': 'lower_action',
23+
'external': 'true',
24+
'inputs': ['input.txt'],
25+
'outputs': ['<(PRODUCT_DIR)/out1.txt', '<(PRODUCT_DIR)/out2.txt'],
26+
'action': ['python', 'rcopy.py', '<@(_inputs)', '<@(_outputs)'],
27+
},
28+
{
29+
'action_name': 'lower_action2',
30+
'inputs': ['input.txt'],
31+
'outputs': ['<(PRODUCT_DIR)/out2.1.txt'],
32+
'action': ['python', 'rcopy.py', '<@(_inputs)', '<@(_outputs)'],
33+
}],
2634
},
2735
],
2836
}
Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
1-
#!/usr/bin/env python
2-
3-
# Copyright (c) 2015 Google Inc. All rights reserved.
4-
# Use of this source code is governed by a BSD-style license that can be
5-
# found in the LICENSE file.
6-
71
"""
82
Verifies actions with multiple outputs will correctly rebuild.
93
"""
104

11-
from __future__ import print_function
12-
135
import TestGyp
146
import os
15-
import sys
16-
17-
if sys.platform == 'win32':
18-
print("This test is currently disabled: https://crbug.com/483696.")
19-
sys.exit(0)
207

218
test = TestGyp.TestGyp()
229

@@ -28,6 +15,7 @@
2815
def build_and_check():
2916
# Build + check that both outputs exist.
3017
test.build('multiple-outputs.gyp', chdir=chdir)
18+
test.up_to_date('action.gyp', chdir=chdir)
3119
test.built_file_must_exist('out1.txt', chdir=chdir)
3220
test.built_file_must_exist('out2.txt', chdir=chdir)
3321

@@ -36,10 +24,10 @@ def build_and_check():
3624

3725
# Remove either + rebuild. Both should exist (again).
3826
os.remove(test.built_file_path('out1.txt', chdir=chdir))
39-
build_and_check();
27+
build_and_check()
4028

4129
# Remove the other + rebuild. Both should exist (again).
4230
os.remove(test.built_file_path('out2.txt', chdir=chdir))
43-
build_and_check();
31+
build_and_check()
4432

4533
test.pass_test()

test/actions-multiple-outputs/src/multiple-outputs.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'actions': [
1111
{
1212
'action_name': 'action1',
13+
'external': 'true',
1314
'inputs': [],
1415
'outputs': [
1516
'<(PRODUCT_DIR)/out1.txt',

test/lib/TestGyp.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,22 @@ def match_modulo_line_numbers(contents_a, contents_b):
5454
return TestCommon.match_exact(contents_a, contents_b)
5555

5656

57-
def mk_temp_dir(workdir):
57+
def mk_temp_dir(workdir, hint=''):
5858
# Put test output in out/testworkarea by default.
5959
# Use temporary names so there are no collisions.
6060
workdir = workdir or 'testworkarea'
6161
workdir = os.path.join('out', workdir)
6262
# Create work area if it doesn't already exist.
6363
if not os.path.isdir(workdir):
6464
os.makedirs(workdir)
65-
return tempfile.mktemp(prefix='testgyp.', dir=workdir)
65+
if hint:
66+
slug = re.sub(r'[/.\\]', '_', hint)
67+
dir_name = os.path.join(workdir, slug)
68+
if os.path.exists(dir_name):
69+
shutil.rmtree(dir_name)
70+
return dir_name
71+
else:
72+
return tempfile.mktemp(prefix='testgyp.', dir=workdir)
6673

6774

6875
@contextmanager
@@ -131,7 +138,8 @@ def __init__(self, gyp=None, **kw):
131138
if 'description' not in kw:
132139
bt = [t[0] for t in traceback.extract_stack() if 'gyptest' in t[0]]
133140
kw['description'] = bt and bt.pop()
134-
kw['workdir'] = mk_temp_dir(kw.get('workdir'))
141+
kw_workdir = kw.get('workdir')
142+
kw['workdir'] = mk_temp_dir(kw_workdir, kw['description'])
135143
kw_formats = kw.pop('formats', [])
136144

137145
if not gyp:

0 commit comments

Comments
 (0)