Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(529)

Side by Side Diff: pylib/gyp/xcode_emulation.py

Issue 12725005: improve xcode_emulation.py (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: test/{xcode => mac}, fixed ios tests with 'xcode' Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 gyp.common 10 import gyp.common
11 import os.path 11 import os.path
12 import re 12 import re
13 import shlex 13 import shlex
14 import subprocess
15 import sys
16 from gyp.common import GypError
14 17
15 class XcodeSettings(object): 18 class XcodeSettings(object):
16 """A class that understands the gyp 'xcode_settings' object.""" 19 """A class that understands the gyp 'xcode_settings' object."""
17 20
18 # Computed lazily by _GetSdkBaseDir(). Shared by all XcodeSettings, so cached 21 # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached
19 # at class-level for efficiency. 22 # at class-level for efficiency.
20 _sdk_base_dir = None 23 _sdk_path_cache = {}
21 24
22 def __init__(self, spec): 25 def __init__(self, spec):
23 self.spec = spec 26 self.spec = spec
24 27
25 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. 28 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp.
26 # This means self.xcode_settings[config] always contains all settings 29 # This means self.xcode_settings[config] always contains all settings
27 # for that config -- the per-target settings as well. Settings that are 30 # for that config -- the per-target settings as well. Settings that are
28 # the same for all configs are implicitly per-target settings. 31 # the same for all configs are implicitly per-target settings.
29 self.xcode_settings = {} 32 self.xcode_settings = {}
30 configs = spec['configurations'] 33 configs = spec['configurations']
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return self._GetStandaloneBinaryPath() 215 return self._GetStandaloneBinaryPath()
213 216
214 def GetExecutablePath(self): 217 def GetExecutablePath(self):
215 """Returns the directory name of the bundle represented by this target. E.g. 218 """Returns the directory name of the bundle represented by this target. E.g.
216 Chromium.app/Contents/MacOS/Chromium.""" 219 Chromium.app/Contents/MacOS/Chromium."""
217 if self._IsBundle(): 220 if self._IsBundle():
218 return self._GetBundleBinaryPath() 221 return self._GetBundleBinaryPath()
219 else: 222 else:
220 return self._GetStandaloneBinaryPath() 223 return self._GetStandaloneBinaryPath()
221 224
222 def _GetSdkBaseDir(self): 225 def _GetSdkVersionInfoItem(self, sdk, infoitem):
223 """Returns the root of the 'Developer' directory. On Xcode 4.2 and prior, 226 job = subprocess.Popen(['xcodebuild', '-version', '-sdk', sdk, infoitem],
Nico 2013/03/18 15:17:05 As it turns out, this doesn't work with Xcode 4.2:
Nico 2013/03/18 15:32:31 Durr, it works if you say "macosx10.6" instead of
kal 2013/03/18 15:32:32 The SDK name is "macosx10.6". "10.6" is not a vali
Nico 2013/04/12 20:28:39 Zombie thread: Why do you redirect stderr at all?
224 this is usually just /Developer. Xcode 4.3 moved that folder into the Xcode 227 stdout=subprocess.PIPE,
225 bundle.""" 228 stderr=subprocess.STDOUT)
226 if not XcodeSettings._sdk_base_dir: 229 out = job.communicate()[0]
227 import subprocess 230 if job.returncode != 0:
228 job = subprocess.Popen(['xcode-select', '-print-path'], 231 sys.stderr.write(out + '\n')
229 stdout=subprocess.PIPE, 232 raise GypError('Error %d running xcodebuild' % job.returncode)
230 stderr=subprocess.STDOUT) 233 return out.rstrip('\n')
231 out, err = job.communicate()
232 if job.returncode != 0:
233 print out
234 raise Exception('Error %d running xcode-select' % job.returncode)
235 # The Developer folder moved in Xcode 4.3.
236 xcode43_sdk_path = os.path.join(
237 out.rstrip(), 'Platforms/MacOSX.platform/Developer/SDKs')
238 if os.path.isdir(xcode43_sdk_path):
239 XcodeSettings._sdk_base_dir = xcode43_sdk_path
240 else:
241 XcodeSettings._sdk_base_dir = os.path.join(out.rstrip(), 'SDKs')
242 return XcodeSettings._sdk_base_dir
243 234
244 def _SdkPath(self): 235 def _SdkPath(self):
245 sdk_root = self.GetPerTargetSetting('SDKROOT', default='macosx10.5') 236 sdk_root = self.GetPerTargetSetting('SDKROOT', default='macosx')
246 if sdk_root.startswith('macosx'): 237 if sdk_root not in XcodeSettings._sdk_path_cache:
247 return os.path.join(self._GetSdkBaseDir(), 238 XcodeSettings._sdk_path_cache[sdk_root] = self._GetSdkVersionInfoItem(
248 'MacOSX' + sdk_root[len('macosx'):] + '.sdk') 239 sdk_root, 'Path')
249 return sdk_root 240 return XcodeSettings._sdk_path_cache[sdk_root]
241
242 def _AppendPlatformVersionMinFlags(self, lst):
243 self._Appendf(lst, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s')
244 if 'IPHONEOS_DEPLOYMENT_TARGET' in self._Settings():
245 # TODO: Implement this better?
Nico 2013/03/13 17:45:25 nit: remove this TODO, it's not actionable and mys
246 sdk_path_basename = os.path.basename(self._SdkPath())
247 if sdk_path_basename.lower().startswith('iphonesimulator'):
248 self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET',
249 '-mios-simulator-version-min=%s')
250 else:
251 self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET',
252 '-miphoneos-version-min=%s')
250 253
251 def GetCflags(self, configname): 254 def GetCflags(self, configname):
252 """Returns flags that need to be added to .c, .cc, .m, and .mm 255 """Returns flags that need to be added to .c, .cc, .m, and .mm
253 compilations.""" 256 compilations."""
254 # This functions (and the similar ones below) do not offer complete 257 # This functions (and the similar ones below) do not offer complete
255 # emulation of all xcode_settings keys. They're implemented on demand. 258 # emulation of all xcode_settings keys. They're implemented on demand.
256 259
257 self.configname = configname 260 self.configname = configname
258 cflags = [] 261 cflags = []
259 262
260 sdk_root = self._SdkPath() 263 sdk_root = self._SdkPath()
261 if 'SDKROOT' in self._Settings(): 264 if 'SDKROOT' in self._Settings():
262 cflags.append('-isysroot %s' % sdk_root) 265 cflags.append('-isysroot %s' % sdk_root)
263 266
267 if self._Test('CLANG_WARN_CONSTANT_CONVERSION', 'YES', default='NO'):
268 cflags.append('-Wconstant-conversion')
269
264 if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'): 270 if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'):
265 cflags.append('-funsigned-char') 271 cflags.append('-funsigned-char')
266 272
267 if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'): 273 if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'):
268 cflags.append('-fasm-blocks') 274 cflags.append('-fasm-blocks')
269 275
270 if 'GCC_DYNAMIC_NO_PIC' in self._Settings(): 276 if 'GCC_DYNAMIC_NO_PIC' in self._Settings():
271 if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES': 277 if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES':
272 cflags.append('-mdynamic-no-pic') 278 cflags.append('-mdynamic-no-pic')
273 else: 279 else:
(...skipping 20 matching lines...) Expand all
294 300
295 if self._Test('GCC_SYMBOLS_PRIVATE_EXTERN', 'YES', default='NO'): 301 if self._Test('GCC_SYMBOLS_PRIVATE_EXTERN', 'YES', default='NO'):
296 cflags.append('-fvisibility=hidden') 302 cflags.append('-fvisibility=hidden')
297 303
298 if self._Test('GCC_TREAT_WARNINGS_AS_ERRORS', 'YES', default='NO'): 304 if self._Test('GCC_TREAT_WARNINGS_AS_ERRORS', 'YES', default='NO'):
299 cflags.append('-Werror') 305 cflags.append('-Werror')
300 306
301 if self._Test('GCC_WARN_ABOUT_MISSING_NEWLINE', 'YES', default='NO'): 307 if self._Test('GCC_WARN_ABOUT_MISSING_NEWLINE', 'YES', default='NO'):
302 cflags.append('-Wnewline-eof') 308 cflags.append('-Wnewline-eof')
303 309
304 self._Appendf(cflags, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') 310 self._AppendPlatformVersionMinFlags(cflags)
305 311
306 # TODO: 312 # TODO:
307 if self._Test('COPY_PHASE_STRIP', 'YES', default='NO'): 313 if self._Test('COPY_PHASE_STRIP', 'YES', default='NO'):
308 self._WarnUnimplemented('COPY_PHASE_STRIP') 314 self._WarnUnimplemented('COPY_PHASE_STRIP')
309 self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS') 315 self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS')
310 self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS') 316 self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS')
311 317
312 # TODO: This is exported correctly, but assigning to it is not supported. 318 # TODO: This is exported correctly, but assigning to it is not supported.
313 self._WarnUnimplemented('MACH_O_TYPE') 319 self._WarnUnimplemented('MACH_O_TYPE')
314 self._WarnUnimplemented('PRODUCT_TYPE') 320 self._WarnUnimplemented('PRODUCT_TYPE')
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 cflags_c = [] 353 cflags_c = []
348 self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s') 354 self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s')
349 cflags_c += self._Settings().get('OTHER_CFLAGS', []) 355 cflags_c += self._Settings().get('OTHER_CFLAGS', [])
350 self.configname = None 356 self.configname = None
351 return cflags_c 357 return cflags_c
352 358
353 def GetCflagsCC(self, configname): 359 def GetCflagsCC(self, configname):
354 """Returns flags that need to be added to .cc, and .mm compilations.""" 360 """Returns flags that need to be added to .cc, and .mm compilations."""
355 self.configname = configname 361 self.configname = configname
356 cflags_cc = [] 362 cflags_cc = []
363
364 clang_cxx_language_standard = self._Settings().get(
365 'CLANG_CXX_LANGUAGE_STANDARD')
366 if clang_cxx_language_standard == 'c++0x':
367 cflags_cc.append('-std=c++11')
368 elif clang_cxx_language_standard == 'gnu++0x':
369 cflags_cc.append('-std=gnu++11')
370 elif clang_cxx_language_standard:
371 cflags_cc.append('-std=%s' % clang_cxx_language_standard)
372
373 self._Appendf(cflags_cc, 'CLANG_CXX_LIBRARY', '-stdlib=%s')
374
357 if self._Test('GCC_ENABLE_CPP_RTTI', 'NO', default='YES'): 375 if self._Test('GCC_ENABLE_CPP_RTTI', 'NO', default='YES'):
358 cflags_cc.append('-fno-rtti') 376 cflags_cc.append('-fno-rtti')
359 if self._Test('GCC_ENABLE_CPP_EXCEPTIONS', 'NO', default='YES'): 377 if self._Test('GCC_ENABLE_CPP_EXCEPTIONS', 'NO', default='YES'):
360 cflags_cc.append('-fno-exceptions') 378 cflags_cc.append('-fno-exceptions')
361 if self._Test('GCC_INLINES_ARE_PRIVATE_EXTERN', 'YES', default='NO'): 379 if self._Test('GCC_INLINES_ARE_PRIVATE_EXTERN', 'YES', default='NO'):
362 cflags_cc.append('-fvisibility-inlines-hidden') 380 cflags_cc.append('-fvisibility-inlines-hidden')
363 if self._Test('GCC_THREADSAFE_STATICS', 'NO', default='YES'): 381 if self._Test('GCC_THREADSAFE_STATICS', 'NO', default='YES'):
364 cflags_cc.append('-fno-threadsafe-statics') 382 cflags_cc.append('-fno-threadsafe-statics')
365 if self._Test('GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO', 'NO', default='YES'): 383 if self._Test('GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO', 'NO', default='YES'):
366 cflags_cc.append('-Wno-invalid-offsetof') 384 cflags_cc.append('-Wno-invalid-offsetof')
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 if self._Test('DEAD_CODE_STRIPPING', 'YES', default='NO'): 535 if self._Test('DEAD_CODE_STRIPPING', 'YES', default='NO'):
518 ldflags.append('-Wl,-dead_strip') 536 ldflags.append('-Wl,-dead_strip')
519 537
520 if self._Test('PREBINDING', 'YES', default='NO'): 538 if self._Test('PREBINDING', 'YES', default='NO'):
521 ldflags.append('-Wl,-prebind') 539 ldflags.append('-Wl,-prebind')
522 540
523 self._Appendf( 541 self._Appendf(
524 ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s') 542 ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s')
525 self._Appendf( 543 self._Appendf(
526 ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s') 544 ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s')
527 self._Appendf( 545
528 ldflags, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') 546 self._AppendPlatformVersionMinFlags(ldflags)
547
529 if 'SDKROOT' in self._Settings(): 548 if 'SDKROOT' in self._Settings():
530 ldflags.append('-isysroot ' + self._SdkPath()) 549 ldflags.append('-isysroot ' + self._SdkPath())
531 550
532 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []): 551 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []):
533 ldflags.append('-L' + gyp_to_build_path(library_path)) 552 ldflags.append('-L' + gyp_to_build_path(library_path))
534 553
535 if 'ORDER_FILE' in self._Settings(): 554 if 'ORDER_FILE' in self._Settings():
536 ldflags.append('-Wl,-order_file ' + 555 ldflags.append('-Wl,-order_file ' +
537 '-Wl,' + gyp_to_build_path( 556 '-Wl,' + gyp_to_build_path(
538 self._Settings()['ORDER_FILE'])) 557 self._Settings()['ORDER_FILE']))
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 return matches 1054 return matches
1036 1055
1037 try: 1056 try:
1038 # Topologically sort, and then reverse, because we used an edge definition 1057 # Topologically sort, and then reverse, because we used an edge definition
1039 # that's inverted from the expected result of this function (see comment 1058 # that's inverted from the expected result of this function (see comment
1040 # above). 1059 # above).
1041 order = gyp.common.TopologicallySorted(env.keys(), GetEdges) 1060 order = gyp.common.TopologicallySorted(env.keys(), GetEdges)
1042 order.reverse() 1061 order.reverse()
1043 return order 1062 return order
1044 except gyp.common.CycleError, e: 1063 except gyp.common.CycleError, e:
1045 raise Exception( 1064 raise GypError(
1046 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) 1065 'Xcode environment variables are cyclically dependent: ' + str(e.nodes))
1047 1066
1048 1067
1049 def GetSortedXcodeEnv(xcode_settings, built_products_dir, srcroot, 1068 def GetSortedXcodeEnv(xcode_settings, built_products_dir, srcroot,
1050 configuration, additional_settings=None): 1069 configuration, additional_settings=None):
1051 env = _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, 1070 env = _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
1052 additional_settings) 1071 additional_settings)
1053 return [(key, env[key]) for key in _TopologicallySortedEnvVarKeys(env)] 1072 return [(key, env[key]) for key in _TopologicallySortedEnvVarKeys(env)]
1054 1073
1055 1074
1056 def GetSpecPostbuildCommands(spec, quiet=False): 1075 def GetSpecPostbuildCommands(spec, quiet=False):
1057 """Returns the list of postbuilds explicitly defined on |spec|, in a form 1076 """Returns the list of postbuilds explicitly defined on |spec|, in a form
1058 executable by a shell.""" 1077 executable by a shell."""
1059 postbuilds = [] 1078 postbuilds = []
1060 for postbuild in spec.get('postbuilds', []): 1079 for postbuild in spec.get('postbuilds', []):
1061 if not quiet: 1080 if not quiet:
1062 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( 1081 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % (
1063 spec['target_name'], postbuild['postbuild_name'])) 1082 spec['target_name'], postbuild['postbuild_name']))
1064 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) 1083 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action']))
1065 return postbuilds 1084 return postbuilds
OLDNEW
« no previous file with comments | « no previous file | test/ios/deployment-target/check-version-min.c » ('j') | test/mac/gyptest-clang-cxx-library.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698