 Chromium Code Reviews
 Chromium Code Reviews 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
    
  
    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| OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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=True): | 
| 
jeanluc1
2012/05/16 17:46:26
I would not provide a default but force caller to
 
scottmg
2012/05/16 17:56:37
Done.
 | |
| 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 Loading... | |
| 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 = 'call "$(ProjectDir)%(cygwin_dir)s\\setup_env.bat" && ' \ | 
| 277 'call "$(ProjectDir)%(cygwin_dir)s\\setup_env.bat" && ' | 277 if do_setup_env else '' | 
| 
jeanluc1
2012/05/16 17:46:26
I don't understand what this line does.  do_setup_
 
scottmg
2012/05/16 17:56:37
It's like ?: in C (in a misguided attempt to terse
 | |
| 278 'set CYGWIN=nontsec&& ') | 278 cmd += 'set CYGWIN=nontsec&& ' | 
| 279 if direct_cmd.find('NUMBER_OF_PROCESSORS') >= 0: | 279 if direct_cmd.find('NUMBER_OF_PROCESSORS') >= 0: | 
| 280 cmd += 'set /a NUMBER_OF_PROCESSORS_PLUS_1=%%NUMBER_OF_PROCESSORS%%+1&& ' | 280 cmd += 'set /a NUMBER_OF_PROCESSORS_PLUS_1=%%NUMBER_OF_PROCESSORS%%+1&& ' | 
| 281 if direct_cmd.find('INTDIR') >= 0: | 281 if direct_cmd.find('INTDIR') >= 0: | 
| 282 cmd += 'set INTDIR=$(IntDir)&& ' | 282 cmd += 'set INTDIR=$(IntDir)&& ' | 
| 283 if direct_cmd.find('OUTDIR') >= 0: | 283 if direct_cmd.find('OUTDIR') >= 0: | 
| 284 cmd += 'set OUTDIR=$(OutDir)&& ' | 284 cmd += 'set OUTDIR=$(OutDir)&& ' | 
| 285 if has_input_path and direct_cmd.find('INPUTPATH') >= 0: | 285 if has_input_path and direct_cmd.find('INPUTPATH') >= 0: | 
| 286 cmd += 'set INPUTPATH=$(InputPath) && ' | 286 cmd += 'set INPUTPATH=$(InputPath) && ' | 
| 287 cmd += 'bash -c "%(cmd)s"' | 287 cmd += 'bash -c "%(cmd)s"' | 
| 288 cmd = cmd % {'cygwin_dir': cygwin_dir, | 288 cmd = cmd % {'cygwin_dir': cygwin_dir, | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 300 arguments = [i.replace('$(InputDir)','%INPUTDIR%') for i in arguments] | 300 arguments = [i.replace('$(InputDir)','%INPUTDIR%') for i in arguments] | 
| 301 if quote_cmd: | 301 if quote_cmd: | 
| 302 # Support a mode for using cmd directly. | 302 # Support a mode for using cmd directly. | 
| 303 # Convert any paths to native form (first element is used directly). | 303 # Convert any paths to native form (first element is used directly). | 
| 304 # TODO(quote): regularize quoting path names throughout the module | 304 # TODO(quote): regularize quoting path names throughout the module | 
| 305 arguments = ['"%s"' % i for i in arguments] | 305 arguments = ['"%s"' % i for i in arguments] | 
| 306 # Collapse into a single command. | 306 # Collapse into a single command. | 
| 307 return input_dir_preamble + ' '.join(command + arguments) | 307 return input_dir_preamble + ' '.join(command + arguments) | 
| 308 | 308 | 
| 309 | 309 | 
| 310 def _BuildCommandLineForRule(spec, rule, has_input_path): | 310 def _BuildCommandLineForRule(spec, rule, has_input_path, do_setup_env=True): | 
| 311 # Find path to cygwin. | 311 # Find path to cygwin. | 
| 312 cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0]) | 312 cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0]) | 
| 313 | 313 | 
| 314 # Currently this weird argument munging is used to duplicate the way a | 314 # 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. | 315 # 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 | 316 # 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. | 317 # per project. For now the behavior chrome needs is the default. | 
| 318 mcs = rule.get('msvs_cygwin_shell') | 318 mcs = rule.get('msvs_cygwin_shell') | 
| 319 if mcs is None: | 319 if mcs is None: | 
| 320 mcs = int(spec.get('msvs_cygwin_shell', 1)) | 320 mcs = int(spec.get('msvs_cygwin_shell', 1)) | 
| 321 elif isinstance(mcs, str): | 321 elif isinstance(mcs, str): | 
| 322 mcs = int(mcs) | 322 mcs = int(mcs) | 
| 323 quote_cmd = int(rule.get('msvs_quote_cmd', 1)) | 323 quote_cmd = int(rule.get('msvs_quote_cmd', 1)) | 
| 324 return _BuildCommandLineForRuleRaw(spec, rule['action'], mcs, has_input_path, | 324 return _BuildCommandLineForRuleRaw(spec, rule['action'], mcs, has_input_path, | 
| 325 quote_cmd) | 325 quote_cmd, do_setup_env=do_setup_env) | 
| 326 | 326 | 
| 327 | 327 | 
| 328 def _AddActionStep(actions_dict, inputs, outputs, description, command): | 328 def _AddActionStep(actions_dict, inputs, outputs, description, command): | 
| 329 """Merge action into an existing list of actions. | 329 """Merge action into an existing list of actions. | 
| 330 | 330 | 
| 331 Care must be taken so that actions which have overlapping inputs either don't | 331 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. | 332 get assigned to the same input, or get collapsed into one. | 
| 333 | 333 | 
| 334 Arguments: | 334 Arguments: | 
| 335 actions_dict: dictionary keyed on input name, which maps to a list of | 335 actions_dict: dictionary keyed on input name, which maps to a list of | 
| (...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1437 _ConfigFullName(config_name, config), | 1437 _ConfigFullName(config_name, config), | 
| 1438 {}, tools=[tool]) | 1438 {}, tools=[tool]) | 
| 1439 # Do nothing if there was no precompiled source. | 1439 # Do nothing if there was no precompiled source. | 
| 1440 if extensions_excluded_from_precompile: | 1440 if extensions_excluded_from_precompile: | 
| 1441 DisableForSourceTree(sources) | 1441 DisableForSourceTree(sources) | 
| 1442 | 1442 | 
| 1443 | 1443 | 
| 1444 def _AddActions(actions_to_add, spec, relative_path_of_gyp_file): | 1444 def _AddActions(actions_to_add, spec, relative_path_of_gyp_file): | 
| 1445 # Add actions. | 1445 # Add actions. | 
| 1446 actions = spec.get('actions', []) | 1446 actions = spec.get('actions', []) | 
| 1447 # Don't setup_env every time, or when all the actions are run together in | |
| 
jeanluc1
2012/05/16 17:46:26
-->  Don't setup_env every time.  When
 
scottmg
2012/05/16 17:56:37
Done.
 | |
| 1448 # one batch file in VS, the PATH will grow too long. | |
| 1449 first_action = True | |
| 1447 for a in actions: | 1450 for a in actions: | 
| 1448 cmd = _BuildCommandLineForRule(spec, a, has_input_path=False) | 1451 cmd = _BuildCommandLineForRule(spec, a, has_input_path=False, | 
| 1452 do_setup_env=first_action) | |
| 1449 # Attach actions to the gyp file if nothing else is there. | 1453 # Attach actions to the gyp file if nothing else is there. | 
| 1450 inputs = a.get('inputs') or [relative_path_of_gyp_file] | 1454 inputs = a.get('inputs') or [relative_path_of_gyp_file] | 
| 1451 # Add the action. | 1455 # Add the action. | 
| 1452 _AddActionStep(actions_to_add, | 1456 _AddActionStep(actions_to_add, | 
| 1453 inputs=inputs, | 1457 inputs=inputs, | 
| 1454 outputs=a.get('outputs', []), | 1458 outputs=a.get('outputs', []), | 
| 1455 description=a.get('message', a['action_name']), | 1459 description=a.get('message', a['action_name']), | 
| 1456 command=cmd) | 1460 command=cmd) | 
| 1461 first_action = False | |
| 1457 | 1462 | 
| 1458 | 1463 | 
| 1459 def _WriteMSVSUserFile(project_path, version, spec): | 1464 def _WriteMSVSUserFile(project_path, version, spec): | 
| 1460 # Add run_as and test targets. | 1465 # Add run_as and test targets. | 
| 1461 if 'run_as' in spec: | 1466 if 'run_as' in spec: | 
| 1462 run_as = spec['run_as'] | 1467 run_as = spec['run_as'] | 
| 1463 action = run_as.get('action', []) | 1468 action = run_as.get('action', []) | 
| 1464 environment = run_as.get('environment', []) | 1469 environment = run_as.get('environment', []) | 
| 1465 working_directory = run_as.get('working_directory', '.') | 1470 working_directory = run_as.get('working_directory', '.') | 
| 1466 elif int(spec.get('test', 0)): | 1471 elif int(spec.get('test', 0)): | 
| (...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3014 cmd = action['command'] | 3019 cmd = action['command'] | 
| 3015 # For most actions, add 'call' so that actions that invoke batch files | 3020 # For most actions, add 'call' so that actions that invoke batch files | 
| 3016 # return and continue executing. msbuild_use_call provides a way to | 3021 # 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 | 3022 # disable this but I have not seen any adverse effect from doing that | 
| 3018 # for everything. | 3023 # for everything. | 
| 3019 if action.get('msbuild_use_call', True): | 3024 if action.get('msbuild_use_call', True): | 
| 3020 cmd = 'call ' + cmd | 3025 cmd = 'call ' + cmd | 
| 3021 commands.append(cmd) | 3026 commands.append(cmd) | 
| 3022 # Add the custom build action for one input file. | 3027 # Add the custom build action for one input file. | 
| 3023 description = ', and also '.join(descriptions) | 3028 description = ', and also '.join(descriptions) | 
| 3024 command = ' && '.join(commands) | 3029 | 
| 3030 # We can't join the commands simply with && because the command line will | |
| 3031 # get too long. See also _AddActions: cygwin's setup_env mustn't be called | |
| 3032 # for every invocation or the command that sets the PATH will grow too | |
| 3033 # long. | |
| 3034 command = ( | |
| 3035 '\r\nif %errorlevel% neq 0 exit /b %errorlevel%\r\n'.join(commands)) | |
| 3025 _AddMSBuildAction(spec, | 3036 _AddMSBuildAction(spec, | 
| 3026 primary_input, | 3037 primary_input, | 
| 3027 inputs, | 3038 inputs, | 
| 3028 outputs, | 3039 outputs, | 
| 3029 command, | 3040 command, | 
| 3030 description, | 3041 description, | 
| 3031 sources_handled_by_action, | 3042 sources_handled_by_action, | 
| 3032 actions_spec) | 3043 actions_spec) | 
| 3033 return actions_spec, sources_handled_by_action | 3044 return actions_spec, sources_handled_by_action | 
| 3034 | 3045 | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 3047 action_spec.extend( | 3058 action_spec.extend( | 
| 3048 # TODO(jeanluc) 'Document' for all or just if as_sources? | 3059 # TODO(jeanluc) 'Document' for all or just if as_sources? | 
| 3049 [['FileType', 'Document'], | 3060 [['FileType', 'Document'], | 
| 3050 ['Command', command], | 3061 ['Command', command], | 
| 3051 ['Message', description], | 3062 ['Message', description], | 
| 3052 ['Outputs', outputs] | 3063 ['Outputs', outputs] | 
| 3053 ]) | 3064 ]) | 
| 3054 if additional_inputs: | 3065 if additional_inputs: | 
| 3055 action_spec.append(['AdditionalInputs', additional_inputs]) | 3066 action_spec.append(['AdditionalInputs', additional_inputs]) | 
| 3056 actions_spec.append(action_spec) | 3067 actions_spec.append(action_spec) | 
| OLD | NEW |