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

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: Added tests 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
« no previous file with comments | « no previous file | test/ios/deployment-target/check-version-min.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
14 15
15 class XcodeSettings(object): 16 class XcodeSettings(object):
16 """A class that understands the gyp 'xcode_settings' object.""" 17 """A class that understands the gyp 'xcode_settings' object."""
17 18
18 # Computed lazily by _GetSdkBaseDir(). Shared by all XcodeSettings, so cached 19 # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached
19 # at class-level for efficiency. 20 # at class-level for efficiency.
20 _sdk_base_dir = None 21 _sdk_path_cache = {}
21 22
22 def __init__(self, spec): 23 def __init__(self, spec):
23 self.spec = spec 24 self.spec = spec
24 25
25 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. 26 # Per-target 'xcode_settings' are pushed down into configs earlier by gyp.
26 # This means self.xcode_settings[config] always contains all settings 27 # This means self.xcode_settings[config] always contains all settings
27 # for that config -- the per-target settings as well. Settings that are 28 # for that config -- the per-target settings as well. Settings that are
28 # the same for all configs are implicitly per-target settings. 29 # the same for all configs are implicitly per-target settings.
29 self.xcode_settings = {} 30 self.xcode_settings = {}
30 configs = spec['configurations'] 31 configs = spec['configurations']
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return self._GetStandaloneBinaryPath() 213 return self._GetStandaloneBinaryPath()
213 214
214 def GetExecutablePath(self): 215 def GetExecutablePath(self):
215 """Returns the directory name of the bundle represented by this target. E.g. 216 """Returns the directory name of the bundle represented by this target. E.g.
216 Chromium.app/Contents/MacOS/Chromium.""" 217 Chromium.app/Contents/MacOS/Chromium."""
217 if self._IsBundle(): 218 if self._IsBundle():
218 return self._GetBundleBinaryPath() 219 return self._GetBundleBinaryPath()
219 else: 220 else:
220 return self._GetStandaloneBinaryPath() 221 return self._GetStandaloneBinaryPath()
221 222
222 def _GetSdkBaseDir(self): 223 def _GetSdkVersionInfoItem(self, sdk, infoitem):
223 """Returns the root of the 'Developer' directory. On Xcode 4.2 and prior, 224 job = subprocess.Popen(['xcodebuild', '-version', '-sdk', sdk, infoitem],
224 this is usually just /Developer. Xcode 4.3 moved that folder into the Xcode 225 stdout=subprocess.PIPE,
225 bundle.""" 226 stderr=subprocess.STDOUT)
226 if not XcodeSettings._sdk_base_dir: 227 out, nul = job.communicate()
Sam Clegg 2013/03/12 19:06:24 The convention here is to use '_' for variables th
kal 2013/03/12 23:07:23 FIXED
227 import subprocess 228 if job.returncode != 0:
Sam Clegg 2013/03/12 19:06:24 Just "if job.retruncode:" is generally considered
228 job = subprocess.Popen(['xcode-select', '-print-path'], 229 print out
229 stdout=subprocess.PIPE, 230 raise Exception('Error %d running xcodebuild' % job.returncode)
Sam Clegg 2013/03/12 19:06:24 Use GypError() rather than Exception(). Most exc
kal 2013/03/12 23:07:23 FIXED.
230 stderr=subprocess.STDOUT) 231 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 232
244 def _SdkPath(self): 233 def _SdkPath(self):
245 sdk_root = self.GetPerTargetSetting('SDKROOT', default='macosx10.5') 234 sdk_root = self.GetPerTargetSetting('SDKROOT', default='macosx')
246 if sdk_root.startswith('macosx'): 235 if sdk_root not in XcodeSettings._sdk_path_cache:
247 return os.path.join(self._GetSdkBaseDir(), 236 XcodeSettings._sdk_path_cache[sdk_root] = self._GetSdkVersionInfoItem(
248 'MacOSX' + sdk_root[len('macosx'):] + '.sdk') 237 sdk_root, 'Path')
249 return sdk_root 238 return XcodeSettings._sdk_path_cache[sdk_root]
239
240 def _AppendPlatformVersionMinFlags(self, lst):
241 self._Appendf(lst, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s')
242 if 'IPHONEOS_DEPLOYMENT_TARGET' in self._Settings():
243 # TODO: Implement this better?
244 sdk_path_basename = os.path.basename(self._SdkPath())
245 if sdk_path_basename.lower().startswith('iphonesimulator'):
246 self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET',
247 '-mios-simulator-version-min=%s')
248 else:
249 self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET',
250 '-miphoneos-version-min=%s')
250 251
251 def GetCflags(self, configname): 252 def GetCflags(self, configname):
252 """Returns flags that need to be added to .c, .cc, .m, and .mm 253 """Returns flags that need to be added to .c, .cc, .m, and .mm
253 compilations.""" 254 compilations."""
254 # This functions (and the similar ones below) do not offer complete 255 # This functions (and the similar ones below) do not offer complete
255 # emulation of all xcode_settings keys. They're implemented on demand. 256 # emulation of all xcode_settings keys. They're implemented on demand.
256 257
257 self.configname = configname 258 self.configname = configname
258 cflags = [] 259 cflags = []
259 260
260 sdk_root = self._SdkPath() 261 sdk_root = self._SdkPath()
261 if 'SDKROOT' in self._Settings(): 262 if 'SDKROOT' in self._Settings():
262 cflags.append('-isysroot %s' % sdk_root) 263 cflags.append('-isysroot %s' % sdk_root)
263 264
265 if self._Test('CLANG_WARN_CONSTANT_CONVERSION', 'YES', default='NO'):
266 cflags.append('-Wconstant-conversion')
267
264 if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'): 268 if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'):
265 cflags.append('-funsigned-char') 269 cflags.append('-funsigned-char')
266 270
267 if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'): 271 if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'):
268 cflags.append('-fasm-blocks') 272 cflags.append('-fasm-blocks')
269 273
270 if 'GCC_DYNAMIC_NO_PIC' in self._Settings(): 274 if 'GCC_DYNAMIC_NO_PIC' in self._Settings():
271 if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES': 275 if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES':
272 cflags.append('-mdynamic-no-pic') 276 cflags.append('-mdynamic-no-pic')
273 else: 277 else:
(...skipping 20 matching lines...) Expand all
294 298
295 if self._Test('GCC_SYMBOLS_PRIVATE_EXTERN', 'YES', default='NO'): 299 if self._Test('GCC_SYMBOLS_PRIVATE_EXTERN', 'YES', default='NO'):
296 cflags.append('-fvisibility=hidden') 300 cflags.append('-fvisibility=hidden')
297 301
298 if self._Test('GCC_TREAT_WARNINGS_AS_ERRORS', 'YES', default='NO'): 302 if self._Test('GCC_TREAT_WARNINGS_AS_ERRORS', 'YES', default='NO'):
299 cflags.append('-Werror') 303 cflags.append('-Werror')
300 304
301 if self._Test('GCC_WARN_ABOUT_MISSING_NEWLINE', 'YES', default='NO'): 305 if self._Test('GCC_WARN_ABOUT_MISSING_NEWLINE', 'YES', default='NO'):
302 cflags.append('-Wnewline-eof') 306 cflags.append('-Wnewline-eof')
303 307
304 self._Appendf(cflags, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') 308 self._AppendPlatformVersionMinFlags(cflags)
305 309
306 # TODO: 310 # TODO:
307 if self._Test('COPY_PHASE_STRIP', 'YES', default='NO'): 311 if self._Test('COPY_PHASE_STRIP', 'YES', default='NO'):
308 self._WarnUnimplemented('COPY_PHASE_STRIP') 312 self._WarnUnimplemented('COPY_PHASE_STRIP')
309 self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS') 313 self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS')
310 self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS') 314 self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS')
311 315
312 # TODO: This is exported correctly, but assigning to it is not supported. 316 # TODO: This is exported correctly, but assigning to it is not supported.
313 self._WarnUnimplemented('MACH_O_TYPE') 317 self._WarnUnimplemented('MACH_O_TYPE')
314 self._WarnUnimplemented('PRODUCT_TYPE') 318 self._WarnUnimplemented('PRODUCT_TYPE')
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 cflags_c = [] 351 cflags_c = []
348 self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s') 352 self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s')
349 cflags_c += self._Settings().get('OTHER_CFLAGS', []) 353 cflags_c += self._Settings().get('OTHER_CFLAGS', [])
350 self.configname = None 354 self.configname = None
351 return cflags_c 355 return cflags_c
352 356
353 def GetCflagsCC(self, configname): 357 def GetCflagsCC(self, configname):
354 """Returns flags that need to be added to .cc, and .mm compilations.""" 358 """Returns flags that need to be added to .cc, and .mm compilations."""
355 self.configname = configname 359 self.configname = configname
356 cflags_cc = [] 360 cflags_cc = []
361
362 clang_cxx_language_standard = self._Settings().get(
363 'CLANG_CXX_LANGUAGE_STANDARD')
364 if clang_cxx_language_standard == 'c++0x':
365 cflags_cc.append('-std=c++11')
366 elif clang_cxx_language_standard == 'gnu++0x':
367 cflags_cc.append('-std=gnu++11')
368 elif clang_cxx_language_standard:
369 cflags_cc.append('-std=%s' % clang_cxx_language_standard)
370
371 self._Appendf(cflags_cc, 'CLANG_CXX_LIBRARY', '-stdlib=%s')
372
357 if self._Test('GCC_ENABLE_CPP_RTTI', 'NO', default='YES'): 373 if self._Test('GCC_ENABLE_CPP_RTTI', 'NO', default='YES'):
358 cflags_cc.append('-fno-rtti') 374 cflags_cc.append('-fno-rtti')
359 if self._Test('GCC_ENABLE_CPP_EXCEPTIONS', 'NO', default='YES'): 375 if self._Test('GCC_ENABLE_CPP_EXCEPTIONS', 'NO', default='YES'):
360 cflags_cc.append('-fno-exceptions') 376 cflags_cc.append('-fno-exceptions')
361 if self._Test('GCC_INLINES_ARE_PRIVATE_EXTERN', 'YES', default='NO'): 377 if self._Test('GCC_INLINES_ARE_PRIVATE_EXTERN', 'YES', default='NO'):
362 cflags_cc.append('-fvisibility-inlines-hidden') 378 cflags_cc.append('-fvisibility-inlines-hidden')
363 if self._Test('GCC_THREADSAFE_STATICS', 'NO', default='YES'): 379 if self._Test('GCC_THREADSAFE_STATICS', 'NO', default='YES'):
364 cflags_cc.append('-fno-threadsafe-statics') 380 cflags_cc.append('-fno-threadsafe-statics')
365 if self._Test('GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO', 'NO', default='YES'): 381 if self._Test('GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO', 'NO', default='YES'):
366 cflags_cc.append('-Wno-invalid-offsetof') 382 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'): 533 if self._Test('DEAD_CODE_STRIPPING', 'YES', default='NO'):
518 ldflags.append('-Wl,-dead_strip') 534 ldflags.append('-Wl,-dead_strip')
519 535
520 if self._Test('PREBINDING', 'YES', default='NO'): 536 if self._Test('PREBINDING', 'YES', default='NO'):
521 ldflags.append('-Wl,-prebind') 537 ldflags.append('-Wl,-prebind')
522 538
523 self._Appendf( 539 self._Appendf(
524 ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s') 540 ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s')
525 self._Appendf( 541 self._Appendf(
526 ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s') 542 ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s')
527 self._Appendf( 543
528 ldflags, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') 544 self._AppendPlatformVersionMinFlags(ldflags)
545
529 if 'SDKROOT' in self._Settings(): 546 if 'SDKROOT' in self._Settings():
530 ldflags.append('-isysroot ' + self._SdkPath()) 547 ldflags.append('-isysroot ' + self._SdkPath())
531 548
532 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []): 549 for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []):
533 ldflags.append('-L' + gyp_to_build_path(library_path)) 550 ldflags.append('-L' + gyp_to_build_path(library_path))
534 551
535 if 'ORDER_FILE' in self._Settings(): 552 if 'ORDER_FILE' in self._Settings():
536 ldflags.append('-Wl,-order_file ' + 553 ldflags.append('-Wl,-order_file ' +
537 '-Wl,' + gyp_to_build_path( 554 '-Wl,' + gyp_to_build_path(
538 self._Settings()['ORDER_FILE'])) 555 self._Settings()['ORDER_FILE']))
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 def GetSpecPostbuildCommands(spec, quiet=False): 1073 def GetSpecPostbuildCommands(spec, quiet=False):
1057 """Returns the list of postbuilds explicitly defined on |spec|, in a form 1074 """Returns the list of postbuilds explicitly defined on |spec|, in a form
1058 executable by a shell.""" 1075 executable by a shell."""
1059 postbuilds = [] 1076 postbuilds = []
1060 for postbuild in spec.get('postbuilds', []): 1077 for postbuild in spec.get('postbuilds', []):
1061 if not quiet: 1078 if not quiet:
1062 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( 1079 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % (
1063 spec['target_name'], postbuild['postbuild_name'])) 1080 spec['target_name'], postbuild['postbuild_name']))
1064 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) 1081 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action']))
1065 return postbuilds 1082 return postbuilds
OLDNEW
« no previous file with comments | « no previous file | test/ios/deployment-target/check-version-min.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698