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 gyp | 6 import gyp |
7 import gyp.common | 7 import gyp.common |
8 import gyp.msvs_emulation | 8 import gyp.msvs_emulation |
9 import gyp.system_test | 9 import gyp.system_test |
10 import gyp.xcode_emulation | 10 import gyp.xcode_emulation |
| 11 import json |
11 import os.path | 12 import os.path |
12 import re | 13 import re |
13 import subprocess | 14 import subprocess |
14 import sys | 15 import sys |
15 | 16 |
16 import gyp.ninja_syntax as ninja_syntax | 17 import gyp.ninja_syntax as ninja_syntax |
17 | 18 |
18 generator_default_variables = { | 19 generator_default_variables = { |
19 'EXECUTABLE_PREFIX': '', | 20 'EXECUTABLE_PREFIX': '', |
20 'EXECUTABLE_SUFFIX': '', | 21 'EXECUTABLE_SUFFIX': '', |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' | 210 INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' |
210 if INTERMEDIATE_DIR in path: | 211 if INTERMEDIATE_DIR in path: |
211 int_dir = self.GypPathToUniqueOutput('gen') | 212 int_dir = self.GypPathToUniqueOutput('gen') |
212 # GypPathToUniqueOutput generates a path relative to the product dir, | 213 # GypPathToUniqueOutput generates a path relative to the product dir, |
213 # so insert product_dir in front if it is provided. | 214 # so insert product_dir in front if it is provided. |
214 path = path.replace(INTERMEDIATE_DIR, | 215 path = path.replace(INTERMEDIATE_DIR, |
215 os.path.join(product_dir or '', int_dir)) | 216 os.path.join(product_dir or '', int_dir)) |
216 | 217 |
217 if self.flavor == 'win': | 218 if self.flavor == 'win': |
218 # Don't use os.path.normpath here. Callers pass in './foo' and expect | 219 # Don't use os.path.normpath here. Callers pass in './foo' and expect |
219 # the result to be runnable, but normpath removes the prefix. | 220 # the result to be runnable, but normpath removes the prefix. If the |
| 221 # variable is $! prefixed on Windows, don't modify it (used for compiler |
| 222 # flags, etc.) |
| 223 if path.startswith('$!'): |
| 224 return path[2:] |
220 return path.replace('/', '\\') | 225 return path.replace('/', '\\') |
221 return path | 226 return path |
222 | 227 |
223 def ExpandRuleVariables(self, path, root, dirname, source, ext, name): | 228 def ExpandRuleVariables(self, path, root, dirname, source, ext, name): |
224 path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root) | 229 path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root) |
225 path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'], | 230 path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'], |
226 dirname) | 231 dirname) |
227 path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source) | 232 path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source) |
228 path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext) | 233 path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext) |
229 path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name) | 234 path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 Returns None if there are no outputs (e.g. a settings-only 'none' type | 301 Returns None if there are no outputs (e.g. a settings-only 'none' type |
297 target).""" | 302 target).""" |
298 | 303 |
299 self.config_name = config_name | 304 self.config_name = config_name |
300 self.name = spec['target_name'] | 305 self.name = spec['target_name'] |
301 self.toolset = spec['toolset'] | 306 self.toolset = spec['toolset'] |
302 config = spec['configurations'][config_name] | 307 config = spec['configurations'][config_name] |
303 self.target = Target(spec['type']) | 308 self.target = Target(spec['type']) |
304 | 309 |
305 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) | 310 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) |
| 311 self.xcode_settings = self.msvs_settings = None |
306 if self.flavor == 'mac': | 312 if self.flavor == 'mac': |
307 self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) | 313 self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) |
308 else: | 314 if self.flavor == 'win': |
309 self.xcode_settings = None | 315 self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec) |
310 | 316 |
311 # Compute predepends for all rules. | 317 # Compute predepends for all rules. |
312 # actions_depends is the dependencies this target depends on before running | 318 # actions_depends is the dependencies this target depends on before running |
313 # any of its action/rule/copy steps. | 319 # any of its action/rule/copy steps. |
314 # compile_depends is the dependencies this target depends on before running | 320 # compile_depends is the dependencies this target depends on before running |
315 # any of its compile steps. | 321 # any of its compile steps. |
316 actions_depends = [] | 322 actions_depends = [] |
317 compile_depends = [] | 323 compile_depends = [] |
318 # TODO(evan): it is rather confusing which things are lists and which | 324 # TODO(evan): it is rather confusing which things are lists and which |
319 # are strings. Fix these. | 325 # are strings. Fix these. |
(...skipping 24 matching lines...) Expand all Loading... |
344 # otherwise we depend on dependent target's actions/rules/copies etc. | 350 # otherwise we depend on dependent target's actions/rules/copies etc. |
345 # We never need to explicitly depend on previous target's link steps, | 351 # We never need to explicitly depend on previous target's link steps, |
346 # because no compile ever depends on them. | 352 # because no compile ever depends on them. |
347 compile_depends_stamp = (self.target.actions_stamp or compile_depends) | 353 compile_depends_stamp = (self.target.actions_stamp or compile_depends) |
348 | 354 |
349 # Write out the compilation steps, if any. | 355 # Write out the compilation steps, if any. |
350 link_deps = [] | 356 link_deps = [] |
351 sources = spec.get('sources', []) + extra_sources | 357 sources = spec.get('sources', []) + extra_sources |
352 if sources: | 358 if sources: |
353 link_deps = self.WriteSources( | 359 link_deps = self.WriteSources( |
354 config_name, config, sources, compile_depends_stamp, | 360 config_name, config, sources, compile_depends_stamp, spec, |
355 gyp.xcode_emulation.MacPrefixHeader( | 361 gyp.xcode_emulation.MacPrefixHeader( |
356 self.xcode_settings, self.GypPathToNinja, | 362 self.xcode_settings, self.GypPathToNinja, |
357 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) | 363 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) |
358 # Some actions/rules output 'sources' that are already object files. | 364 # Some actions/rules output 'sources' that are already object files. |
359 link_deps += [self.GypPathToNinja(f) | 365 link_deps += [self.GypPathToNinja(f) |
360 for f in sources if f.endswith(self.obj_ext)] | 366 for f in sources if f.endswith(self.obj_ext)] |
361 | 367 |
362 # Write out a link step, if needed. | 368 # Write out a link step, if needed. |
363 output = None | 369 output = None |
364 if link_deps or self.target.actions_stamp or actions_depends: | 370 if link_deps or self.target.actions_stamp or actions_depends: |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 # Actions cd into the base directory. | 434 # Actions cd into the base directory. |
429 env = self.GetXcodeEnv() | 435 env = self.GetXcodeEnv() |
430 all_outputs = [] | 436 all_outputs = [] |
431 for action in actions: | 437 for action in actions: |
432 # First write out a rule for the action. | 438 # First write out a rule for the action. |
433 name = re.sub(r'[ {}$]', '_', action['action_name']) | 439 name = re.sub(r'[ {}$]', '_', action['action_name']) |
434 description = self.GenerateDescription('ACTION', | 440 description = self.GenerateDescription('ACTION', |
435 action.get('message', None), | 441 action.get('message', None), |
436 name) | 442 name) |
437 rule_name = self.WriteNewNinjaRule(name, action['action'], description, | 443 rule_name = self.WriteNewNinjaRule(name, action['action'], description, |
438 env=env) | 444 env=env, rule=action) |
439 | 445 |
440 inputs = [self.GypPathToNinja(i, env) for i in action['inputs']] | 446 if self.flavor == 'win': |
| 447 inputs = [self.msvs_settings.ConvertVSMacros(i) |
| 448 for i in action['inputs']] |
| 449 else: |
| 450 inputs = actions['inputs'] |
| 451 inputs = [self.GypPathToNinja(i, env) for i in inputs] |
441 if int(action.get('process_outputs_as_sources', False)): | 452 if int(action.get('process_outputs_as_sources', False)): |
442 extra_sources += action['outputs'] | 453 extra_sources += action['outputs'] |
443 if int(action.get('process_outputs_as_mac_bundle_resources', False)): | 454 if int(action.get('process_outputs_as_mac_bundle_resources', False)): |
444 extra_mac_bundle_resources += action['outputs'] | 455 extra_mac_bundle_resources += action['outputs'] |
445 outputs = [self.GypPathToNinja(o, env) for o in action['outputs']] | 456 if self.flavor == 'win': |
| 457 outputs = [self.msvs_settings.ConvertVSMacros(i) |
| 458 for i in action['outputs']] |
| 459 else: |
| 460 outputs = action['outputs'] |
| 461 outputs = [self.GypPathToNinja(o, env) for o in outputs] |
446 | 462 |
447 # Then write out an edge using the rule. | 463 # Then write out an edge using the rule. |
448 self.ninja.build(outputs, rule_name, inputs, | 464 self.ninja.build(outputs, rule_name, inputs, |
449 order_only=prebuild) | 465 order_only=prebuild) |
450 all_outputs += outputs | 466 all_outputs += outputs |
451 | 467 |
452 self.ninja.newline() | 468 self.ninja.newline() |
453 | 469 |
454 return all_outputs | 470 return all_outputs |
455 | 471 |
456 def WriteRules(self, rules, extra_sources, prebuild, | 472 def WriteRules(self, rules, extra_sources, prebuild, |
457 extra_mac_bundle_resources): | 473 extra_mac_bundle_resources): |
458 all_outputs = [] | 474 all_outputs = [] |
459 for rule in rules: | 475 for rule in rules: |
460 # First write out a rule for the rule action. | 476 # First write out a rule for the rule action. |
461 name = rule['rule_name'] | 477 name = rule['rule_name'] |
462 args = rule['action'] | 478 args = rule['action'] |
463 description = self.GenerateDescription( | 479 description = self.GenerateDescription( |
464 'RULE', | 480 'RULE', |
465 rule.get('message', None), | 481 rule.get('message', None), |
466 ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name) | 482 ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name) |
467 rule_name = self.WriteNewNinjaRule(name, args, description) | 483 rule_name = self.WriteNewNinjaRule(name, args, description, rule=rule) |
468 | 484 |
469 # TODO: if the command references the outputs directly, we should | 485 # TODO: if the command references the outputs directly, we should |
470 # simplify it to just use $out. | 486 # simplify it to just use $out. |
471 | 487 |
472 # Rules can potentially make use of some special variables which | 488 # Rules can potentially make use of some special variables which |
473 # must vary per source file. | 489 # must vary per source file. |
474 # Compute the list of variables we'll need to provide. | 490 # Compute the list of variables we'll need to provide. |
475 special_locals = ('source', 'root', 'dirname', 'ext', 'name') | 491 special_locals = ('source', 'root', 'dirname', 'ext', 'name') |
476 needed_variables = set(['source']) | 492 needed_variables = set(['source']) |
477 for argument in args: | 493 for argument in args: |
478 for var in special_locals: | 494 for var in special_locals: |
479 if ('${%s}' % var) in argument: | 495 if ('${%s}' % var) in argument: |
480 needed_variables.add(var) | 496 needed_variables.add(var) |
481 | 497 |
| 498 is_cygwin = gyp.msvs_emulation.IsRuleRunUnderCygwin(rule) |
| 499 def cygwin_munge(path): |
| 500 if is_cygwin: |
| 501 return path.replace('\\', '/') |
| 502 return path |
| 503 |
482 # For each source file, write an edge that generates all the outputs. | 504 # For each source file, write an edge that generates all the outputs. |
483 for source in rule.get('rule_sources', []): | 505 for source in rule.get('rule_sources', []): |
484 dirname, basename = os.path.split(source) | 506 dirname, basename = os.path.split(source) |
485 root, ext = os.path.splitext(basename) | 507 root, ext = os.path.splitext(basename) |
486 | 508 |
487 # Gather the list of outputs, expanding $vars if possible. | 509 # Gather the list of outputs, expanding $vars if possible. |
488 outputs = [] | 510 outputs = [] |
489 for output in rule['outputs']: | 511 for output in rule['outputs']: |
490 outputs.append(self.ExpandRuleVariables(output, root, dirname, | 512 outputs.append(self.ExpandRuleVariables(output, root, dirname, |
491 source, ext, basename)) | 513 source, ext, basename)) |
492 | 514 |
493 if int(rule.get('process_outputs_as_sources', False)): | 515 if int(rule.get('process_outputs_as_sources', False)): |
494 extra_sources += outputs | 516 extra_sources += outputs |
495 if int(rule.get('process_outputs_as_mac_bundle_resources', False)): | 517 if int(rule.get('process_outputs_as_mac_bundle_resources', False)): |
496 extra_mac_bundle_resources += outputs | 518 extra_mac_bundle_resources += outputs |
497 | 519 |
498 extra_bindings = [] | 520 extra_bindings = [] |
499 for var in needed_variables: | 521 for var in needed_variables: |
500 if var == 'root': | 522 if var == 'root': |
501 extra_bindings.append(('root', root)) | 523 extra_bindings.append(('root', cygwin_munge(root))) |
502 elif var == 'dirname': | 524 elif var == 'dirname': |
503 extra_bindings.append(('dirname', dirname)) | 525 extra_bindings.append(('dirname', cygwin_munge(dirname))) |
504 elif var == 'source': | 526 elif var == 'source': |
505 # '$source' is a parameter to the rule action, which means | 527 # '$source' is a parameter to the rule action, which means |
506 # it shouldn't be converted to a Ninja path. But we don't | 528 # it shouldn't be converted to a Ninja path. But we don't |
507 # want $!PRODUCT_DIR in there either. | 529 # want $!PRODUCT_DIR in there either. |
508 source_expanded = self.ExpandSpecial(source, self.base_to_build) | 530 source_expanded = self.ExpandSpecial(source, self.base_to_build) |
509 extra_bindings.append(('source', source_expanded)) | 531 extra_bindings.append(('source', cygwin_munge(source_expanded))) |
510 elif var == 'ext': | 532 elif var == 'ext': |
511 extra_bindings.append(('ext', ext)) | 533 extra_bindings.append(('ext', cygwin_munge(ext))) |
512 elif var == 'name': | 534 elif var == 'name': |
513 extra_bindings.append(('name', basename)) | 535 extra_bindings.append(('name', basename)) |
514 else: | 536 else: |
515 assert var == None, repr(var) | 537 assert var == None, repr(var) |
516 | 538 |
517 inputs = map(self.GypPathToNinja, rule.get('inputs', [])) | 539 inputs = [] |
| 540 for input in rule.get('inputs', []): |
| 541 inputs.append(self.ExpandRuleVariables(input, root, dirname, source, |
| 542 ext, basename)) |
| 543 inputs = map(self.GypPathToNinja, inputs) |
518 outputs = map(self.GypPathToNinja, outputs) | 544 outputs = map(self.GypPathToNinja, outputs) |
519 self.ninja.build(outputs, rule_name, self.GypPathToNinja(source), | 545 self.ninja.build(outputs, rule_name, self.GypPathToNinja(source), |
520 implicit=inputs, | 546 implicit=inputs, |
521 order_only=prebuild, | 547 order_only=prebuild, |
522 variables=extra_bindings) | 548 variables=extra_bindings) |
523 | 549 |
524 all_outputs.extend(outputs) | 550 all_outputs.extend(outputs) |
525 | 551 |
526 return all_outputs | 552 return all_outputs |
527 | 553 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 variables=[('defines',defines)]) | 593 variables=[('defines',defines)]) |
568 | 594 |
569 env = self.GetXcodeEnv(additional_settings=extra_env) | 595 env = self.GetXcodeEnv(additional_settings=extra_env) |
570 env = self.ComputeExportEnvString(env) | 596 env = self.ComputeExportEnvString(env) |
571 | 597 |
572 self.ninja.build(out, 'mac_tool', info_plist, | 598 self.ninja.build(out, 'mac_tool', info_plist, |
573 variables=[('mactool_cmd', 'copy-info-plist'), | 599 variables=[('mactool_cmd', 'copy-info-plist'), |
574 ('env', env)]) | 600 ('env', env)]) |
575 bundle_depends.append(out) | 601 bundle_depends.append(out) |
576 | 602 |
577 def WriteSources(self, config_name, config, sources, predepends, | 603 def WriteSources(self, config_name, config, sources, predepends, spec, |
578 precompiled_header): | 604 precompiled_header): |
579 """Write build rules to compile all of |sources|.""" | 605 """Write build rules to compile all of |sources|.""" |
580 if self.toolset == 'target': | 606 if self.toolset == 'target': |
581 self.ninja.variable('ar', '$ar_target') | 607 self.ninja.variable('ar', '$ar_target') |
582 self.ninja.variable('cc', '$cc_target') | 608 self.ninja.variable('cc', '$cc_target') |
583 self.ninja.variable('cxx', '$cxx_target') | 609 self.ninja.variable('cxx', '$cxx_target') |
584 self.ninja.variable('ld', '$ld_target') | 610 self.ninja.variable('ld', '$ld_target') |
585 | 611 |
| 612 extra_defines = [] |
586 if self.flavor == 'mac': | 613 if self.flavor == 'mac': |
587 cflags = self.xcode_settings.GetCflags(config_name) | 614 cflags = self.xcode_settings.GetCflags(config_name) |
588 cflags_c = self.xcode_settings.GetCflagsC(config_name) | 615 cflags_c = self.xcode_settings.GetCflagsC(config_name) |
589 cflags_cc = self.xcode_settings.GetCflagsCC(config_name) | 616 cflags_cc = self.xcode_settings.GetCflagsCC(config_name) |
590 cflags_objc = ['$cflags_c'] + \ | 617 cflags_objc = ['$cflags_c'] + \ |
591 self.xcode_settings.GetCflagsObjC(config_name) | 618 self.xcode_settings.GetCflagsObjC(config_name) |
592 cflags_objcc = ['$cflags_cc'] + \ | 619 cflags_objcc = ['$cflags_cc'] + \ |
593 self.xcode_settings.GetCflagsObjCC(config_name) | 620 self.xcode_settings.GetCflagsObjCC(config_name) |
| 621 elif self.flavor == 'win': |
| 622 cflags = self.msvs_settings.GetCflags(config_name) |
| 623 cflags_c = self.msvs_settings.GetCflagsC(config_name) |
| 624 cflags_cc = self.msvs_settings.GetCflagsCC(config_name) |
| 625 extra_defines = self.msvs_settings.GetComputedDefines(config_name) |
| 626 self.msvs_settings.HandleIdlFiles( |
| 627 self.ninja, spec, sources, config_name, |
| 628 self.GypPathToNinja, |
| 629 self.GypPathToUniqueOutput, |
| 630 self.ExpandRuleVariables) |
594 else: | 631 else: |
595 cflags = config.get('cflags', []) | 632 cflags = config.get('cflags', []) |
596 cflags_c = config.get('cflags_c', []) | 633 cflags_c = config.get('cflags_c', []) |
597 cflags_cc = config.get('cflags_cc', []) | 634 cflags_cc = config.get('cflags_cc', []) |
598 | 635 |
| 636 defines = config.get('defines', []) + extra_defines |
599 self.WriteVariableList('defines', | 637 self.WriteVariableList('defines', |
600 [QuoteShellArgument(ninja_syntax.escape('-D' + d), self.flavor) | 638 [QuoteShellArgument(ninja_syntax.escape('-D' + d), self.flavor) |
601 for d in config.get('defines', [])]) | 639 for d in defines]) |
| 640 include_dirs = config.get('include_dirs', []) |
| 641 if self.flavor == 'win': |
| 642 include_dirs = self.msvs_settings.AdjustIncludeDirs(include_dirs, |
| 643 config_name) |
602 self.WriteVariableList('includes', | 644 self.WriteVariableList('includes', |
603 ['-I' + self.GypPathToNinja(i) | 645 [QuoteShellArgument('-I' + self.GypPathToNinja(i), self.flavor) |
604 for i in config.get('include_dirs', [])]) | 646 for i in include_dirs]) |
605 | 647 |
606 pch_commands = precompiled_header.GetGchBuildCommands() | 648 pch_commands = precompiled_header.GetGchBuildCommands() |
607 if self.flavor == 'mac': | 649 if self.flavor == 'mac': |
608 self.WriteVariableList('cflags_pch_c', | 650 self.WriteVariableList('cflags_pch_c', |
609 [precompiled_header.GetInclude('c')]) | 651 [precompiled_header.GetInclude('c')]) |
610 self.WriteVariableList('cflags_pch_cc', | 652 self.WriteVariableList('cflags_pch_cc', |
611 [precompiled_header.GetInclude('cc')]) | 653 [precompiled_header.GetInclude('cc')]) |
612 self.WriteVariableList('cflags_pch_objc', | 654 self.WriteVariableList('cflags_pch_objc', |
613 [precompiled_header.GetInclude('m')]) | 655 [precompiled_header.GetInclude('m')]) |
614 self.WriteVariableList('cflags_pch_objcc', | 656 self.WriteVariableList('cflags_pch_objcc', |
(...skipping 14 matching lines...) Expand all Loading... |
629 ext = ext[1:] | 671 ext = ext[1:] |
630 if ext in ('cc', 'cpp', 'cxx'): | 672 if ext in ('cc', 'cpp', 'cxx'): |
631 command = 'cxx' | 673 command = 'cxx' |
632 elif ext in ('c', 's', 'S'): | 674 elif ext in ('c', 's', 'S'): |
633 command = 'cc' | 675 command = 'cc' |
634 elif self.flavor == 'mac' and ext == 'm': | 676 elif self.flavor == 'mac' and ext == 'm': |
635 command = 'objc' | 677 command = 'objc' |
636 elif self.flavor == 'mac' and ext == 'mm': | 678 elif self.flavor == 'mac' and ext == 'mm': |
637 command = 'objcxx' | 679 command = 'objcxx' |
638 else: | 680 else: |
639 # TODO: should we assert here on unexpected extensions? | |
640 continue | 681 continue |
641 input = self.GypPathToNinja(source) | 682 input = self.GypPathToNinja(source) |
642 output = self.GypPathToUniqueOutput(filename + self.obj_ext) | 683 output = self.GypPathToUniqueOutput(filename + self.obj_ext) |
643 implicit = precompiled_header.GetObjDependencies([input], [output]) | 684 implicit = precompiled_header.GetObjDependencies([input], [output]) |
644 self.ninja.build(output, command, input, | 685 self.ninja.build(output, command, input, |
645 implicit=[gch for _, _, gch in implicit], | 686 implicit=[gch for _, _, gch in implicit], |
646 order_only=predepends) | 687 order_only=predepends) |
647 outputs.append(output) | 688 outputs.append(output) |
648 | 689 |
649 self.WritePchTargets(pch_commands) | 690 self.WritePchTargets(pch_commands) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 output = self.ComputeMacBundleBinaryOutput() | 745 output = self.ComputeMacBundleBinaryOutput() |
705 else: | 746 else: |
706 output = self.ComputeOutput(spec) | 747 output = self.ComputeOutput(spec) |
707 extra_bindings.append(('postbuilds', | 748 extra_bindings.append(('postbuilds', |
708 self.GetPostbuildCommand(spec, output, output))) | 749 self.GetPostbuildCommand(spec, output, output))) |
709 | 750 |
710 if self.flavor == 'mac': | 751 if self.flavor == 'mac': |
711 ldflags = self.xcode_settings.GetLdflags(config_name, | 752 ldflags = self.xcode_settings.GetLdflags(config_name, |
712 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), | 753 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
713 self.GypPathToNinja) | 754 self.GypPathToNinja) |
| 755 elif self.flavor == 'win': |
| 756 ldflags = self.msvs_settings.GetLdflags(config_name, spec, |
| 757 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
| 758 self.GypPathToNinja) |
| 759 libflags = self.msvs_settings.GetLibFlags(config_name, spec) |
| 760 self.WriteVariableList('libflags', |
| 761 gyp.common.uniquer(map(self.ExpandSpecial, |
| 762 libflags))) |
714 else: | 763 else: |
715 ldflags = config.get('ldflags', []) | 764 ldflags = config.get('ldflags', []) |
716 self.WriteVariableList('ldflags', | 765 self.WriteVariableList('ldflags', |
717 gyp.common.uniquer(map(self.ExpandSpecial, | 766 gyp.common.uniquer(map(self.ExpandSpecial, |
718 ldflags))) | 767 ldflags))) |
719 | 768 |
720 libraries = gyp.common.uniquer(map(self.ExpandSpecial, | 769 libraries = gyp.common.uniquer(map(self.ExpandSpecial, |
721 spec.get('libraries', []))) | 770 spec.get('libraries', []))) |
722 if self.flavor == 'mac': | 771 if self.flavor == 'mac': |
723 libraries = self.xcode_settings.AdjustLibraries(libraries) | 772 libraries = self.xcode_settings.AdjustLibraries(libraries) |
| 773 elif self.flavor == 'win': |
| 774 libraries = self.msvs_settings.AdjustLibraries(libraries) |
724 self.WriteVariableList('libs', libraries) | 775 self.WriteVariableList('libs', libraries) |
725 | 776 |
726 self.target.binary = output | 777 self.target.binary = output |
727 | 778 |
728 if command in ('solink', 'solink_module'): | 779 if command in ('solink', 'solink_module'): |
729 extra_bindings.append(('soname', os.path.split(output)[1])) | 780 extra_bindings.append(('soname', os.path.split(output)[1])) |
730 if self.flavor == 'win': | 781 if self.flavor == 'win': |
731 import_lib = output + '.lib' | 782 import_lib = output + '.lib' |
732 extra_bindings.append(('dll', output)) | 783 extra_bindings.append(('dll', output)) |
733 extra_bindings.append(('implib', import_lib)) | 784 extra_bindings.append(('implib', import_lib)) |
| 785 output = [output, import_lib] |
734 self.target.binary = import_lib | 786 self.target.binary = import_lib |
735 output = [output, import_lib] | |
736 | 787 |
737 self.ninja.build(output, command, link_deps, | 788 self.ninja.build(output, command, link_deps, |
738 implicit=list(implicit_deps), | 789 implicit=list(implicit_deps), |
739 variables=extra_bindings) | 790 variables=extra_bindings) |
740 | 791 |
741 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): | 792 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): |
742 if spec['type'] == 'none': | 793 if spec['type'] == 'none': |
743 # TODO(evan): don't call this function for 'none' target types, as | 794 # TODO(evan): don't call this function for 'none' target types, as |
744 # it doesn't do anything, and we fake out a 'binary' with a stamp file. | 795 # it doesn't do anything, and we fake out a 'binary' with a stamp file. |
745 self.target.binary = compile_deps | 796 self.target.binary = compile_deps |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 libdir = os.path.join('lib', '%s' % self.toolset) | 978 libdir = os.path.join('lib', '%s' % self.toolset) |
928 return os.path.join(libdir, filename) | 979 return os.path.join(libdir, filename) |
929 else: | 980 else: |
930 return self.GypPathToUniqueOutput(filename, qualified=False) | 981 return self.GypPathToUniqueOutput(filename, qualified=False) |
931 | 982 |
932 def WriteVariableList(self, var, values): | 983 def WriteVariableList(self, var, values): |
933 if values is None: | 984 if values is None: |
934 values = [] | 985 values = [] |
935 self.ninja.variable(var, ' '.join(values)) | 986 self.ninja.variable(var, ' '.join(values)) |
936 | 987 |
937 def WriteNewNinjaRule(self, name, args, description, env={}): | 988 def WriteNewNinjaRule(self, name, args, description, env={}, rule=None): |
938 """Write out a new ninja "rule" statement for a given command. | 989 """Write out a new ninja "rule" statement for a given command. |
939 | 990 |
940 Returns the name of the new rule.""" | 991 Returns the name of the new rule.""" |
941 | 992 |
942 # TODO: we shouldn't need to qualify names; we do it because | 993 # TODO: we shouldn't need to qualify names; we do it because |
943 # currently the ninja rule namespace is global, but it really | 994 # currently the ninja rule namespace is global, but it really |
944 # should be scoped to the subninja. | 995 # should be scoped to the subninja. |
945 rule_name = self.name | 996 rule_name = self.name |
946 if self.toolset == 'target': | 997 if self.toolset == 'target': |
947 rule_name += '.' + self.toolset | 998 rule_name += '.' + self.toolset |
948 rule_name += '.' + name | 999 rule_name += '.' + name |
949 rule_name = rule_name.replace(' ', '_') | 1000 rule_name = rule_name.replace(' ', '_') |
950 | 1001 |
951 args = args[:] | 1002 args = args[:] |
952 | 1003 |
| 1004 is_cygwin = rule and int(rule.get('msvs_cygwin_shell', 1)) |
| 1005 |
953 # gyp dictates that commands are run from the base directory. | 1006 # gyp dictates that commands are run from the base directory. |
954 # cd into the directory before running, and adjust paths in | 1007 # cd into the directory before running, and adjust paths in |
955 # the arguments to point to the proper locations. | 1008 # the arguments to point to the proper locations. |
956 if self.flavor == 'win': | 1009 if self.flavor == 'win': |
957 cd = 'cmd /s /c "cd %s && ' % self.build_to_base | 1010 cd = 'cmd /s /c "' |
| 1011 if not is_cygwin: |
| 1012 cd += 'cd %s && ' % self.build_to_base |
958 else: | 1013 else: |
959 cd = 'cd %s; ' % self.build_to_base | 1014 cd = 'cd %s; ' % self.build_to_base |
960 args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args] | 1015 args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args] |
961 env = self.ComputeExportEnvString(env) | 1016 env = self.ComputeExportEnvString(env) |
962 if self.flavor == 'win': | 1017 if self.flavor == 'win': |
963 # TODO(scottmg): Respect msvs_cygwin setting here. | 1018 if is_cygwin: |
964 # If there's no command, fake one to match the dangling |&&| above. | 1019 command = gyp.msvs_emulation.BuildCygwinBashCommandLine( |
965 command = gyp.msvs_emulation.EncodeCmdExeList(args) or 'cmd /c' | 1020 self.msvs_settings, rule, args, self.build_to_base, self.config_name
) |
| 1021 else: |
| 1022 # If there's no command, fake one to match the dangling |&&| above. |
| 1023 command = self.msvs_settings.EncodeCmdExeList(args) or 'cmd /c' |
966 else: | 1024 else: |
967 command = gyp.common.EncodePOSIXShellList(args) | 1025 command = gyp.common.EncodePOSIXShellList(args) |
968 if env: | 1026 if env: |
969 # If an environment is passed in, variables in the command should be | 1027 # If an environment is passed in, variables in the command should be |
970 # read from it, instead of from ninja's internal variables. | 1028 # read from it, instead of from ninja's internal variables. |
971 command = ninja_syntax.escape(command) | 1029 command = ninja_syntax.escape(command) |
972 | 1030 |
973 command = cd + env + command | 1031 command = cd + env + command |
974 # GYP rules/actions express being no-ops by not touching their outputs. | 1032 # GYP rules/actions express being no-ops by not touching their outputs. |
975 # Avoid executing downstream dependencies in this case by specifying | 1033 # Avoid executing downstream dependencies in this case by specifying |
(...skipping 28 matching lines...) Expand all Loading... |
1004 global generator_extra_sources_for_rules | 1062 global generator_extra_sources_for_rules |
1005 generator_extra_sources_for_rules = getattr(xcode_generator, | 1063 generator_extra_sources_for_rules = getattr(xcode_generator, |
1006 'generator_extra_sources_for_rules', []) | 1064 'generator_extra_sources_for_rules', []) |
1007 elif flavor == 'win': | 1065 elif flavor == 'win': |
1008 default_variables.setdefault('OS', 'win') | 1066 default_variables.setdefault('OS', 'win') |
1009 default_variables['EXECUTABLE_SUFFIX'] = '.exe' | 1067 default_variables['EXECUTABLE_SUFFIX'] = '.exe' |
1010 default_variables['STATIC_LIB_PREFIX'] = '' | 1068 default_variables['STATIC_LIB_PREFIX'] = '' |
1011 default_variables['STATIC_LIB_SUFFIX'] = '.lib' | 1069 default_variables['STATIC_LIB_SUFFIX'] = '.lib' |
1012 default_variables['SHARED_LIB_PREFIX'] = '' | 1070 default_variables['SHARED_LIB_PREFIX'] = '' |
1013 default_variables['SHARED_LIB_SUFFIX'] = '.dll' | 1071 default_variables['SHARED_LIB_SUFFIX'] = '.dll' |
| 1072 generator_flags = params.get('generator_flags', {}) |
| 1073 msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags) |
| 1074 |
| 1075 # Set a variable so conditions can be based on msvs_version. |
| 1076 default_variables['MSVS_VERSION'] = msvs_version.ShortName() |
| 1077 |
| 1078 # To determine processor word size on Windows, in addition to checking |
| 1079 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current |
| 1080 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which |
| 1081 # contains the actual word size of the system when running thru WOW64). |
| 1082 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or |
| 1083 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): |
| 1084 default_variables['MSVS_OS_BITS'] = 64 |
| 1085 else: |
| 1086 default_variables['MSVS_OS_BITS'] = 32 |
1014 else: | 1087 else: |
1015 operating_system = flavor | 1088 operating_system = flavor |
1016 if flavor == 'android': | 1089 if flavor == 'android': |
1017 operating_system = 'linux' # Keep this legacy behavior for now. | 1090 operating_system = 'linux' # Keep this legacy behavior for now. |
1018 default_variables.setdefault('OS', operating_system) | 1091 default_variables.setdefault('OS', operating_system) |
1019 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') | 1092 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') |
1020 default_variables.setdefault('SHARED_LIB_DIR', | 1093 default_variables.setdefault('SHARED_LIB_DIR', |
1021 os.path.join('$!PRODUCT_DIR', 'lib')) | 1094 os.path.join('$!PRODUCT_DIR', 'lib')) |
1022 default_variables.setdefault('LIB_DIR', '') | 1095 default_variables.setdefault('LIB_DIR', '') |
1023 | 1096 |
1024 | 1097 |
1025 def OpenOutput(path): | 1098 def OpenOutput(path): |
1026 """Open |path| for writing, creating directories if necessary.""" | 1099 """Open |path| for writing, creating directories if necessary.""" |
1027 try: | 1100 try: |
1028 os.makedirs(os.path.dirname(path)) | 1101 os.makedirs(os.path.dirname(path)) |
1029 except OSError: | 1102 except OSError: |
1030 pass | 1103 pass |
1031 return open(path, 'w') | 1104 return open(path, 'w') |
1032 | 1105 |
1033 | 1106 |
1034 def GenerateOutputForConfig(target_list, target_dicts, data, params, | 1107 def GenerateOutputForConfig(target_list, target_dicts, data, params, |
1035 config_name): | 1108 config_name): |
| 1109 print "Generating ninja build files for %s..." % config_name |
1036 options = params['options'] | 1110 options = params['options'] |
1037 flavor = gyp.common.GetFlavor(params) | 1111 flavor = gyp.common.GetFlavor(params) |
1038 generator_flags = params.get('generator_flags', {}) | 1112 generator_flags = params.get('generator_flags', {}) |
1039 | 1113 |
1040 # build_dir: relative path from source root to our output files. | 1114 # build_dir: relative path from source root to our output files. |
1041 # e.g. "out/Debug" | 1115 # e.g. "out/Debug" |
1042 build_dir = os.path.join(generator_flags.get('output_dir', 'out'), | 1116 build_dir = os.path.join(generator_flags.get('output_dir', 'out'), |
1043 config_name) | 1117 config_name) |
1044 | 1118 |
| 1119 top_build_dir = os.path.join(options.toplevel_dir, build_dir) |
1045 master_ninja = ninja_syntax.Writer( | 1120 master_ninja = ninja_syntax.Writer( |
1046 OpenOutput(os.path.join(options.toplevel_dir, build_dir, 'build.ninja')), | 1121 OpenOutput(os.path.join(top_build_dir, 'build.ninja')), |
1047 width=120) | 1122 width=120) |
1048 | 1123 |
1049 # Put build-time support tools in out/{config_name}. | 1124 # Put build-time support tools in out/{config_name}. |
1050 gyp.common.CopyTool(flavor, os.path.join(options.toplevel_dir, build_dir)) | 1125 gyp.common.CopyTool(flavor, top_build_dir) |
1051 | 1126 |
1052 # Grab make settings for CC/CXX. | 1127 # Grab make settings for CC/CXX. |
1053 if flavor == 'win': | 1128 if flavor == 'win': |
1054 cc = cxx = 'cl' | 1129 cc = cxx = gyp.msvs_emulation.GetCLPath(generator_flags) |
1055 else: | 1130 else: |
1056 cc, cxx = 'gcc', 'g++' | 1131 cc, cxx = 'gcc', 'g++' |
1057 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) | 1132 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) |
1058 make_global_settings = data[build_file].get('make_global_settings', []) | 1133 make_global_settings = data[build_file].get('make_global_settings', []) |
1059 build_to_root = InvertRelativePath(build_dir) | 1134 build_to_root = InvertRelativePath(build_dir) |
1060 for key, value in make_global_settings: | 1135 for key, value in make_global_settings: |
1061 if key == 'CC': cc = os.path.join(build_to_root, value) | 1136 if key == 'CC': cc = os.path.join(build_to_root, value) |
1062 if key == 'CXX': cxx = os.path.join(build_to_root, value) | 1137 if key == 'CXX': cxx = os.path.join(build_to_root, value) |
1063 | 1138 |
1064 flock = 'flock' | 1139 flock = 'flock' |
1065 if flavor == 'mac': | 1140 if flavor == 'mac': |
1066 flock = './gyp-mac-tool flock' | 1141 flock = './gyp-mac-tool flock' |
1067 master_ninja.variable('ar', os.environ.get('AR', 'ar')) | 1142 master_ninja.variable('ar', os.environ.get('AR', 'ar')) |
1068 master_ninja.variable('cc', os.environ.get('CC', cc)) | 1143 master_ninja.variable('cc', os.environ.get('CC', cc)) |
1069 master_ninja.variable('cxx', os.environ.get('CXX', cxx)) | 1144 master_ninja.variable('cxx', os.environ.get('CXX', cxx)) |
1070 if flavor == 'win': | 1145 if flavor == 'win': |
1071 master_ninja.variable('ld', 'link') | 1146 master_ninja.variable('ld', gyp.msvs_emulation.GetLinkPath(generator_flags)) |
| 1147 master_ninja.variable('idl', |
| 1148 gyp.msvs_emulation.GetMidlPath(generator_flags)) |
1072 else: | 1149 else: |
1073 master_ninja.variable('ld', flock + ' linker.lock $cxx') | 1150 master_ninja.variable('ld', flock + ' linker.lock $cxx') |
1074 | 1151 |
1075 master_ninja.variable('ar_target', os.environ.get('AR_target', '$ar')) | 1152 master_ninja.variable('ar_target', os.environ.get('AR_target', '$ar')) |
1076 master_ninja.variable('cc_target', os.environ.get('CC_target', '$cc')) | 1153 master_ninja.variable('cc_target', os.environ.get('CC_target', '$cc')) |
1077 master_ninja.variable('cxx_target', os.environ.get('CXX_target', '$cxx')) | 1154 master_ninja.variable('cxx_target', os.environ.get('CXX_target', '$cxx')) |
1078 if flavor == 'win': | 1155 if flavor == 'win': |
1079 master_ninja.variable('ld_target', 'link') | 1156 master_ninja.variable('ld_target', gyp.msvs_emulation.GetLinkPath( |
| 1157 generator_flags)) |
1080 else: | 1158 else: |
1081 master_ninja.variable('ld_target', flock + ' linker.lock $cxx_target') | 1159 master_ninja.variable('ld_target', flock + ' linker.lock $cxx_target') |
1082 | 1160 |
1083 if flavor == 'mac': | 1161 if flavor == 'mac': |
1084 master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool')) | 1162 master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool')) |
1085 master_ninja.newline() | 1163 master_ninja.newline() |
1086 | 1164 |
1087 if flavor != 'win': | 1165 if flavor != 'win': |
1088 master_ninja.rule( | 1166 master_ninja.rule( |
1089 'cc', | 1167 'cc', |
1090 description='CC $out', | 1168 description='CC $out', |
1091 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' | 1169 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' |
1092 '$cflags_pch_c -c $in -o $out'), | 1170 '$cflags_pch_c -c $in -o $out'), |
1093 depfile='$out.d') | 1171 depfile='$out.d') |
1094 master_ninja.rule( | 1172 master_ninja.rule( |
1095 'cxx', | 1173 'cxx', |
1096 description='CXX $out', | 1174 description='CXX $out', |
1097 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' | 1175 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' |
1098 '$cflags_pch_cc -c $in -o $out'), | 1176 '$cflags_pch_cc -c $in -o $out'), |
1099 depfile='$out.d') | 1177 depfile='$out.d') |
1100 else: | 1178 else: |
1101 # TODO(scottmg): Requires deplist branch of ninja for now (for | 1179 # TODO(scottmg): Requires deplist branch of ninja for now (for |
1102 # /showIncludes handling). | 1180 # /showIncludes handling). |
1103 master_ninja.rule( | 1181 master_ninja.rule( |
1104 'cc', | 1182 'cc', |
1105 description='CC $out', | 1183 description='CC $out', |
1106 command=('cmd /c $cc /nologo /showIncludes ' | 1184 command=('cmd /s /c "$cc /nologo /showIncludes ' |
1107 '$defines $includes $cflags $cflags_c ' | 1185 '@$out.rsp ' |
1108 '$cflags_pch_c /c $in /Fo$out ' | 1186 '$cflags_pch_c /c $in /Fo$out /Fd$out.pdb ' |
1109 '| ninja-deplist-helper -f cl -o $out.dl'), | 1187 '| ninja-deplist-helper -d .ninja_depdb -q -f cl -o $in"'), |
1110 deplist='$out.dl') | 1188 depdb='$in', |
| 1189 rspfile='$out.rsp', |
| 1190 rspfile_content='$defines $includes $cflags $cflags_c') |
1111 master_ninja.rule( | 1191 master_ninja.rule( |
1112 'cxx', | 1192 'cxx', |
1113 description='CXX $out', | 1193 description='CXX $out', |
1114 command=('cmd /c $cxx /nologo /showIncludes ' | 1194 command=('cmd /s /c "$cxx /nologo /showIncludes ' |
1115 '$defines $includes $cflags $cflags_cc ' | 1195 '@$out.rsp ' |
1116 '$cflags_pch_cc /c $in /Fo$out ' | 1196 '$cflags_pch_cc /c $in /Fo$out /Fd$out.pdb ' |
1117 '| ninja-deplist-helper -f cl -o $out.dl'), | 1197 '| ninja-deplist-helper -d .ninja_depdb -q -f cl -o $in"'), |
1118 deplist='$out.dl') | 1198 depdb='$in', |
| 1199 rspfile='$out.rsp', |
| 1200 rspfile_content='$defines $includes $cflags $cflags_cc') |
| 1201 master_ninja.rule( |
| 1202 'idl', |
| 1203 description='IDL $outdir', |
| 1204 command=('python gyp-win-tool quiet-midl $outdir ' |
| 1205 '$tlb $h $dlldata $iid $proxy $in ' |
| 1206 '$idlflags')) |
1119 | 1207 |
1120 if flavor != 'mac' and flavor != 'win': | 1208 if flavor != 'mac' and flavor != 'win': |
1121 master_ninja.rule( | 1209 master_ninja.rule( |
1122 'alink', | 1210 'alink', |
1123 description='AR $out', | 1211 description='AR $out', |
1124 command='rm -f $out && $ar rcsT $out $in') | 1212 command='rm -f $out && $ar rcsT $out $in') |
1125 master_ninja.rule( | 1213 master_ninja.rule( |
1126 'solink', | 1214 'solink', |
1127 description='SOLINK $out', | 1215 description='SOLINK $out', |
1128 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1216 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
1129 '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) | 1217 '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) |
1130 master_ninja.rule( | 1218 master_ninja.rule( |
1131 'solink_module', | 1219 'solink_module', |
1132 description='SOLINK(module) $out', | 1220 description='SOLINK(module) $out', |
1133 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1221 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
1134 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1222 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1135 master_ninja.rule( | 1223 master_ninja.rule( |
1136 'link', | 1224 'link', |
1137 description='LINK $out', | 1225 description='LINK $out', |
1138 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' | 1226 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' |
1139 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1227 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1140 elif flavor == 'win': | 1228 elif flavor == 'win': |
1141 master_ninja.rule( | 1229 master_ninja.rule( |
1142 'alink', | 1230 'alink', |
1143 description='LIB $out', | 1231 description='LIB $out', |
1144 command='lib /nologo /OUT:$out $in') | 1232 command='lib /nologo /ignore:4221 $libflags /OUT:$out @$out.rsp', |
1145 master_ninja.rule( | 1233 rspfile='$out.rsp', |
1146 'solink', | 1234 rspfile_content='$in') |
1147 description='LINK(DLL) $dll', | 1235 # TODO(scottmg): The lib is the main output, rather than the dll. link |
1148 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) | 1236 # doesn't create the import lib unless there's exports from the dll, |
1149 master_ninja.rule( | 1237 # however. This means the dependencies are wrong and the dll will always |
1150 'solink_module', | 1238 # relink if it has no exports. We could touch a dummy file, but we don't |
1151 description='LINK(DLL) $dll', | 1239 # want to do && touch, because that would mean we'd have to prepend cmd, |
1152 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) | 1240 # which would impose a short line length on the link command line. That |
| 1241 # can be resolved by adding support for @rsp files, but neither ninja or |
| 1242 # gyp takes care of that right now. So, currently, we force the export |
| 1243 # of the entry point, and then ignore the warning that we're doing so, |
| 1244 # which causes the lib to always get generated. |
| 1245 dlldesc = 'LINK(DLL) $dll and $implib' |
| 1246 dllcmd = ('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll ' |
| 1247 '/PDB:$dll.pdb $libs @$dll.rsp') |
| 1248 master_ninja.rule('solink', description=dlldesc, command=dllcmd, |
| 1249 rspfile='$dll.rsp', rspfile_content='$in') |
| 1250 master_ninja.rule('solink_module', description=dlldesc, command=dllcmd) |
1153 master_ninja.rule( | 1251 master_ninja.rule( |
1154 'link', | 1252 'link', |
1155 description='LINK $out', | 1253 description='LINK $out', |
1156 command=('$ld /nologo $ldflags /OUT:$out $in $libs')) | 1254 command=('$ld /nologo $ldflags /OUT:$out /PDB:$out.pdb $in $libs')) |
1157 else: | 1255 else: |
1158 master_ninja.rule( | 1256 master_ninja.rule( |
1159 'objc', | 1257 'objc', |
1160 description='OBJC $out', | 1258 description='OBJC $out', |
1161 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' | 1259 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' |
1162 '$cflags_pch_objc -c $in -o $out'), | 1260 '$cflags_pch_objc -c $in -o $out'), |
1163 depfile='$out.d') | 1261 depfile='$out.d') |
1164 master_ninja.rule( | 1262 master_ninja.rule( |
1165 'objcxx', | 1263 'objcxx', |
1166 description='OBJCXX $out', | 1264 description='OBJCXX $out', |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 command='$mac_tool package-framework $out $version$postbuilds ' | 1303 command='$mac_tool package-framework $out $version$postbuilds ' |
1206 '&& touch $out') | 1304 '&& touch $out') |
1207 if flavor == 'win': | 1305 if flavor == 'win': |
1208 master_ninja.rule( | 1306 master_ninja.rule( |
1209 'stamp', | 1307 'stamp', |
1210 description='STAMP $out', | 1308 description='STAMP $out', |
1211 command='cmd /c copy /y nul $out>nul') | 1309 command='cmd /c copy /y nul $out>nul') |
1212 master_ninja.rule( | 1310 master_ninja.rule( |
1213 'copy', | 1311 'copy', |
1214 description='COPY $in $out', | 1312 description='COPY $in $out', |
1215 command='cmd /c mklink /h $out $in >nul || mklink /h /j $out $in >nul || ' | 1313 command='python gyp-win-tool recursive-mirror $in $out') |
1216 'python gyp-win-tool recursive-mirror $in $out') | |
1217 else: | 1314 else: |
1218 master_ninja.rule( | 1315 master_ninja.rule( |
1219 'stamp', | 1316 'stamp', |
1220 description='STAMP $out', | 1317 description='STAMP $out', |
1221 command='${postbuilds}touch $out') | 1318 command='${postbuilds}touch $out') |
1222 master_ninja.rule( | 1319 master_ninja.rule( |
1223 'copy', | 1320 'copy', |
1224 description='COPY $in $out', | 1321 description='COPY $in $out', |
1225 command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') | 1322 command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') |
1226 master_ninja.newline() | 1323 master_ninja.newline() |
(...skipping 22 matching lines...) Expand all Loading... |
1249 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) | 1346 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) |
1250 | 1347 |
1251 build_file = gyp.common.RelativePath(build_file, options.toplevel_dir) | 1348 build_file = gyp.common.RelativePath(build_file, options.toplevel_dir) |
1252 | 1349 |
1253 base_path = os.path.dirname(build_file) | 1350 base_path = os.path.dirname(build_file) |
1254 obj = 'obj' | 1351 obj = 'obj' |
1255 if toolset != 'target': | 1352 if toolset != 'target': |
1256 obj += '.' + toolset | 1353 obj += '.' + toolset |
1257 output_file = os.path.join(obj, base_path, name + '.ninja') | 1354 output_file = os.path.join(obj, base_path, name + '.ninja') |
1258 | 1355 |
1259 abs_build_dir=os.path.abspath(os.path.join(options.toplevel_dir, build_dir)) | 1356 abs_build_dir=os.path.abspath(top_build_dir) |
1260 writer = NinjaWriter(target_outputs, base_path, build_dir, | 1357 writer = NinjaWriter(target_outputs, base_path, build_dir, |
1261 OpenOutput(os.path.join(options.toplevel_dir, | 1358 OpenOutput(os.path.join(top_build_dir, output_file)), |
1262 build_dir, | |
1263 output_file)), | |
1264 flavor, abs_build_dir=abs_build_dir) | 1359 flavor, abs_build_dir=abs_build_dir) |
1265 master_ninja.subninja(output_file) | 1360 master_ninja.subninja(output_file) |
1266 | 1361 |
1267 target = writer.WriteSpec(spec, config_name) | 1362 target = writer.WriteSpec(spec, config_name) |
1268 if target: | 1363 if target: |
1269 target_outputs[qualified_target] = target | 1364 target_outputs[qualified_target] = target |
1270 if qualified_target in all_targets: | 1365 if qualified_target in all_targets: |
1271 all_outputs.add(target.FinalOutput()) | 1366 all_outputs.add(target.FinalOutput()) |
1272 | 1367 |
1273 if all_outputs: | 1368 if all_outputs: |
1274 master_ninja.build('all', 'phony', list(all_outputs)) | 1369 master_ninja.build('all', 'phony', list(all_outputs)) |
1275 | 1370 |
1276 | 1371 |
1277 def GenerateOutput(target_list, target_dicts, data, params): | 1372 def GenerateOutput(target_list, target_dicts, data, params): |
1278 if params['options'].generator_output: | 1373 if params['options'].generator_output: |
1279 raise NotImplementedError, "--generator_output not implemented for ninja" | 1374 raise NotImplementedError, "--generator_output not implemented for ninja" |
1280 | 1375 |
1281 user_config = params.get('generator_flags', {}).get('config', None) | 1376 user_config = params.get('generator_flags', {}).get('config', None) |
1282 if user_config: | 1377 if user_config: |
1283 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1378 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1284 user_config) | 1379 user_config) |
1285 else: | 1380 else: |
1286 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1381 config_names = target_dicts[target_list[0]]['configurations'].keys() |
1287 for config_name in config_names: | 1382 for config_name in config_names: |
1288 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1383 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1289 config_name) | 1384 config_name) |
OLD | NEW |