| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2011 Google Inc. All rights reserved. | 3 # Copyright (c) 2011 Google Inc. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 # Notes: | 7 # Notes: |
| 8 # | 8 # |
| 9 # This is all roughly based on the Makefile system used by the Linux | 9 # This is all roughly based on the Makefile system used by the Linux |
| 10 # kernel, but is a non-recursive make -- we put the entire dependency | 10 # kernel, but is a non-recursive make -- we put the entire dependency |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 quiet_cmd_copy = COPY $@ | 200 quiet_cmd_copy = COPY $@ |
| 201 # send stderr to /dev/null to ignore messages when linking directories. | 201 # send stderr to /dev/null to ignore messages when linking directories. |
| 202 cmd_copy = ln -f $< $@ 2>/dev/null || cp -af $< $@ | 202 cmd_copy = ln -f $< $@ 2>/dev/null || cp -af $< $@ |
| 203 | 203 |
| 204 # Due to circular dependencies between libraries :(, we wrap the | 204 # Due to circular dependencies between libraries :(, we wrap the |
| 205 # special "figure out circular dependencies" flags around the entire | 205 # special "figure out circular dependencies" flags around the entire |
| 206 # input list during linking. | 206 # input list during linking. |
| 207 quiet_cmd_link = LINK($(TOOLSET)) $@ | 207 quiet_cmd_link = LINK($(TOOLSET)) $@ |
| 208 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--s
tart-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) | 208 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--s
tart-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) |
| 209 | 209 |
| 210 # Shared-object link (for generating .so). | 210 # We support two kinds of shared objects (.so): |
| 211 # Set SONAME to the library filename so our binaries don't reference the local, | 211 # 1) shared_library, which is just bundling together many dependent libraries |
| 212 # absolute paths used on the link command-line. | 212 # into a link line. |
| 213 # TODO: perhaps this can share with the LINK command above? | 213 # 2) loadable_module, which is generating a module intended for dlopen(). |
| 214 # |
| 215 # They differ only slightly: |
| 216 # In the former case, we want to package all dependent code into the .so. |
| 217 # In the latter case, we want to package just the API exposed by the |
| 218 # outermost module. |
| 219 # This means shared_library uses --whole-archive, while loadable_module doesn't. |
| 220 # (Note that --whole-archive is incompatible with the --start-group used in |
| 221 # normal linking.) |
| 222 |
| 223 # Other shared-object link notes: |
| 224 # - Set SONAME to the library filename so our binaries don't reference |
| 225 # the local, absolute paths used on the link command-line. |
| 214 quiet_cmd_solink = SOLINK($(TOOLSET)) $@ | 226 quiet_cmd_solink = SOLINK($(TOOLSET)) $@ |
| 215 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl
,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-
group $(LIBS) | 227 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl
,-soname=$(@F) -o $@ -Wl,--whole-archive $(filter-out FORCE_DO_CMD, $^) -Wl,--no
-whole-archive $(LIBS) |
| 228 |
| 229 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ |
| 230 cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE
T)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl
,--end-group $(LIBS) |
| 216 """ | 231 """ |
| 232 |
| 217 r""" | 233 r""" |
| 218 # Define an escape_quotes function to escape single quotes. | 234 # Define an escape_quotes function to escape single quotes. |
| 219 # This allows us to handle quotes properly as long as we always use | 235 # This allows us to handle quotes properly as long as we always use |
| 220 # use single quotes and escape_quotes. | 236 # use single quotes and escape_quotes. |
| 221 escape_quotes = $(subst ','\'',$(1)) | 237 escape_quotes = $(subst ','\'',$(1)) |
| 222 # This comment is here just to include a ' to unconfuse syntax highlighting. | 238 # This comment is here just to include a ' to unconfuse syntax highlighting. |
| 223 # Define an escape_vars function to escape '$' variable syntax. | 239 # Define an escape_vars function to escape '$' variable syntax. |
| 224 # This allows us to read/write command lines with shell variables (e.g. | 240 # This allows us to read/write command lines with shell variables (e.g. |
| 225 # $LD_LIBRARY_PATH), without triggering make substitution. | 241 # $LD_LIBRARY_PATH), without triggering make substitution. |
| 226 escape_vars = $(subst $$,$$$$,$(1)) | 242 escape_vars = $(subst $$,$$$$,$(1)) |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 """Convert a path to its source directory form.""" | 504 """Convert a path to its source directory form.""" |
| 489 if '$(' in path: | 505 if '$(' in path: |
| 490 return path | 506 return path |
| 491 if os.path.isabs(path): | 507 if os.path.isabs(path): |
| 492 return path | 508 return path |
| 493 return srcdir_prefix + path | 509 return srcdir_prefix + path |
| 494 | 510 |
| 495 | 511 |
| 496 # Map from qualified target to path to output. | 512 # Map from qualified target to path to output. |
| 497 target_outputs = {} | 513 target_outputs = {} |
| 498 # Map from qualified target to a list of all linker dependencies, | 514 # Map from qualified target to any linkable output. A subset |
| 499 # transitively expanded. | 515 # of target_outputs. E.g. when mybinary depends on liba, we want to |
| 500 # Used in building shared-library-based executables. | 516 # include liba in the linker line; when otherbinary depends on |
| 517 # mybinary, we just want to build mybinary first. |
| 501 target_link_deps = {} | 518 target_link_deps = {} |
| 502 | 519 |
| 503 | 520 |
| 504 class MakefileWriter: | 521 class MakefileWriter: |
| 505 """MakefileWriter packages up the writing of one target-specific foobar.mk. | 522 """MakefileWriter packages up the writing of one target-specific foobar.mk. |
| 506 | 523 |
| 507 Its only real entry point is Write(), and is mostly used for namespacing. | 524 Its only real entry point is Write(), and is mostly used for namespacing. |
| 508 """ | 525 """ |
| 509 | 526 |
| 510 def __init__(self, generator_flags): | 527 def __init__(self, generator_flags): |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 self.WriteLn('# End of this set of suffix rules') | 612 self.WriteLn('# End of this set of suffix rules') |
| 596 | 613 |
| 597 | 614 |
| 598 self.WriteTarget(spec, configs, deps, | 615 self.WriteTarget(spec, configs, deps, |
| 599 extra_link_deps + link_deps, extra_outputs, part_of_all) | 616 extra_link_deps + link_deps, extra_outputs, part_of_all) |
| 600 | 617 |
| 601 # Update global list of target outputs, used in dependency tracking. | 618 # Update global list of target outputs, used in dependency tracking. |
| 602 target_outputs[qualified_target] = install_path | 619 target_outputs[qualified_target] = install_path |
| 603 | 620 |
| 604 # Update global list of link dependencies. | 621 # Update global list of link dependencies. |
| 605 if self.type == 'static_library': | 622 if self.type in ('static_library', 'shared_library'): |
| 606 target_link_deps[qualified_target] = [self.output] | 623 target_link_deps[qualified_target] = self.output |
| 607 elif self.type == 'shared_library': | |
| 608 # Anyone that uses us transitively depend on all of our link | |
| 609 # dependencies. | |
| 610 target_link_deps[qualified_target] = [self.output] + link_deps | |
| 611 | 624 |
| 612 # Currently any versions have the same effect, but in future the behavior | 625 # Currently any versions have the same effect, but in future the behavior |
| 613 # could be different. | 626 # could be different. |
| 614 if self.generator_flags.get('android_ndk_version', None): | 627 if self.generator_flags.get('android_ndk_version', None): |
| 615 self.WriteAndroidNdkModuleRule(self.target, all_sources, link_deps) | 628 self.WriteAndroidNdkModuleRule(self.target, all_sources, link_deps) |
| 616 | 629 |
| 617 self.fp.close() | 630 self.fp.close() |
| 618 | 631 |
| 619 | 632 |
| 620 def WriteSubMake(self, output_filename, makefile_path, targets, build_dir): | 633 def WriteSubMake(self, output_filename, makefile_path, targets, build_dir): |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 filenames that will need to be put in front of make for either | 975 filenames that will need to be put in front of make for either |
| 963 building (deps) or linking (link_deps). | 976 building (deps) or linking (link_deps). |
| 964 """ | 977 """ |
| 965 deps = [] | 978 deps = [] |
| 966 link_deps = [] | 979 link_deps = [] |
| 967 if 'dependencies' in spec: | 980 if 'dependencies' in spec: |
| 968 deps.extend([target_outputs[dep] for dep in spec['dependencies'] | 981 deps.extend([target_outputs[dep] for dep in spec['dependencies'] |
| 969 if target_outputs[dep]]) | 982 if target_outputs[dep]]) |
| 970 for dep in spec['dependencies']: | 983 for dep in spec['dependencies']: |
| 971 if dep in target_link_deps: | 984 if dep in target_link_deps: |
| 972 link_deps.extend(target_link_deps[dep]) | 985 link_deps.append(target_link_deps[dep]) |
| 973 deps.extend(link_deps) | 986 deps.extend(link_deps) |
| 974 # TODO: It seems we need to transitively link in libraries (e.g. -lfoo)? | 987 # TODO: It seems we need to transitively link in libraries (e.g. -lfoo)? |
| 975 # This hack makes it work: | 988 # This hack makes it work: |
| 976 # link_deps.extend(spec.get('libraries', [])) | 989 # link_deps.extend(spec.get('libraries', [])) |
| 977 return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps)) | 990 return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps)) |
| 978 | 991 |
| 979 | 992 |
| 980 def WriteTarget(self, spec, configs, deps, link_deps, extra_outputs, | 993 def WriteTarget(self, spec, configs, deps, link_deps, extra_outputs, |
| 981 part_of_all): | 994 part_of_all): |
| 982 """Write Makefile code to produce the final target of the gyp spec. | 995 """Write Makefile code to produce the final target of the gyp spec. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1008 # Remove duplicate entries | 1021 # Remove duplicate entries |
| 1009 libraries = gyp.common.uniquer(libraries) | 1022 libraries = gyp.common.uniquer(libraries) |
| 1010 self.WriteList(libraries, 'LIBS') | 1023 self.WriteList(libraries, 'LIBS') |
| 1011 self.WriteLn('%s: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))' % self.output) | 1024 self.WriteLn('%s: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))' % self.output) |
| 1012 self.WriteLn('%s: LIBS := $(LIBS)' % self.output) | 1025 self.WriteLn('%s: LIBS := $(LIBS)' % self.output) |
| 1013 | 1026 |
| 1014 if self.type == 'executable': | 1027 if self.type == 'executable': |
| 1015 self.WriteDoCmd([self.output], link_deps, 'link', part_of_all) | 1028 self.WriteDoCmd([self.output], link_deps, 'link', part_of_all) |
| 1016 elif self.type == 'static_library': | 1029 elif self.type == 'static_library': |
| 1017 self.WriteDoCmd([self.output], link_deps, 'alink', part_of_all) | 1030 self.WriteDoCmd([self.output], link_deps, 'alink', part_of_all) |
| 1018 elif self.type in ('loadable_module', 'shared_library'): | 1031 elif self.type == 'shared_library': |
| 1019 self.WriteDoCmd([self.output], link_deps, 'solink', part_of_all) | 1032 self.WriteDoCmd([self.output], link_deps, 'solink', part_of_all) |
| 1033 elif self.type == 'loadable_module': |
| 1034 self.WriteDoCmd([self.output], link_deps, 'solink_module', part_of_all) |
| 1020 elif self.type == 'none': | 1035 elif self.type == 'none': |
| 1021 # Write a stamp line. | 1036 # Write a stamp line. |
| 1022 self.WriteDoCmd([self.output], deps, 'touch', part_of_all) | 1037 self.WriteDoCmd([self.output], deps, 'touch', part_of_all) |
| 1023 elif self.type == 'settings': | 1038 elif self.type == 'settings': |
| 1024 # Only used for passing flags around. | 1039 # Only used for passing flags around. |
| 1025 pass | 1040 pass |
| 1026 else: | 1041 else: |
| 1027 print "WARNING: no output for", self.type, target | 1042 print "WARNING: no output for", self.type, target |
| 1028 | 1043 |
| 1029 # Add an alias for each target (if there are any outputs). | 1044 # Add an alias for each target (if there are any outputs). |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 # Add a check to make sure we tried to process all the .d files. | 1533 # Add a check to make sure we tried to process all the .d files. |
| 1519 all_deps += """ | 1534 all_deps += """ |
| 1520 ifneq ($(word %(last)d,$(d_files)),) | 1535 ifneq ($(word %(last)d,$(d_files)),) |
| 1521 $(error Found unprocessed dependency files (gyp didn't generate enough rules
!)) | 1536 $(error Found unprocessed dependency files (gyp didn't generate enough rules
!)) |
| 1522 endif | 1537 endif |
| 1523 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 } | 1538 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 } |
| 1524 | 1539 |
| 1525 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps }) | 1540 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps }) |
| 1526 | 1541 |
| 1527 root_makefile.close() | 1542 root_makefile.close() |
| OLD | NEW |