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 """ | 5 """ |
6 This module contains classes that help to emulate xcodebuild behavior on top of | 6 This module contains classes that help to emulate xcodebuild behavior on top of |
7 other build systems, such as make and ninja. | 7 other build systems, such as make and ninja. |
8 """ | 8 """ |
9 | 9 |
10 import os.path | 10 import os.path |
(...skipping 11 matching lines...) Expand all Loading... |
22 # for that config -- the per-target settings as well. Settings that are | 22 # for that config -- the per-target settings as well. Settings that are |
23 # the same for all configs are implicitly per-target settings. | 23 # the same for all configs are implicitly per-target settings. |
24 self.xcode_settings = {} | 24 self.xcode_settings = {} |
25 configs = spec['configurations'] | 25 configs = spec['configurations'] |
26 for configname, config in configs.iteritems(): | 26 for configname, config in configs.iteritems(): |
27 self.xcode_settings[configname] = config.get('xcode_settings', {}) | 27 self.xcode_settings[configname] = config.get('xcode_settings', {}) |
28 | 28 |
29 # This is only non-None temporarily during the execution of some methods. | 29 # This is only non-None temporarily during the execution of some methods. |
30 self.configname = None | 30 self.configname = None |
31 | 31 |
| 32 # Used by _AdjustLibrary to match .a and .dylib entries in libraries. |
| 33 self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$') |
| 34 |
32 def _Settings(self): | 35 def _Settings(self): |
33 assert self.configname | 36 assert self.configname |
34 return self.xcode_settings[self.configname] | 37 return self.xcode_settings[self.configname] |
35 | 38 |
36 def _Test(self, test_key, cond_key, default): | 39 def _Test(self, test_key, cond_key, default): |
37 return self._Settings().get(test_key, default) == cond_key | 40 return self._Settings().get(test_key, default) == cond_key |
38 | 41 |
39 def _Appendf(self, lst, test_key, format_str, default=None): | 42 def _Appendf(self, lst, test_key, format_str, default=None): |
40 if test_key in self._Settings(): | 43 if test_key in self._Settings(): |
41 lst.append(format_str % str(self._Settings()[test_key])) | 44 lst.append(format_str % str(self._Settings()[test_key])) |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 self._Appendf( | 376 self._Appendf( |
374 ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s') | 377 ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s') |
375 self._Appendf( | 378 self._Appendf( |
376 ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s') | 379 ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s') |
377 self._Appendf( | 380 self._Appendf( |
378 ldflags, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') | 381 ldflags, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') |
379 if 'SDKROOT' in self._Settings(): | 382 if 'SDKROOT' in self._Settings(): |
380 ldflags.append('-isysroot ' + self._SdkPath()) | 383 ldflags.append('-isysroot ' + self._SdkPath()) |
381 | 384 |
382 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []): | 385 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []): |
383 ldflags.append('-L' + library_path) | 386 ldflags.append('-L' + gyp_to_build_path(library_path)) |
384 | 387 |
385 if 'ORDER_FILE' in self._Settings(): | 388 if 'ORDER_FILE' in self._Settings(): |
386 ldflags.append('-Wl,-order_file ' + | 389 ldflags.append('-Wl,-order_file ' + |
387 '-Wl,' + gyp_to_build_path( | 390 '-Wl,' + gyp_to_build_path( |
388 self._Settings()['ORDER_FILE'])) | 391 self._Settings()['ORDER_FILE'])) |
389 | 392 |
390 # TODO: Do not hardcode arch. Supporting fat binaries will be annoying. | 393 # TODO: Do not hardcode arch. Supporting fat binaries will be annoying. |
391 ldflags.append('-arch i386') | 394 ldflags.append('-arch i386') |
392 | 395 |
393 # Xcode adds the product directory by default. | 396 # Xcode adds the product directory by default. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 self.configname = None | 527 self.configname = None |
525 return result | 528 return result |
526 | 529 |
527 def GetTargetPostbuilds(self, configname, output, output_binary): | 530 def GetTargetPostbuilds(self, configname, output, output_binary): |
528 """Returns a list of shell commands that contain the shell commands | 531 """Returns a list of shell commands that contain the shell commands |
529 to run as postbuilds for this target, before the actual postbuilds.""" | 532 to run as postbuilds for this target, before the actual postbuilds.""" |
530 # dSYMs need to build before stripping happens. | 533 # dSYMs need to build before stripping happens. |
531 return (self._GetDebugPostbuilds(configname, output, output_binary) + | 534 return (self._GetDebugPostbuilds(configname, output, output_binary) + |
532 self._GetStripPostbuilds(configname, output_binary)) | 535 self._GetStripPostbuilds(configname, output_binary)) |
533 | 536 |
534 def AdjustFrameworkLibraries(self, libraries): | 537 def _AdjustLibrary(self, library): |
| 538 if library.endswith('.framework'): |
| 539 l = '-framework ' + os.path.splitext(os.path.basename(library))[0] |
| 540 else: |
| 541 m = self.library_re.match(library) |
| 542 if m: |
| 543 l = '-l' + m.group(1) |
| 544 else: |
| 545 l = library |
| 546 return l.replace('$(SDKROOT)', self._SdkPath()) |
| 547 |
| 548 def AdjustLibraries(self, libraries): |
535 """Transforms entries like 'Cocoa.framework' in libraries into entries like | 549 """Transforms entries like 'Cocoa.framework' in libraries into entries like |
536 '-framework Cocoa'. | 550 '-framework Cocoa', 'libcrypto.dylib' into '-lcrypto', etc. |
537 """ | 551 """ |
538 libraries = [ | 552 libraries = [ self._AdjustLibrary(library) for library in libraries] |
539 '-framework ' + os.path.splitext(os.path.basename(library))[0] | |
540 if library.endswith('.framework') else library | |
541 for library in libraries] | |
542 libraries = [library.replace('$(SDKROOT)', self._SdkPath()) | |
543 for library in libraries] | |
544 return libraries | 553 return libraries |
545 | 554 |
546 | 555 |
547 class MacPrefixHeader(object): | 556 class MacPrefixHeader(object): |
548 """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. | 557 """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. |
549 | 558 |
550 This feature consists of several pieces: | 559 This feature consists of several pieces: |
551 * If GCC_PREFIX_HEADER is present, all compilations in that project get an | 560 * If GCC_PREFIX_HEADER is present, all compilations in that project get an |
552 additional |-include path_to_prefix_header| cflag. | 561 additional |-include path_to_prefix_header| cflag. |
553 * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is | 562 * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 | 919 |
911 # Any remaining edges indicate a cycle. | 920 # Any remaining edges indicate a cycle. |
912 if len(edges): | 921 if len(edges): |
913 raise Exception('Xcode environment variables are cyclically dependent: ' + | 922 raise Exception('Xcode environment variables are cyclically dependent: ' + |
914 str(edges)) | 923 str(edges)) |
915 | 924 |
916 # Append the "nodes" not in the graph to those that were just sorted. | 925 # Append the "nodes" not in the graph to those that were just sorted. |
917 sorted_nodes.extend(key_list) | 926 sorted_nodes.extend(key_list) |
918 | 927 |
919 return sorted_nodes | 928 return sorted_nodes |
OLD | NEW |