Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: pylib/gyp/generator/msvs.py

Issue 10341003: msvs: fix many actions on the same script resulting in too-long command lines (Closed) Base URL: https://gyp.googlecode.com/svn/trunk
Patch Set: verify outputs are created, non-default arg a bit higher Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import copy 5 import copy
6 import ntpath 6 import ntpath
7 import os 7 import os
8 import posixpath 8 import posixpath
9 import re 9 import re
10 import subprocess 10 import subprocess
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 else: 235 else:
236 return config_name 236 return config_name
237 237
238 238
239 def _ConfigFullName(config_name, config_data): 239 def _ConfigFullName(config_name, config_data):
240 platform_name = _ConfigPlatform(config_data) 240 platform_name = _ConfigPlatform(config_data)
241 return '%s|%s' % (_ConfigBaseName(config_name, platform_name), platform_name) 241 return '%s|%s' % (_ConfigBaseName(config_name, platform_name), platform_name)
242 242
243 243
244 def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path, 244 def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path,
245 quote_cmd): 245 quote_cmd, do_setup_env):
246 246
247 if [x for x in cmd if '$(InputDir)' in x]: 247 if [x for x in cmd if '$(InputDir)' in x]:
248 input_dir_preamble = ( 248 input_dir_preamble = (
249 'set INPUTDIR=$(InputDir)\n' 249 'set INPUTDIR=$(InputDir)\n'
250 'set INPUTDIR=%INPUTDIR:$(ProjectDir)=%\n' 250 'set INPUTDIR=%INPUTDIR:$(ProjectDir)=%\n'
251 'set INPUTDIR=%INPUTDIR:~0,-1%\n' 251 'set INPUTDIR=%INPUTDIR:~0,-1%\n'
252 ) 252 )
253 else: 253 else:
254 input_dir_preamble = '' 254 input_dir_preamble = ''
255 255
(...skipping 10 matching lines...) Expand all
266 '`cygpath -m "${INPUTDIR}"`') for i in direct_cmd] 266 '`cygpath -m "${INPUTDIR}"`') for i in direct_cmd]
267 if has_input_path: 267 if has_input_path:
268 direct_cmd = [i.replace('$(InputPath)', 268 direct_cmd = [i.replace('$(InputPath)',
269 '`cygpath -m "${INPUTPATH}"`') 269 '`cygpath -m "${INPUTPATH}"`')
270 for i in direct_cmd] 270 for i in direct_cmd]
271 direct_cmd = ['"%s"' % i for i in direct_cmd] 271 direct_cmd = ['"%s"' % i for i in direct_cmd]
272 direct_cmd = [i.replace('"', '\\"') for i in direct_cmd] 272 direct_cmd = [i.replace('"', '\\"') for i in direct_cmd]
273 #direct_cmd = gyp.common.EncodePOSIXShellList(direct_cmd) 273 #direct_cmd = gyp.common.EncodePOSIXShellList(direct_cmd)
274 direct_cmd = ' '.join(direct_cmd) 274 direct_cmd = ' '.join(direct_cmd)
275 # TODO(quote): regularize quoting path names throughout the module 275 # TODO(quote): regularize quoting path names throughout the module
276 cmd = ( 276 cmd = ''
277 'call "$(ProjectDir)%(cygwin_dir)s\\setup_env.bat" && ' 277 if do_setup_env:
278 'set CYGWIN=nontsec&& ') 278 cmd += 'call "$(ProjectDir)%(cygwin_dir)s\\setup_env.bat" && '
279 cmd += 'set CYGWIN=nontsec&& '
279 if direct_cmd.find('NUMBER_OF_PROCESSORS') >= 0: 280 if direct_cmd.find('NUMBER_OF_PROCESSORS') >= 0:
280 cmd += 'set /a NUMBER_OF_PROCESSORS_PLUS_1=%%NUMBER_OF_PROCESSORS%%+1&& ' 281 cmd += 'set /a NUMBER_OF_PROCESSORS_PLUS_1=%%NUMBER_OF_PROCESSORS%%+1&& '
281 if direct_cmd.find('INTDIR') >= 0: 282 if direct_cmd.find('INTDIR') >= 0:
282 cmd += 'set INTDIR=$(IntDir)&& ' 283 cmd += 'set INTDIR=$(IntDir)&& '
283 if direct_cmd.find('OUTDIR') >= 0: 284 if direct_cmd.find('OUTDIR') >= 0:
284 cmd += 'set OUTDIR=$(OutDir)&& ' 285 cmd += 'set OUTDIR=$(OutDir)&& '
285 if has_input_path and direct_cmd.find('INPUTPATH') >= 0: 286 if has_input_path and direct_cmd.find('INPUTPATH') >= 0:
286 cmd += 'set INPUTPATH=$(InputPath) && ' 287 cmd += 'set INPUTPATH=$(InputPath) && '
287 cmd += 'bash -c "%(cmd)s"' 288 cmd += 'bash -c "%(cmd)s"'
288 cmd = cmd % {'cygwin_dir': cygwin_dir, 289 cmd = cmd % {'cygwin_dir': cygwin_dir,
(...skipping 11 matching lines...) Expand all
300 arguments = [i.replace('$(InputDir)','%INPUTDIR%') for i in arguments] 301 arguments = [i.replace('$(InputDir)','%INPUTDIR%') for i in arguments]
301 if quote_cmd: 302 if quote_cmd:
302 # Support a mode for using cmd directly. 303 # Support a mode for using cmd directly.
303 # Convert any paths to native form (first element is used directly). 304 # Convert any paths to native form (first element is used directly).
304 # TODO(quote): regularize quoting path names throughout the module 305 # TODO(quote): regularize quoting path names throughout the module
305 arguments = ['"%s"' % i for i in arguments] 306 arguments = ['"%s"' % i for i in arguments]
306 # Collapse into a single command. 307 # Collapse into a single command.
307 return input_dir_preamble + ' '.join(command + arguments) 308 return input_dir_preamble + ' '.join(command + arguments)
308 309
309 310
310 def _BuildCommandLineForRule(spec, rule, has_input_path): 311 def _BuildCommandLineForRule(spec, rule, has_input_path, do_setup_env):
311 # Find path to cygwin. 312 # Find path to cygwin.
312 cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0]) 313 cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0])
313 314
314 # Currently this weird argument munging is used to duplicate the way a 315 # Currently this weird argument munging is used to duplicate the way a
315 # python script would need to be run as part of the chrome tree. 316 # python script would need to be run as part of the chrome tree.
316 # Eventually we should add some sort of rule_default option to set this 317 # Eventually we should add some sort of rule_default option to set this
317 # per project. For now the behavior chrome needs is the default. 318 # per project. For now the behavior chrome needs is the default.
318 mcs = rule.get('msvs_cygwin_shell') 319 mcs = rule.get('msvs_cygwin_shell')
319 if mcs is None: 320 if mcs is None:
320 mcs = int(spec.get('msvs_cygwin_shell', 1)) 321 mcs = int(spec.get('msvs_cygwin_shell', 1))
321 elif isinstance(mcs, str): 322 elif isinstance(mcs, str):
322 mcs = int(mcs) 323 mcs = int(mcs)
323 quote_cmd = int(rule.get('msvs_quote_cmd', 1)) 324 quote_cmd = int(rule.get('msvs_quote_cmd', 1))
324 return _BuildCommandLineForRuleRaw(spec, rule['action'], mcs, has_input_path, 325 return _BuildCommandLineForRuleRaw(spec, rule['action'], mcs, has_input_path,
325 quote_cmd) 326 quote_cmd, do_setup_env=do_setup_env)
326 327
327 328
328 def _AddActionStep(actions_dict, inputs, outputs, description, command): 329 def _AddActionStep(actions_dict, inputs, outputs, description, command):
329 """Merge action into an existing list of actions. 330 """Merge action into an existing list of actions.
330 331
331 Care must be taken so that actions which have overlapping inputs either don't 332 Care must be taken so that actions which have overlapping inputs either don't
332 get assigned to the same input, or get collapsed into one. 333 get assigned to the same input, or get collapsed into one.
333 334
334 Arguments: 335 Arguments:
335 actions_dict: dictionary keyed on input name, which maps to a list of 336 actions_dict: dictionary keyed on input name, which maps to a list of
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 rules_filename = '%s%s.rules' % (spec['target_name'], 485 rules_filename = '%s%s.rules' % (spec['target_name'],
485 options.suffix) 486 options.suffix)
486 rules_file = MSVSToolFile.Writer(os.path.join(output_dir, rules_filename), 487 rules_file = MSVSToolFile.Writer(os.path.join(output_dir, rules_filename),
487 spec['target_name']) 488 spec['target_name'])
488 # Add each rule. 489 # Add each rule.
489 for r in rules: 490 for r in rules:
490 rule_name = r['rule_name'] 491 rule_name = r['rule_name']
491 rule_ext = r['extension'] 492 rule_ext = r['extension']
492 inputs = _FixPaths(r.get('inputs', [])) 493 inputs = _FixPaths(r.get('inputs', []))
493 outputs = _FixPaths(r.get('outputs', [])) 494 outputs = _FixPaths(r.get('outputs', []))
494 cmd = _BuildCommandLineForRule(spec, r, has_input_path=True) 495 cmd = _BuildCommandLineForRule(spec, r, has_input_path=True,
496 do_setup_env=True)
495 rules_file.AddCustomBuildRule(name=rule_name, 497 rules_file.AddCustomBuildRule(name=rule_name,
496 description=r.get('message', rule_name), 498 description=r.get('message', rule_name),
497 extensions=[rule_ext], 499 extensions=[rule_ext],
498 additional_dependencies=inputs, 500 additional_dependencies=inputs,
499 outputs=outputs, 501 outputs=outputs,
500 cmd=cmd) 502 cmd=cmd)
501 # Write out rules file. 503 # Write out rules file.
502 rules_file.WriteIfChanged() 504 rules_file.WriteIfChanged()
503 505
504 # Add rules file to project. 506 # Add rules file to project.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 mk_file.close() 574 mk_file.close()
573 575
574 # Add makefile to list of sources. 576 # Add makefile to list of sources.
575 sources.add(filename) 577 sources.add(filename)
576 # Add a build action to call makefile. 578 # Add a build action to call makefile.
577 cmd = ['make', 579 cmd = ['make',
578 'OutDir=$(OutDir)', 580 'OutDir=$(OutDir)',
579 'IntDir=$(IntDir)', 581 'IntDir=$(IntDir)',
580 '-j', '${NUMBER_OF_PROCESSORS_PLUS_1}', 582 '-j', '${NUMBER_OF_PROCESSORS_PLUS_1}',
581 '-f', filename] 583 '-f', filename]
582 cmd = _BuildCommandLineForRuleRaw(spec, cmd, True, False, True) 584 cmd = _BuildCommandLineForRuleRaw(spec, cmd, True, False, True, True)
583 # Insert makefile as 0'th input, so it gets the action attached there, 585 # Insert makefile as 0'th input, so it gets the action attached there,
584 # as this is easier to understand from in the IDE. 586 # as this is easier to understand from in the IDE.
585 all_inputs = list(all_inputs) 587 all_inputs = list(all_inputs)
586 all_inputs.insert(0, filename) 588 all_inputs.insert(0, filename)
587 _AddActionStep(actions_to_add, 589 _AddActionStep(actions_to_add,
588 inputs=_FixPaths(all_inputs), 590 inputs=_FixPaths(all_inputs),
589 outputs=_FixPaths(all_outputs), 591 outputs=_FixPaths(all_outputs),
590 description='Running %s' % cmd, 592 description='Running %s' % cmd,
591 command=cmd) 593 command=cmd)
592 594
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 _ConfigFullName(config_name, config), 1439 _ConfigFullName(config_name, config),
1438 {}, tools=[tool]) 1440 {}, tools=[tool])
1439 # Do nothing if there was no precompiled source. 1441 # Do nothing if there was no precompiled source.
1440 if extensions_excluded_from_precompile: 1442 if extensions_excluded_from_precompile:
1441 DisableForSourceTree(sources) 1443 DisableForSourceTree(sources)
1442 1444
1443 1445
1444 def _AddActions(actions_to_add, spec, relative_path_of_gyp_file): 1446 def _AddActions(actions_to_add, spec, relative_path_of_gyp_file):
1445 # Add actions. 1447 # Add actions.
1446 actions = spec.get('actions', []) 1448 actions = spec.get('actions', [])
1449 # Don't setup_env every time. When all the actions are run together in one
1450 # batch file in VS, the PATH will grow too long.
1451 first_action = True
1447 for a in actions: 1452 for a in actions:
1448 cmd = _BuildCommandLineForRule(spec, a, has_input_path=False) 1453 cmd = _BuildCommandLineForRule(spec, a, has_input_path=False,
1454 do_setup_env=first_action)
1449 # Attach actions to the gyp file if nothing else is there. 1455 # Attach actions to the gyp file if nothing else is there.
1450 inputs = a.get('inputs') or [relative_path_of_gyp_file] 1456 inputs = a.get('inputs') or [relative_path_of_gyp_file]
1451 # Add the action. 1457 # Add the action.
1452 _AddActionStep(actions_to_add, 1458 _AddActionStep(actions_to_add,
1453 inputs=inputs, 1459 inputs=inputs,
1454 outputs=a.get('outputs', []), 1460 outputs=a.get('outputs', []),
1455 description=a.get('message', a['action_name']), 1461 description=a.get('message', a['action_name']),
1456 command=cmd) 1462 command=cmd)
1463 first_action = False
1457 1464
1458 1465
1459 def _WriteMSVSUserFile(project_path, version, spec): 1466 def _WriteMSVSUserFile(project_path, version, spec):
1460 # Add run_as and test targets. 1467 # Add run_as and test targets.
1461 if 'run_as' in spec: 1468 if 'run_as' in spec:
1462 run_as = spec['run_as'] 1469 run_as = spec['run_as']
1463 action = run_as.get('action', []) 1470 action = run_as.get('action', [])
1464 environment = run_as.get('environment', []) 1471 environment = run_as.get('environment', [])
1465 working_directory = run_as.get('working_directory', '.') 1472 working_directory = run_as.get('working_directory', '.')
1466 elif int(spec.get('test', 0)): 1473 elif int(spec.get('test', 0)):
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 2000
1994 self.description = MSVSSettings.ConvertVCMacrosToMSBuild( 2001 self.description = MSVSSettings.ConvertVCMacrosToMSBuild(
1995 rule.get('message', self.rule_name)) 2002 rule.get('message', self.rule_name))
1996 old_additional_dependencies = _FixPaths(rule.get('inputs', [])) 2003 old_additional_dependencies = _FixPaths(rule.get('inputs', []))
1997 self.additional_dependencies = ( 2004 self.additional_dependencies = (
1998 ';'.join([MSVSSettings.ConvertVCMacrosToMSBuild(i) 2005 ';'.join([MSVSSettings.ConvertVCMacrosToMSBuild(i)
1999 for i in old_additional_dependencies])) 2006 for i in old_additional_dependencies]))
2000 old_outputs = _FixPaths(rule.get('outputs', [])) 2007 old_outputs = _FixPaths(rule.get('outputs', []))
2001 self.outputs = ';'.join([MSVSSettings.ConvertVCMacrosToMSBuild(i) 2008 self.outputs = ';'.join([MSVSSettings.ConvertVCMacrosToMSBuild(i)
2002 for i in old_outputs]) 2009 for i in old_outputs])
2003 old_command = _BuildCommandLineForRule(spec, rule, has_input_path=True) 2010 old_command = _BuildCommandLineForRule(spec, rule, has_input_path=True,
2011 do_setup_env=True)
2004 self.command = MSVSSettings.ConvertVCMacrosToMSBuild(old_command) 2012 self.command = MSVSSettings.ConvertVCMacrosToMSBuild(old_command)
2005 2013
2006 2014
2007 def _GenerateMSBuildRulePropsFile(props_path, msbuild_rules): 2015 def _GenerateMSBuildRulePropsFile(props_path, msbuild_rules):
2008 """Generate the .props file.""" 2016 """Generate the .props file."""
2009 content = ['Project', 2017 content = ['Project',
2010 {'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'}] 2018 {'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'}]
2011 for rule in msbuild_rules: 2019 for rule in msbuild_rules:
2012 content.extend([ 2020 content.extend([
2013 ['PropertyGroup', 2021 ['PropertyGroup',
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after
3014 cmd = action['command'] 3022 cmd = action['command']
3015 # For most actions, add 'call' so that actions that invoke batch files 3023 # For most actions, add 'call' so that actions that invoke batch files
3016 # return and continue executing. msbuild_use_call provides a way to 3024 # return and continue executing. msbuild_use_call provides a way to
3017 # disable this but I have not seen any adverse effect from doing that 3025 # disable this but I have not seen any adverse effect from doing that
3018 # for everything. 3026 # for everything.
3019 if action.get('msbuild_use_call', True): 3027 if action.get('msbuild_use_call', True):
3020 cmd = 'call ' + cmd 3028 cmd = 'call ' + cmd
3021 commands.append(cmd) 3029 commands.append(cmd)
3022 # Add the custom build action for one input file. 3030 # Add the custom build action for one input file.
3023 description = ', and also '.join(descriptions) 3031 description = ', and also '.join(descriptions)
3024 command = ' && '.join(commands) 3032
3033 # We can't join the commands simply with && because the command line will
3034 # get too long. See also _AddActions: cygwin's setup_env mustn't be called
3035 # for every invocation or the command that sets the PATH will grow too
3036 # long.
3037 command = (
3038 '\r\nif %errorlevel% neq 0 exit /b %errorlevel%\r\n'.join(commands))
3025 _AddMSBuildAction(spec, 3039 _AddMSBuildAction(spec,
3026 primary_input, 3040 primary_input,
3027 inputs, 3041 inputs,
3028 outputs, 3042 outputs,
3029 command, 3043 command,
3030 description, 3044 description,
3031 sources_handled_by_action, 3045 sources_handled_by_action,
3032 actions_spec) 3046 actions_spec)
3033 return actions_spec, sources_handled_by_action 3047 return actions_spec, sources_handled_by_action
3034 3048
(...skipping 12 matching lines...) Expand all
3047 action_spec.extend( 3061 action_spec.extend(
3048 # TODO(jeanluc) 'Document' for all or just if as_sources? 3062 # TODO(jeanluc) 'Document' for all or just if as_sources?
3049 [['FileType', 'Document'], 3063 [['FileType', 'Document'],
3050 ['Command', command], 3064 ['Command', command],
3051 ['Message', description], 3065 ['Message', description],
3052 ['Outputs', outputs] 3066 ['Outputs', outputs]
3053 ]) 3067 ])
3054 if additional_inputs: 3068 if additional_inputs:
3055 action_spec.append(['AdditionalInputs', additional_inputs]) 3069 action_spec.append(['AdditionalInputs', additional_inputs])
3056 actions_spec.append(action_spec) 3070 actions_spec.append(action_spec)
OLDNEW
« no previous file with comments | « no previous file | test/many-actions/gyptest-many-actions.py » ('j') | test/many-actions/many-actions.gyp » ('J')

Powered by Google App Engine
This is Rietveld 408576698