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): |
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 = '' |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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) |
OLD | NEW |