Browse Source

Upgrade GYP to r1078

v0.7.4-release
Ryan Dahl 13 years ago
parent
commit
dbfc8198a6
  1. 16
      tools/gyp/DEPS
  2. 2
      tools/gyp/pylib/gyp/MSVSSettings.py
  3. 2
      tools/gyp/pylib/gyp/__init__.py
  4. 3
      tools/gyp/pylib/gyp/generator/gypd.py
  5. 3
      tools/gyp/pylib/gyp/generator/gypsh.py
  6. 338
      tools/gyp/pylib/gyp/generator/make.py
  7. 96
      tools/gyp/pylib/gyp/generator/msvs.py
  8. 33
      tools/gyp/pylib/gyp/generator/ninja.py
  9. 3
      tools/gyp/pylib/gyp/generator/scons.py
  10. 5
      tools/gyp/pylib/gyp/generator/xcode.py
  11. 10
      tools/gyp/pylib/gyp/mac_tool.py

16
tools/gyp/DEPS

@ -2,7 +2,21 @@
# #
# (You don't need to use gclient for normal GYP development work.) # (You don't need to use gclient for normal GYP development work.)
vars = {
"chrome_trunk": "http://src.chromium.org/svn/trunk",
}
deps = { deps = {
"scons": "scons":
"http://src.chromium.org/svn/trunk/src/third_party/scons@44099", Var("chrome_trunk") + "/src/third_party/scons@44099",
}
deps_os = {
"win": {
"third_party/cygwin":
Var("chrome_trunk") + "/deps/third_party/cygwin@66844",
"third_party/python_26":
Var("chrome_trunk") + "/tools/third_party/python_26@89111",
},
} }

2
tools/gyp/pylib/gyp/MSVSSettings.py

@ -966,6 +966,7 @@ _Same(_lib, 'ModuleDefinitionFile', _file_name) # /DEF
_Same(_lib, 'OutputFile', _file_name) # /OUT _Same(_lib, 'OutputFile', _file_name) # /OUT
_Same(_lib, 'SuppressStartupBanner', _boolean) # /NOLOGO _Same(_lib, 'SuppressStartupBanner', _boolean) # /NOLOGO
_Same(_lib, 'UseUnicodeResponseFiles', _boolean) _Same(_lib, 'UseUnicodeResponseFiles', _boolean)
_Same(_lib, 'LinkTimeCodeGeneration', _boolean) # /LTCG
# TODO(jeanluc) _link defines the same value that gets moved to # TODO(jeanluc) _link defines the same value that gets moved to
# ProjectReference. We may want to validate that they are consistent. # ProjectReference. We may want to validate that they are consistent.
@ -980,7 +981,6 @@ _MSBuildOnly(_lib, 'ErrorReporting',
'QueueForNextLogin', # /ERRORREPORT:QUEUE 'QueueForNextLogin', # /ERRORREPORT:QUEUE
'SendErrorReport', # /ERRORREPORT:SEND 'SendErrorReport', # /ERRORREPORT:SEND
'NoErrorReport'])) # /ERRORREPORT:NONE 'NoErrorReport'])) # /ERRORREPORT:NONE
_MSBuildOnly(_lib, 'LinkTimeCodeGeneration', _boolean) # /LTCG
_MSBuildOnly(_lib, 'MinimumRequiredVersion', _string) _MSBuildOnly(_lib, 'MinimumRequiredVersion', _string)
_MSBuildOnly(_lib, 'Name', _file_name) # /NAME _MSBuildOnly(_lib, 'Name', _file_name) # /NAME
_MSBuildOnly(_lib, 'RemoveObjects', _file_list) # /REMOVE _MSBuildOnly(_lib, 'RemoveObjects', _file_list) # /REMOVE

2
tools/gyp/pylib/gyp/__init__.py

@ -335,6 +335,7 @@ def main(args):
'linux2': 'make', 'linux2': 'make',
'linux3': 'make', 'linux3': 'make',
'openbsd4': 'make', 'openbsd4': 'make',
'openbsd5': 'make',
'sunos5': 'make',}[sys.platform] ] 'sunos5': 'make',}[sys.platform] ]
if not options.generator_output and options.use_environment: if not options.generator_output and options.use_environment:
@ -418,6 +419,7 @@ def main(args):
if home_dot_gyp != None: if home_dot_gyp != None:
default_include = os.path.join(home_dot_gyp, 'include.gypi') default_include = os.path.join(home_dot_gyp, 'include.gypi')
if os.path.exists(default_include): if os.path.exists(default_include):
print 'Using overrides found in ' + default_include
includes.append(default_include) includes.append(default_include)
# Command-line --include files come after the default include. # Command-line --include files come after the default include.

3
tools/gyp/pylib/gyp/generator/gypd.py

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# Copyright (c) 2009 Google Inc. All rights reserved. # Copyright (c) 2011 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -46,6 +46,7 @@ _generator_identity_variables = [
'INTERMEDIATE_DIR', 'INTERMEDIATE_DIR',
'PRODUCT_DIR', 'PRODUCT_DIR',
'RULE_INPUT_ROOT', 'RULE_INPUT_ROOT',
'RULE_INPUT_DIRNAME',
'RULE_INPUT_EXT', 'RULE_INPUT_EXT',
'RULE_INPUT_NAME', 'RULE_INPUT_NAME',
'RULE_INPUT_PATH', 'RULE_INPUT_PATH',

3
tools/gyp/pylib/gyp/generator/gypsh.py

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# Copyright (c) 2009 Google Inc. All rights reserved. # Copyright (c) 2011 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -28,6 +28,7 @@ _generator_identity_variables = [
'INTERMEDIATE_DIR', 'INTERMEDIATE_DIR',
'PRODUCT_DIR', 'PRODUCT_DIR',
'RULE_INPUT_ROOT', 'RULE_INPUT_ROOT',
'RULE_INPUT_DIRNAME',
'RULE_INPUT_EXT', 'RULE_INPUT_EXT',
'RULE_INPUT_NAME', 'RULE_INPUT_NAME',
'RULE_INPUT_PATH', 'RULE_INPUT_PATH',

338
tools/gyp/pylib/gyp/generator/make.py

@ -44,6 +44,7 @@ generator_default_variables = {
'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen',
'PRODUCT_DIR': '$(builddir)', 'PRODUCT_DIR': '$(builddir)',
'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', # This gets expanded by Python. 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', # This gets expanded by Python.
'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s', # This gets expanded by Python.
'RULE_INPUT_PATH': '$(abspath $<)', 'RULE_INPUT_PATH': '$(abspath $<)',
'RULE_INPUT_EXT': '$(suffix $<)', 'RULE_INPUT_EXT': '$(suffix $<)',
'RULE_INPUT_NAME': '$(notdir $<)', 'RULE_INPUT_NAME': '$(notdir $<)',
@ -61,14 +62,7 @@ generator_wants_sorted_dependencies = False
def GetFlavor(params): def GetFlavor(params):
"""Returns |params.flavor| if it's set, the system's default flavor else.""" """Returns |params.flavor| if it's set, the system's default flavor else."""
flavors = { return params.get('flavor', 'mac' if sys.platform == 'darwin' else 'linux')
'darwin': 'mac',
'sunos5': 'solaris',
'freebsd7': 'freebsd',
'freebsd8': 'freebsd',
}
flavor = flavors.get(sys.platform, 'linux')
return params.get('flavor', flavor)
def CalculateVariables(default_variables, params): def CalculateVariables(default_variables, params):
@ -77,8 +71,7 @@ def CalculateVariables(default_variables, params):
default_variables['LINKER_SUPPORTS_ICF'] = \ default_variables['LINKER_SUPPORTS_ICF'] = \
gyp.system_test.TestLinkerSupportsICF(cc_command=cc_target) gyp.system_test.TestLinkerSupportsICF(cc_command=cc_target)
flavor = GetFlavor(params) if GetFlavor(params) == 'mac':
if flavor == 'mac':
default_variables.setdefault('OS', 'mac') default_variables.setdefault('OS', 'mac')
default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib')
default_variables.setdefault('SHARED_LIB_DIR', default_variables.setdefault('SHARED_LIB_DIR',
@ -101,7 +94,7 @@ def CalculateVariables(default_variables, params):
global COMPILABLE_EXTENSIONS global COMPILABLE_EXTENSIONS
COMPILABLE_EXTENSIONS.update({'.m': 'objc', '.mm' : 'objcxx'}) COMPILABLE_EXTENSIONS.update({'.m': 'objc', '.mm' : 'objcxx'})
else: else:
default_variables.setdefault('OS', flavor) default_variables.setdefault('OS', 'linux')
default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') default_variables.setdefault('SHARED_LIB_SUFFIX', '.so')
default_variables.setdefault('SHARED_LIB_DIR','$(builddir)/lib.$(TOOLSET)') default_variables.setdefault('SHARED_LIB_DIR','$(builddir)/lib.$(TOOLSET)')
default_variables.setdefault('LIB_DIR', '$(obj).$(TOOLSET)') default_variables.setdefault('LIB_DIR', '$(obj).$(TOOLSET)')
@ -255,6 +248,8 @@ abs_obj := $(abspath $(obj))
# generated dependency rule Makefiles in one pass. # generated dependency rule Makefiles in one pass.
all_deps := all_deps :=
%(make_global_settings)s
# C++ apps need to be linked with g++. # C++ apps need to be linked with g++.
# #
# Note: flock is used to seralize linking. Linking is a memory-intensive # Note: flock is used to seralize linking. Linking is a memory-intensive
@ -266,9 +261,6 @@ all_deps :=
# This will allow make to invoke N linker processes as specified in -jN. # This will allow make to invoke N linker processes as specified in -jN.
LINK ?= %(flock)s $(builddir)/linker.lock $(CXX) LINK ?= %(flock)s $(builddir)/linker.lock $(CXX)
%(make_global_settings)s
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC) CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS) CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX) CXX.target ?= $(CXX)
@ -357,7 +349,7 @@ cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $
quiet_cmd_cxx = CXX($(TOOLSET)) $@ quiet_cmd_cxx = CXX($(TOOLSET)) $@
cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
%(extra_commands)s %(mac_commands)s
quiet_cmd_touch = TOUCH $@ quiet_cmd_touch = TOUCH $@
cmd_touch = touch $@ cmd_touch = touch $@
@ -407,6 +399,23 @@ command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\\
# $| -- order-only dependencies # $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# Helper that executes all postbuilds, and deletes the output file when done
# if any of the postbuilds failed.
define do_postbuilds
@E=0;\\
for p in $(POSTBUILDS); do\\
eval $$p;\\
F=$$?;\\
if [ $$F -ne 0 ]; then\\
E=$$F;\\
fi;\\
done;\\
if [ $$E -ne 0 ]; then\\
rm -rf "$@";\\
exit $$E;\\
fi
endef
# do_cmd: run a command via the above cmd_foo names, if necessary. # do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes. # Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. # Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
@ -427,7 +436,7 @@ $(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep)) @$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)), $(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done $(call do_postbuilds)
) )
) )
endef endef
@ -471,14 +480,6 @@ quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@
cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4)
""" """
SHARED_HEADER_SUN_COMMANDS = """
# gyp-sun-tool is written next to the root Makefile by gyp.
# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd
# already.
quiet_cmd_sun_tool = SUNTOOL $(4) $<
cmd_sun_tool = ./gyp-sun-tool $(4) $< "$@"
"""
def WriteRootHeaderSuffixRules(writer): def WriteRootHeaderSuffixRules(writer):
extensions = sorted(COMPILABLE_EXTENSIONS.keys(), key=str.lower) extensions = sorted(COMPILABLE_EXTENSIONS.keys(), key=str.lower)
@ -654,9 +655,11 @@ class XcodeSettings(object):
def _Test(self, test_key, cond_key, default): def _Test(self, test_key, cond_key, default):
return self._Settings().get(test_key, default) == cond_key return self._Settings().get(test_key, default) == cond_key
def _Appendf(self, lst, test_key, format_str): def _Appendf(self, lst, test_key, format_str, default=None):
if test_key in self._Settings(): if test_key in self._Settings():
lst.append(format_str % str(self._Settings()[test_key])) lst.append(format_str % str(self._Settings()[test_key]))
elif default:
lst.append(format_str % str(default))
def _WarnUnimplemented(self, test_key): def _WarnUnimplemented(self, test_key):
if test_key in self._Settings(): if test_key in self._Settings():
@ -676,8 +679,12 @@ class XcodeSettings(object):
valid for bundles.""" valid for bundles."""
assert self._IsBundle() assert self._IsBundle()
if self.spec['type'] in ('loadable_module', 'shared_library'): if self.spec['type'] in ('loadable_module', 'shared_library'):
default_wrapper_extension = {
'loadable_module': 'bundle',
'shared_library': 'framework',
}[self.spec['type']]
wrapper_extension = self.GetPerTargetSetting( wrapper_extension = self.GetPerTargetSetting(
'WRAPPER_EXTENSION', default='framework') 'WRAPPER_EXTENSION', default=default_wrapper_extension)
return '.' + self.spec.get('product_extension', wrapper_extension) return '.' + self.spec.get('product_extension', wrapper_extension)
elif self.spec['type'] == 'executable': elif self.spec['type'] == 'executable':
return '.app' return '.app'
@ -716,22 +723,47 @@ class XcodeSettings(object):
"""Returns the qualified path to the bundle's plist file. E.g. """Returns the qualified path to the bundle's plist file. E.g.
Chromium.app/Contents/Info.plist. Only valid for bundles.""" Chromium.app/Contents/Info.plist. Only valid for bundles."""
assert self._IsBundle() assert self._IsBundle()
assert self.spec['type'] != 'loadable_modules', ( if self.spec['type'] in ('executable', 'loadable_module'):
"Info.plist files for loadable_modules not yet supported by the "
"make generator (target %s)" % self.spec['target_name']) # Not tested.
if self.spec['type'] == 'executable':
return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist')
else: else:
return os.path.join(self.GetBundleContentsFolderPath(), return os.path.join(self.GetBundleContentsFolderPath(),
'Resources', 'Info.plist') 'Resources', 'Info.plist')
def GetProductType(self):
"""Returns the PRODUCT_TYPE of this target."""
if self._IsBundle():
return {
'executable': 'com.apple.product-type.application',
'loadable_module': 'com.apple.product-type.bundle',
'shared_library': 'com.apple.product-type.framework',
}[self.spec['type']]
else:
return {
'executable': 'com.apple.product-type.tool',
'loadable_module': 'com.apple.product-type.library.dynamic',
'shared_library': 'com.apple.product-type.library.dynamic',
'static_library': 'com.apple.product-type.library.static',
}[self.spec['type']]
def GetMachOType(self):
"""Returns the MACH_O_TYPE of this target."""
# Weird, but matches Xcode.
if not self._IsBundle() and self.spec['type'] == 'executable':
return ''
return {
'executable': 'mh_execute',
'static_library': 'staticlib',
'shared_library': 'mh_dylib',
'loadable_module': 'mh_bundle',
}[self.spec['type']]
def _GetBundleBinaryPath(self): def _GetBundleBinaryPath(self):
"""Returns the name of the bundle binary of by this target. """Returns the name of the bundle binary of by this target.
E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles.""" E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles."""
assert self._IsBundle() assert self._IsBundle()
if self.spec['type'] in ('loadable_module', 'shared_library'): if self.spec['type'] in ('shared_library'):
path = self.GetBundleContentsFolderPath() path = self.GetBundleContentsFolderPath()
elif self.spec['type'] == 'executable': elif self.spec['type'] in ('executable', 'loadable_module'):
path = os.path.join(self.GetBundleContentsFolderPath(), 'MacOS') path = os.path.join(self.GetBundleContentsFolderPath(), 'MacOS')
return os.path.join(path, self.spec.get('product_name', return os.path.join(path, self.spec.get('product_name',
self.spec['target_name'])) self.spec['target_name']))
@ -819,7 +851,7 @@ class XcodeSettings(object):
if self._Test('GCC_ENABLE_PASCAL_STRINGS', 'YES', default='YES'): if self._Test('GCC_ENABLE_PASCAL_STRINGS', 'YES', default='YES'):
cflags.append('-mpascal-strings') cflags.append('-mpascal-strings')
self._Appendf(cflags, 'GCC_OPTIMIZATION_LEVEL', '-O%s') self._Appendf(cflags, 'GCC_OPTIMIZATION_LEVEL', '-O%s', default='s')
if self._Test('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES', default='YES'): if self._Test('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES', default='YES'):
dbg_format = self._Settings().get('DEBUG_INFORMATION_FORMAT', 'dwarf') dbg_format = self._Settings().get('DEBUG_INFORMATION_FORMAT', 'dwarf')
@ -828,12 +860,7 @@ class XcodeSettings(object):
elif dbg_format == 'stabs': elif dbg_format == 'stabs':
raise NotImplementedError('stabs debug format is not supported yet.') raise NotImplementedError('stabs debug format is not supported yet.')
elif dbg_format == 'dwarf-with-dsym': elif dbg_format == 'dwarf-with-dsym':
# TODO(thakis): this is needed for mac_breakpad chromium builds, but not cflags.append('-gdwarf-2')
# for regular chromium builds.
# -gdwarf-2 as well, but needs to invoke dsymutil after linking too:
# dsymutil build/Default/TestAppGyp.app/Contents/MacOS/TestAppGyp \
# -o build/Default/TestAppGyp.app.dSYM
raise NotImplementedError('dsym debug format is not supported yet.')
else: else:
raise NotImplementedError('Unknown debug format %s' % dbg_format) raise NotImplementedError('Unknown debug format %s' % dbg_format)
@ -850,15 +877,17 @@ class XcodeSettings(object):
# TODO: # TODO:
self._WarnUnimplemented('ARCHS') self._WarnUnimplemented('ARCHS')
self._WarnUnimplemented('COPY_PHASE_STRIP') if self._Test('COPY_PHASE_STRIP', 'YES', default='NO'):
self._WarnUnimplemented('DEPLOYMENT_POSTPROCESSING') self._WarnUnimplemented('COPY_PHASE_STRIP')
self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS') self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS')
self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS') self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS')
self._WarnUnimplemented('GCC_ENABLE_OBJC_GC') self._WarnUnimplemented('GCC_ENABLE_OBJC_GC')
self._WarnUnimplemented('INFOPLIST_PREPROCESS') self._WarnUnimplemented('INFOPLIST_PREPROCESS')
self._WarnUnimplemented('INFOPLIST_PREPROCESSOR_DEFINITIONS') self._WarnUnimplemented('INFOPLIST_PREPROCESSOR_DEFINITIONS')
self._WarnUnimplemented('STRIPFLAGS')
self._WarnUnimplemented('STRIP_INSTALLED_PRODUCT') # TODO: This is exported correctly, but assigning to it is not supported.
self._WarnUnimplemented('MACH_O_TYPE')
self._WarnUnimplemented('PRODUCT_TYPE')
# TODO: Do not hardcode arch. Supporting fat binaries will be annoying. # TODO: Do not hardcode arch. Supporting fat binaries will be annoying.
cflags.append('-arch i386') cflags.append('-arch i386')
@ -1040,6 +1069,64 @@ class XcodeSettings(object):
return default return default
return result return result
def _GetStripPostbuilds(self, configname, output_binary):
"""Returns a list of shell commands that contain the shell commands
neccessary to strip this target's binary. These should be run as postbuilds
before the actual postbuilds run."""
self.configname = configname
result = []
if (self._Test('DEPLOYMENT_POSTPROCESSING', 'YES', default='NO') and
self._Test('STRIP_INSTALLED_PRODUCT', 'YES', default='NO')):
default_strip_style = 'debugging'
if self._IsBundle():
default_strip_style = 'non-global'
elif self.spec['type'] == 'executable':
default_strip_style = 'all'
strip_style = self._Settings().get('STRIP_STYLE', default_strip_style)
strip_flags = {
'all': '',
'non-global': '-x',
'debugging': '-S',
}[strip_style]
explicit_strip_flags = self._Settings().get('STRIPFLAGS', '')
if explicit_strip_flags:
strip_flags += ' ' + explicit_strip_flags
result.append('echo STRIP\\(%s\\)' % self.spec['target_name'])
result.append('strip %s %s' % (strip_flags, output_binary))
self.configname = None
return result
def _GetDebugPostbuilds(self, configname, output, output_binary):
"""Returns a list of shell commands that contain the shell commands
neccessary to massage this target's debug information. These should be run
as postbuilds before the actual postbuilds run."""
self.configname = configname
# For static libraries, no dSYMs are created.
result = []
if (self._Test('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES', default='YES') and
self._Test(
'DEBUG_INFORMATION_FORMAT', 'dwarf-with-dsym', default='dwarf') and
self.spec['type'] != 'static_library'):
result.append('echo DSYMUTIL\\(%s\\)' % self.spec['target_name'])
result.append('dsymutil %s -o %s' % (output_binary, output + '.dSYM'))
self.configname = None
return result
def GetTargetPostbuilds(self, configname, output, output_binary):
"""Returns a list of shell commands that contain the shell commands
to run as postbuilds for this target, before the actual postbuilds."""
# dSYMs need to build before stripping happens.
return (self._GetDebugPostbuilds(configname, output, output_binary) +
self._GetStripPostbuilds(configname, output_binary))
class MacPrefixHeader(object): class MacPrefixHeader(object):
"""A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. If """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. If
@ -1204,6 +1291,15 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
self.type = spec['type'] self.type = spec['type']
self.toolset = spec['toolset'] self.toolset = spec['toolset']
if self.type == 'settings':
# TODO: 'settings' is not actually part of gyp; it was
# accidentally introduced somehow into just the Linux build files.
# Remove this (or make it an error) once all the users are fixed.
print ("WARNING: %s uses invalid type 'settings'. " % self.target +
"Please fix the source gyp file to use type 'none'.")
print "See http://code.google.com/p/chromium/issues/detail?id=96629 ."
self.type = 'none'
# Bundles are directories with a certain subdirectory structure, instead of # Bundles are directories with a certain subdirectory structure, instead of
# just a single file. Bundle rules do not produce a binary but also package # just a single file. Bundle rules do not produce a binary but also package
# resources into that directory. # resources into that directory.
@ -1446,12 +1542,20 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
for rule_source in rule.get('rule_sources', []): for rule_source in rule.get('rule_sources', []):
dirs = set() dirs = set()
rule_source_basename = os.path.basename(rule_source) (rule_source_dirname, rule_source_basename) = os.path.split(rule_source)
(rule_source_root, rule_source_ext) = \ (rule_source_root, rule_source_ext) = \
os.path.splitext(rule_source_basename) os.path.splitext(rule_source_basename)
outputs = [self.ExpandInputRoot(out, rule_source_root) outputs = [self.ExpandInputRoot(out, rule_source_root,
rule_source_dirname)
for out in rule['outputs']] for out in rule['outputs']]
# If an output is just the file name, turn it into a path so
# FixupArgPath() will know to Absolutify() it.
outputs = map(
lambda x : os.path.dirname(x) and x or os.path.join('.', x),
outputs)
for out in outputs: for out in outputs:
dir = os.path.dirname(out) dir = os.path.dirname(out)
if dir: if dir:
@ -1486,7 +1590,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
self.WriteLn('all_deps += %s' % ' '.join(outputs)) self.WriteLn('all_deps += %s' % ' '.join(outputs))
self._num_outputs += len(outputs) self._num_outputs += len(outputs)
action = [self.ExpandInputRoot(ac, rule_source_root) action = [self.ExpandInputRoot(ac, rule_source_root,
rule_source_dirname)
for ac in rule['action']] for ac in rule['action']]
mkdirs = '' mkdirs = ''
if len(dirs) > 0: if len(dirs) > 0:
@ -1789,9 +1894,6 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
""" """
assert not self.is_mac_bundle assert not self.is_mac_bundle
if self.type == 'settings':
return '' # Doesn't have any output.
path = os.path.join('$(obj).' + self.toolset, self.path) path = os.path.join('$(obj).' + self.toolset, self.path)
if self.type == 'executable' or self._InstallImmediately(): if self.type == 'executable' or self._InstallImmediately():
path = '$(builddir)' path = '$(builddir)'
@ -1860,11 +1962,22 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
order_only = True, order_only = True,
multiple_output_trick = False) multiple_output_trick = False)
if self.type not in ('settings', 'none'): has_target_postbuilds = False
if self.type != 'none':
for configname in sorted(configs.keys()): for configname in sorted(configs.keys()):
config = configs[configname] config = configs[configname]
if self.flavor == 'mac': if self.flavor == 'mac':
ldflags = self.xcode_settings.GetLdflags(self, configname) ldflags = self.xcode_settings.GetLdflags(self, configname)
# TARGET_POSTBUILDS_$(BUILDTYPE) is added to postbuilds later on.
target_postbuilds = self.xcode_settings.GetTargetPostbuilds(
configname, self.output, self.output_binary)
if target_postbuilds:
has_target_postbuilds = True
self.WriteLn('%s: TARGET_POSTBUILDS_%s := %s' %
(self.output,
configname,
gyp.common.EncodePOSIXShellList(target_postbuilds)))
else: else:
ldflags = config.get('ldflags', []) ldflags = config.get('ldflags', [])
# Compute an rpath for this output if needed. # Compute an rpath for this output if needed.
@ -1890,6 +2003,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
postbuilds = [] postbuilds = []
if self.flavor == 'mac': if self.flavor == 'mac':
if has_target_postbuilds:
postbuilds.append('$(TARGET_POSTBUILDS_$(BUILDTYPE))')
# Postbuild actions. Like actions, but implicitly depend on the target's # Postbuild actions. Like actions, but implicitly depend on the target's
# output. # output.
for postbuild in spec.get('postbuilds', []): for postbuild in spec.get('postbuilds', []):
@ -1901,14 +2016,40 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# absolutified. Else, it's in the PATH (e.g. install_name_tool, ln). # absolutified. Else, it's in the PATH (e.g. install_name_tool, ln).
if os.path.sep in shell_list[0]: if os.path.sep in shell_list[0]:
shell_list[0] = self.Absolutify(shell_list[0]) shell_list[0] = self.Absolutify(shell_list[0])
postbuilds.append('%s' % gyp.common.EncodePOSIXShellList(shell_list))
# "script.sh" -> "./script.sh"
if not os.path.sep in shell_list[0]:
shell_list[0] = os.path.join('.', shell_list[0])
postbuilds.append(gyp.common.EncodePOSIXShellList(shell_list))
if postbuilds:
# Write envvars for postbuilds.
extra_settings = {}
# CHROMIUM_STRIP_SAVE_FILE is a chromium-specific hack.
# TODO(thakis): It would be nice to have some general mechanism instead.
strip_save_file = self.xcode_settings.GetPerTargetSetting(
'CHROMIUM_STRIP_SAVE_FILE')
if strip_save_file:
strip_save_file = self.Absolutify(strip_save_file)
else:
# Explicitly clear this out, else a postbuild might pick up an export
# from an earlier target.
strip_save_file = ''
extra_settings['CHROMIUM_STRIP_SAVE_FILE'] = strip_save_file
self.WriteXcodeEnv(self.output, spec, additional_settings=extra_settings)
for i in xrange(len(postbuilds)):
if not postbuilds[i].startswith('$'):
postbuilds[i] = EscapeShellArgument(postbuilds[i])
self.WriteLn('%s: builddir := $(abs_builddir)' % self.output)
self.WriteLn('%s: POSTBUILDS := %s' % (self.output, ' '.join(postbuilds)))
# A bundle directory depends on its dependencies such as bundle resources # A bundle directory depends on its dependencies such as bundle resources
# and bundle binary. When all dependencies have been built, the bundle # and bundle binary. When all dependencies have been built, the bundle
# needs to be packaged. # needs to be packaged.
if self.is_mac_bundle: if self.is_mac_bundle:
self.WriteXcodeEnv(self.output, spec) # For postbuilds
# If the framework doesn't contain a binary, then nothing depends # If the framework doesn't contain a binary, then nothing depends
# on the actions -- make the framework depend on them directly too. # on the actions -- make the framework depend on them directly too.
self.WriteDependencyOnExtraOutputs(self.output, extra_outputs) self.WriteDependencyOnExtraOutputs(self.output, extra_outputs)
@ -1926,8 +2067,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# Bundle postbuilds can depend on the whole bundle, so run them after # Bundle postbuilds can depend on the whole bundle, so run them after
# the bundle is packaged, not already after the bundle binary is done. # the bundle is packaged, not already after the bundle binary is done.
for postbuild in postbuilds: if postbuilds:
self.WriteLn('\t@' + postbuild) self.WriteLn('\t@$(call do_postbuilds)')
postbuilds = [] # Don't write postbuilds for target's output. postbuilds = [] # Don't write postbuilds for target's output.
# Needed by test/mac/gyptest-rebuild.py. # Needed by test/mac/gyptest-rebuild.py.
@ -1945,11 +2086,6 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
'on the bundle, not the binary (target \'%s\')' % self.target) 'on the bundle, not the binary (target \'%s\')' % self.target)
assert 'product_dir' not in spec, ('Postbuilds do not work with ' assert 'product_dir' not in spec, ('Postbuilds do not work with '
'custom product_dir') 'custom product_dir')
self.WriteXcodeEnv(self.output_binary, spec) # For postbuilds
postbuilds = [EscapeShellArgument(p) for p in postbuilds]
self.WriteLn('%s: builddir := $(abs_builddir)' % self.output_binary)
self.WriteLn('%s: POSTBUILDS := %s' % (
self.output_binary, ' '.join(postbuilds)))
if self.type == 'executable': if self.type == 'executable':
self.WriteLn( self.WriteLn(
@ -1987,9 +2123,6 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# Write a stamp line. # Write a stamp line.
self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all, self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all,
postbuilds=postbuilds) postbuilds=postbuilds)
elif self.type == 'settings':
# Only used for passing flags around.
pass
else: else:
print "WARNING: no output for", self.type, target print "WARNING: no output for", self.type, target
@ -2259,11 +2392,15 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
'TARGET_BUILD_DIR' : built_products_dir, 'TARGET_BUILD_DIR' : built_products_dir,
'TEMP_DIR' : '$(TMPDIR)', 'TEMP_DIR' : '$(TMPDIR)',
} }
if self.type in ('executable', 'shared_library'): if self.type in ('executable', 'shared_library', 'loadable_module'):
env['EXECUTABLE_NAME'] = os.path.basename(self.output_binary) env['EXECUTABLE_NAME'] = os.path.basename(self.output_binary)
if self.type in ( if self.type in (
'executable', 'static_library', 'shared_library', 'loadable_module'): 'executable', 'static_library', 'shared_library', 'loadable_module'):
env['EXECUTABLE_PATH'] = self.xcode_settings.GetExecutablePath() env['EXECUTABLE_PATH'] = self.xcode_settings.GetExecutablePath()
mach_o_type = self.xcode_settings.GetMachOType()
if mach_o_type:
env['MACH_O_TYPE'] = mach_o_type
env['PRODUCT_TYPE'] = self.xcode_settings.GetProductType()
if self.is_mac_bundle: if self.is_mac_bundle:
env['CONTENTS_FOLDER_PATH'] = \ env['CONTENTS_FOLDER_PATH'] = \
self.xcode_settings.GetBundleContentsFolderPath() self.xcode_settings.GetBundleContentsFolderPath()
@ -2347,14 +2484,13 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
return arg return arg
def ExpandInputRoot(self, template, expansion): def ExpandInputRoot(self, template, expansion, dirname):
if '%(INPUT_ROOT)s' not in template: if '%(INPUT_ROOT)s' not in template and '%(INPUT_DIRNAME)s' not in template:
return template return template
path = template % { 'INPUT_ROOT': expansion } path = template % {
if not os.path.dirname(path): 'INPUT_ROOT': expansion,
# If it's just the file name, turn it into a path so FixupArgPath() 'INPUT_DIRNAME': dirname,
# will know to Absolutify() it. }
path = os.path.join('.', path)
return path return path
@ -2440,31 +2576,17 @@ def RunSystemTests(flavor):
'LINK_flags': link_flags } 'LINK_flags': link_flags }
def CopyTool(flavor, out_path): def CopyMacTool(out_path):
"""Finds (mac|sun)_tool.gyp in the gyp directory and copies it to |out_path|.""" """Finds mac_tool.gyp in the gyp directory and copies it to |out_path|."""
prefix = { 'solaris': 'sun', 'mac': 'mac' }.get(flavor, None)
if not prefix:
return
tool_path = os.path.join(out_path, 'gyp-%s-tool' % prefix)
if os.path.exists(tool_path):
os.remove(tool_path)
# Slurp input file.
source_path = os.path.join( source_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)), '..', '%s_tool.py' % prefix) os.path.dirname(os.path.abspath(__file__)), '..', 'mac_tool.py')
source_file = open(source_path) source_file = open(source_path)
source = source_file.readlines() source = source_file.readlines()
source_file.close() source_file.close()
mactool_file = open(out_path, 'w')
# Add header and write it out. mactool_file.write(
tool_file = open(tool_path, 'w')
tool_file.write(
''.join([source[0], '# Generated by gyp. Do not edit.\n'] + source[1:])) ''.join([source[0], '# Generated by gyp. Do not edit.\n'] + source[1:]))
tool_file.close() mactool_file.close()
# Make file executable.
os.chmod(tool_path, 0o755)
def GenerateOutput(target_list, target_dicts, data, params): def GenerateOutput(target_list, target_dicts, data, params):
@ -2512,33 +2634,24 @@ def GenerateOutput(target_list, target_dicts, data, params):
srcdir = gyp.common.RelativePath(srcdir, options.generator_output) srcdir = gyp.common.RelativePath(srcdir, options.generator_output)
srcdir_prefix = '$(srcdir)/' srcdir_prefix = '$(srcdir)/'
flock_command= 'flock'
header_params = { header_params = {
'builddir': builddir_name, 'builddir': builddir_name,
'default_configuration': default_configuration, 'default_configuration': default_configuration,
'flock': 'flock', 'flock': flock_command,
'flock_index': 1, 'flock_index': 1,
'link_commands': LINK_COMMANDS_LINUX, 'link_commands': LINK_COMMANDS_LINUX,
'extra_commands': '', 'mac_commands': '',
'srcdir': srcdir, 'srcdir': srcdir,
} }
if flavor == 'mac': if flavor == 'mac':
flock_command = './gyp-mac-tool flock'
header_params.update({ header_params.update({
'flock': './gyp-mac-tool flock', 'flock': flock_command,
'flock_index': 2, 'flock_index': 2,
'link_commands': LINK_COMMANDS_MAC, 'link_commands': LINK_COMMANDS_MAC,
'extra_commands': SHARED_HEADER_MAC_COMMANDS, 'mac_commands': SHARED_HEADER_MAC_COMMANDS,
})
elif flavor == 'solaris':
header_params.update({
'flock': './gyp-sun-tool flock',
'flock_index': 2,
'extra_commands': SHARED_HEADER_SUN_COMMANDS,
}) })
elif flavor == 'freebsd':
header_params.update({
'flock': 'lockf',
})
if flavor == 'android': if flavor == 'android':
header_params.update({ header_params.update({
'link_commands': LINK_COMMANDS_ANDROID, 'link_commands': LINK_COMMANDS_ANDROID,
@ -2552,7 +2665,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
if value[0] != '$': if value[0] != '$':
value = '$(abspath %s)' % value value = '$(abspath %s)' % value
if key == 'LINK': if key == 'LINK':
make_global_settings += '%s ?= $(FLOCK) %s\n' % (key, value) make_global_settings += '%s ?= %s %s\n' % (flock_command, key, value)
elif key in ['CC', 'CXX']: elif key in ['CC', 'CXX']:
make_global_settings += ( make_global_settings += (
'ifneq (,$(filter $(origin %s), undefined default))\n' % key) 'ifneq (,$(filter $(origin %s), undefined default))\n' % key)
@ -2579,9 +2692,14 @@ def GenerateOutput(target_list, target_dicts, data, params):
root_makefile.write('TOOLSET := %s\n' % toolset) root_makefile.write('TOOLSET := %s\n' % toolset)
WriteRootHeaderSuffixRules(root_makefile) WriteRootHeaderSuffixRules(root_makefile)
# Put platform tool next to the root Makefile. # Put mac_tool next to the root Makefile.
dest_path = os.path.dirname(makefile_path) if flavor == 'mac':
CopyTool(flavor, dest_path) mactool_path = os.path.join(os.path.dirname(makefile_path), 'gyp-mac-tool')
if os.path.exists(mactool_path):
os.remove(mactool_path)
CopyMacTool(mactool_path)
# Make file executable.
os.chmod(mactool_path, 0755)
# Find the list of targets that derive from the gyp file(s) being built. # Find the list of targets that derive from the gyp file(s) being built.
needed_targets = set() needed_targets = set()

96
tools/gyp/pylib/gyp/generator/msvs.py

@ -58,6 +58,7 @@ generator_default_variables = {
# TODO(jeanluc) I had: 'LIB_DIR': '$(OutDir)lib', # TODO(jeanluc) I had: 'LIB_DIR': '$(OutDir)lib',
'LIB_DIR': '$(OutDir)/lib', 'LIB_DIR': '$(OutDir)/lib',
'RULE_INPUT_ROOT': '$(InputName)', 'RULE_INPUT_ROOT': '$(InputName)',
'RULE_INPUT_DIRNAME': '$(InputDir)',
'RULE_INPUT_EXT': '$(InputExt)', 'RULE_INPUT_EXT': '$(InputExt)',
'RULE_INPUT_NAME': '$(InputFileName)', 'RULE_INPUT_NAME': '$(InputFileName)',
'RULE_INPUT_PATH': '$(InputPath)', 'RULE_INPUT_PATH': '$(InputPath)',
@ -254,6 +255,16 @@ def _ConfigFullName(config_name, config_data):
def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path, def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path,
quote_cmd): quote_cmd):
if [x for x in cmd if '$(InputDir)' in x]:
input_dir_preamble = (
'set INPUTDIR=$(InputDir)\n'
'set INPUTDIR=%INPUTDIR:$(ProjectDir)=%\n'
'set INPUTDIR=%INPUTDIR:~0,-1%\n'
)
else:
input_dir_preamble = ''
if cygwin_shell: if cygwin_shell:
# Find path to cygwin. # Find path to cygwin.
cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0]) cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0])
@ -263,6 +274,8 @@ def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path,
'`cygpath -m "${INTDIR}"`') for i in direct_cmd] '`cygpath -m "${INTDIR}"`') for i in direct_cmd]
direct_cmd = [i.replace('$(OutDir)', direct_cmd = [i.replace('$(OutDir)',
'`cygpath -m "${OUTDIR}"`') for i in direct_cmd] '`cygpath -m "${OUTDIR}"`') for i in direct_cmd]
direct_cmd = [i.replace('$(InputDir)',
'`cygpath -m "${INPUTDIR}"`') for i in direct_cmd]
if has_input_path: if has_input_path:
direct_cmd = [i.replace('$(InputPath)', direct_cmd = [i.replace('$(InputPath)',
'`cygpath -m "${INPUTPATH}"`') '`cygpath -m "${INPUTPATH}"`')
@ -286,7 +299,7 @@ def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path,
cmd += 'bash -c "%(cmd)s"' cmd += 'bash -c "%(cmd)s"'
cmd = cmd % {'cygwin_dir': cygwin_dir, cmd = cmd % {'cygwin_dir': cygwin_dir,
'cmd': direct_cmd} 'cmd': direct_cmd}
return cmd return input_dir_preamble + cmd
else: else:
# Convert cat --> type to mimic unix. # Convert cat --> type to mimic unix.
if cmd[0] == 'cat': if cmd[0] == 'cat':
@ -296,13 +309,14 @@ def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path,
# Fix the paths # Fix the paths
# If the argument starts with a slash, it's probably a command line switch # If the argument starts with a slash, it's probably a command line switch
arguments = [i.startswith('/') and i or _FixPath(i) for i in cmd[1:]] arguments = [i.startswith('/') and i or _FixPath(i) for i in cmd[1:]]
arguments = [i.replace('$(InputDir)','%INPUTDIR%') for i in arguments]
if quote_cmd: if quote_cmd:
# Support a mode for using cmd directly. # Support a mode for using cmd directly.
# Convert any paths to native form (first element is used directly). # Convert any paths to native form (first element is used directly).
# TODO(quote): regularize quoting path names throughout the module # TODO(quote): regularize quoting path names throughout the module
arguments = ['"%s"' % i for i in arguments] arguments = ['"%s"' % i for i in arguments]
# Collapse into a single command. # Collapse into a single command.
return ' '.join(command + arguments) return input_dir_preamble + ' '.join(command + arguments)
def _BuildCommandLineForRule(spec, rule, has_input_path): def _BuildCommandLineForRule(spec, rule, has_input_path):
@ -427,6 +441,7 @@ def _RuleExpandPath(path, input_file):
""" """
path = path.replace('$(InputName)', path = path.replace('$(InputName)',
os.path.splitext(os.path.split(input_file)[1])[0]) os.path.splitext(os.path.split(input_file)[1])[0])
path = path.replace('$(InputDir)', os.path.dirname(input_file))
path = path.replace('$(InputExt)', path = path.replace('$(InputExt)',
os.path.splitext(os.path.split(input_file)[1])[1]) os.path.splitext(os.path.split(input_file)[1])[1])
path = path.replace('$(InputFileName)', os.path.split(input_file)[1]) path = path.replace('$(InputFileName)', os.path.split(input_file)[1])
@ -547,7 +562,8 @@ def _GenerateExternalRules(rules, output_dir, spec,
# Write out all: target, including mkdir for each output directory. # Write out all: target, including mkdir for each output directory.
mk_file.write('all: %s\n' % ' '.join(first_outputs_cyg)) mk_file.write('all: %s\n' % ' '.join(first_outputs_cyg))
for od in all_output_dirs: for od in all_output_dirs:
mk_file.write('\tmkdir -p `cygpath -u "%s"`\n' % od) if od:
mk_file.write('\tmkdir -p `cygpath -u "%s"`\n' % od)
mk_file.write('\n') mk_file.write('\n')
# Define how each output is generated. # Define how each output is generated.
for rule in rules: for rule in rules:
@ -855,30 +871,29 @@ def _GenerateMSVSProject(project, options, version):
project.guid, platforms) project.guid, platforms)
# Get directory project file is in. # Get directory project file is in.
gyp_dir = os.path.split(project.path)[0] project_dir = os.path.split(project.path)[0]
gyp_file = posixpath.split(project.build_file)[1] gyp_path = _NormalizedSource(project.build_file)
gyp_path = _NormalizedSource(gyp_file) relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, project_dir)
relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, gyp_dir)
config_type = _GetMSVSConfigurationType(spec, project.build_file) config_type = _GetMSVSConfigurationType(spec, project.build_file)
for config_name, config in spec['configurations'].iteritems(): for config_name, config in spec['configurations'].iteritems():
_AddConfigurationToMSVSProject(p, spec, config_type, config_name, config) _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config)
# Prepare list of sources and excluded sources. # Prepare list of sources and excluded sources.
sources, excluded_sources = _PrepareListOfSources(spec, gyp_file = os.path.split(project.build_file)[1]
relative_path_of_gyp_file) sources, excluded_sources = _PrepareListOfSources(spec, gyp_file)
# Add rules. # Add rules.
actions_to_add = {} actions_to_add = {}
_GenerateRulesForMSVS(p, gyp_dir, options, spec, _GenerateRulesForMSVS(p, project_dir, options, spec,
sources, excluded_sources, sources, excluded_sources,
actions_to_add) actions_to_add)
sources, excluded_sources, excluded_idl = ( sources, excluded_sources, excluded_idl = (
_AdjustSourcesAndConvertToFilterHierarchy( _AdjustSourcesAndConvertToFilterHierarchy(
spec, options, gyp_dir, sources, excluded_sources)) spec, options, project_dir, sources, excluded_sources))
# Add in files. # Add in files.
_VerifySourcesExist(sources, gyp_dir) _VerifySourcesExist(sources, project_dir)
p.AddFiles(sources) p.AddFiles(sources)
_AddToolFilesToMSVS(p, spec) _AddToolFilesToMSVS(p, spec)
@ -1013,7 +1028,7 @@ def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config):
defines) defines)
# Change program database directory to prevent collisions. # Change program database directory to prevent collisions.
_ToolAppend(tools, 'VCCLCompilerTool', 'ProgramDataBaseFileName', _ToolAppend(tools, 'VCCLCompilerTool', 'ProgramDataBaseFileName',
'$(IntDir)\\$(ProjectName)\\vc80.pdb') '$(IntDir)\\$(ProjectName)\\vc80.pdb', only_if_unset=True)
# Add disabled warnings. # Add disabled warnings.
_ToolAppend(tools, 'VCCLCompilerTool', _ToolAppend(tools, 'VCCLCompilerTool',
'DisableSpecificWarnings', disabled_warnings) 'DisableSpecificWarnings', disabled_warnings)
@ -1236,7 +1251,7 @@ def _AddNormalizedSources(sources_set, sources_array):
sources_set.update(set(sources)) sources_set.update(set(sources))
def _PrepareListOfSources(spec, relative_path_of_gyp_file): def _PrepareListOfSources(spec, gyp_file):
"""Prepare list of sources and excluded sources. """Prepare list of sources and excluded sources.
Besides the sources specified directly in the spec, adds the gyp file so Besides the sources specified directly in the spec, adds the gyp file so
@ -1246,15 +1261,16 @@ def _PrepareListOfSources(spec, relative_path_of_gyp_file):
Arguments: Arguments:
spec: The target dictionary containing the properties of the target. spec: The target dictionary containing the properties of the target.
relative_path_of_gyp_file: The relative path of the gyp file. gyp_file: The name of the gyp file.
Returns: Returns:
A pair of (list of sources, list of excluded sources) A pair of (list of sources, list of excluded sources).
The sources will be relative to the gyp file.
""" """
sources = set() sources = set()
_AddNormalizedSources(sources, spec.get('sources', [])) _AddNormalizedSources(sources, spec.get('sources', []))
excluded_sources = set() excluded_sources = set()
# Add in the gyp file. # Add in the gyp file.
sources.add(relative_path_of_gyp_file) sources.add(gyp_file)
# Add in 'action' inputs and outputs. # Add in 'action' inputs and outputs.
for a in spec.get('actions', []): for a in spec.get('actions', []):
@ -1489,7 +1505,9 @@ def _GetCopies(spec):
def _GetPathDict(root, path): def _GetPathDict(root, path):
if not path: # |path| will eventually be empty (in the recursive calls) if it was initially
# relative; otherwise it will eventually end up as '\', 'D:\', etc.
if not path or path.endswith(os.sep):
return root return root
parent, folder = os.path.split(path) parent, folder = os.path.split(path)
parent_dict = _GetPathDict(root, parent) parent_dict = _GetPathDict(root, parent)
@ -2642,7 +2660,8 @@ def _VerifySourcesExist(sources, root_dir):
if '$' not in source: if '$' not in source:
full_path = os.path.join(root_dir, source) full_path = os.path.join(root_dir, source)
if not os.path.exists(full_path): if not os.path.exists(full_path):
print 'Error: Missing input file ' + full_path print 'Warning: Missing input file ' + full_path + ' pwd=' +\
os.getcwd()
def _GetMSBuildSources(spec, sources, exclusions, extension_to_rule_name, def _GetMSBuildSources(spec, sources, exclusions, extension_to_rule_name,
@ -2685,15 +2704,16 @@ def _AddSources2(spec, sources, exclusions, grouped_sources,
# Add precompile if needed # Add precompile if needed
for config_name, configuration in spec['configurations'].iteritems(): for config_name, configuration in spec['configurations'].iteritems():
precompiled_source = configuration.get('msvs_precompiled_source', '') precompiled_source = configuration.get('msvs_precompiled_source', '')
precompiled_source = _FixPath(precompiled_source) if precompiled_source != '':
if not extensions_excluded_from_precompile: precompiled_source = _FixPath(precompiled_source)
# If the precompiled header is generated by a C source, we must if not extensions_excluded_from_precompile:
# not try to use it for C++ sources, and vice versa. # If the precompiled header is generated by a C source, we must
basename, extension = os.path.splitext(precompiled_source) # not try to use it for C++ sources, and vice versa.
if extension == '.c': basename, extension = os.path.splitext(precompiled_source)
extensions_excluded_from_precompile = ['.cc', '.cpp', '.cxx'] if extension == '.c':
else: extensions_excluded_from_precompile = ['.cc', '.cpp', '.cxx']
extensions_excluded_from_precompile = ['.c'] else:
extensions_excluded_from_precompile = ['.c']
if precompiled_source == source: if precompiled_source == source:
condition = _GetConfigurationCondition(config_name, configuration) condition = _GetConfigurationCondition(config_name, configuration)
@ -2736,30 +2756,28 @@ def _GetMSBuildProjectReferences(project):
def _GenerateMSBuildProject(project, options, version): def _GenerateMSBuildProject(project, options, version):
spec = project.spec spec = project.spec
configurations = spec['configurations'] configurations = spec['configurations']
gyp_dir, gyp_file_name = os.path.split(project.path) project_dir, project_file_name = os.path.split(project.path)
msbuildproj_dir = os.path.dirname(project.path) msbuildproj_dir = os.path.dirname(project.path)
if msbuildproj_dir and not os.path.exists(msbuildproj_dir): if msbuildproj_dir and not os.path.exists(msbuildproj_dir):
os.makedirs(msbuildproj_dir) os.makedirs(msbuildproj_dir)
# Prepare list of sources and excluded sources. # Prepare list of sources and excluded sources.
gyp_dir = os.path.split(project.path)[0] gyp_path = _NormalizedSource(project.build_file)
gyp_file = posixpath.split(project.build_file)[1] relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, project_dir)
gyp_path = _NormalizedSource(gyp_file)
relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, gyp_dir)
sources, excluded_sources = _PrepareListOfSources(spec, gyp_file = os.path.split(project.build_file)[1]
relative_path_of_gyp_file) sources, excluded_sources = _PrepareListOfSources(spec, gyp_file)
# Add rules. # Add rules.
actions_to_add = {} actions_to_add = {}
props_files_of_rules = set() props_files_of_rules = set()
targets_files_of_rules = set() targets_files_of_rules = set()
extension_to_rule_name = {} extension_to_rule_name = {}
_GenerateRulesForMSBuild(gyp_dir, options, spec, _GenerateRulesForMSBuild(project_dir, options, spec,
sources, excluded_sources, sources, excluded_sources,
props_files_of_rules, targets_files_of_rules, props_files_of_rules, targets_files_of_rules,
actions_to_add, extension_to_rule_name) actions_to_add, extension_to_rule_name)
sources, excluded_sources, excluded_idl = ( sources, excluded_sources, excluded_idl = (
_AdjustSourcesAndConvertToFilterHierarchy(spec, options, _AdjustSourcesAndConvertToFilterHierarchy(spec, options,
gyp_dir, sources, project_dir, sources,
excluded_sources)) excluded_sources))
_AddActions(actions_to_add, spec, project.build_file) _AddActions(actions_to_add, spec, project.build_file)
_AddCopies(actions_to_add, spec) _AddCopies(actions_to_add, spec)
@ -2775,7 +2793,7 @@ def _GenerateMSBuildProject(project, options, version):
_GenerateMSBuildFiltersFile(project.path + '.filters', sources, _GenerateMSBuildFiltersFile(project.path + '.filters', sources,
extension_to_rule_name) extension_to_rule_name)
_VerifySourcesExist(sources, gyp_dir) _VerifySourcesExist(sources, project_dir)
for (_, configuration) in configurations.iteritems(): for (_, configuration) in configurations.iteritems():
_FinalizeMSBuildSettings(spec, configuration) _FinalizeMSBuildSettings(spec, configuration)
@ -2798,7 +2816,7 @@ def _GenerateMSBuildProject(project, options, version):
}] }]
content += _GetMSBuildProjectConfigurations(configurations) content += _GetMSBuildProjectConfigurations(configurations)
content += _GetMSBuildGlobalProperties(spec, project.guid, gyp_file_name) content += _GetMSBuildGlobalProperties(spec, project.guid, project_file_name)
content += import_default_section content += import_default_section
content += _GetMSBuildConfigurationDetails(spec, project.build_file) content += _GetMSBuildConfigurationDetails(spec, project.build_file)
content += import_cpp_props_section content += import_cpp_props_section

33
tools/gyp/pylib/gyp/generator/ninja.py

@ -42,6 +42,7 @@ generator_default_variables = {
# We generate definitions for these variables on the fly when processing a # We generate definitions for these variables on the fly when processing a
# rule. # rule.
'RULE_INPUT_ROOT': '${root}', 'RULE_INPUT_ROOT': '${root}',
'RULE_INPUT_DIRNAME': '${dirname}',
'RULE_INPUT_PATH': '${source}', 'RULE_INPUT_PATH': '${source}',
'RULE_INPUT_EXT': '${ext}', 'RULE_INPUT_EXT': '${ext}',
'RULE_INPUT_NAME': '${name}', 'RULE_INPUT_NAME': '${name}',
@ -212,13 +213,17 @@ class NinjaWriter:
Returns the path to the build output, or None.""" Returns the path to the build output, or None."""
self.name = spec['target_name']
self.toolset = spec['toolset']
if spec['type'] == 'settings': if spec['type'] == 'settings':
# TODO: 'settings' is not actually part of gyp; it was # TODO: 'settings' is not actually part of gyp; it was
# accidentally introduced somehow into just the Linux build files. # accidentally introduced somehow into just the Linux build files.
return None # Remove this (or make it an error) once all the users are fixed.
print ("WARNING: %s uses invalid type 'settings'. " % self.name +
self.name = spec['target_name'] "Please fix the source gyp file to use type 'none'.")
self.toolset = spec['toolset'] print "See http://code.google.com/p/chromium/issues/detail?id=96629 ."
spec['type'] = 'none'
# Compute predepends for all rules. # Compute predepends for all rules.
# prebuild is the dependencies this target depends on before # prebuild is the dependencies this target depends on before
@ -331,7 +336,7 @@ class NinjaWriter:
# Rules can potentially make use of some special variables which # Rules can potentially make use of some special variables which
# must vary per source file. # must vary per source file.
# Compute the list of variables we'll need to provide. # Compute the list of variables we'll need to provide.
special_locals = ('source', 'root', 'ext', 'name') special_locals = ('source', 'root', 'dirname', 'ext', 'name')
needed_variables = set(['source']) needed_variables = set(['source'])
for argument in args: for argument in args:
for var in special_locals: for var in special_locals:
@ -340,14 +345,15 @@ class NinjaWriter:
# For each source file, write an edge that generates all the outputs. # For each source file, write an edge that generates all the outputs.
for source in rule.get('rule_sources', []): for source in rule.get('rule_sources', []):
basename = os.path.basename(source) dirname, basename = os.path.split(source)
root, ext = os.path.splitext(basename) root, ext = os.path.splitext(basename)
# Gather the list of outputs, expanding $vars if possible. # Gather the list of outputs, expanding $vars if possible.
outputs = [] outputs = []
for output in rule['outputs']: for output in rule['outputs']:
outputs.append(output.replace( outputs.append(output.replace(
generator_default_variables['RULE_INPUT_ROOT'], root)) generator_default_variables['RULE_INPUT_ROOT'], root).replace(
generator_default_variables['RULE_INPUT_DIRNAME'], dirname))
if int(rule.get('process_outputs_as_sources', False)): if int(rule.get('process_outputs_as_sources', False)):
extra_sources += outputs extra_sources += outputs
@ -356,6 +362,8 @@ class NinjaWriter:
for var in needed_variables: for var in needed_variables:
if var == 'root': if var == 'root':
extra_bindings.append(('root', root)) extra_bindings.append(('root', root))
elif var == 'dirname':
extra_bindings.append(('dirname', dirname))
elif var == 'source': elif var == 'source':
# '$source' is a parameter to the rule action, which means # '$source' is a parameter to the rule action, which means
# it shouldn't be converted to a Ninja path. But we don't # it shouldn't be converted to a Ninja path. But we don't
@ -466,7 +474,7 @@ class NinjaWriter:
command_map = { command_map = {
'executable': 'link', 'executable': 'link',
'static_library': 'alink', 'static_library': 'alink',
'loadable_module': 'solink', 'loadable_module': 'solink_module',
'shared_library': 'solink', 'shared_library': 'solink',
'none': 'stamp', 'none': 'stamp',
} }
@ -481,7 +489,7 @@ class NinjaWriter:
spec.get('libraries', [])))) spec.get('libraries', []))))
extra_bindings = [] extra_bindings = []
if command == 'solink': if command in ('solink', 'solink_module'):
extra_bindings.append(('soname', os.path.split(output)[1])) extra_bindings.append(('soname', os.path.split(output)[1]))
self.ninja.build(output, command, final_deps, self.ninja.build(output, command, final_deps,
@ -528,8 +536,6 @@ class NinjaWriter:
return '%s%s%s' % (prefix, target, extension) return '%s%s%s' % (prefix, target, extension)
elif spec['type'] == 'none': elif spec['type'] == 'none':
return '%s.stamp' % target return '%s.stamp' % target
elif spec['type'] == 'settings':
return None
else: else:
raise 'Unhandled output type', spec['type'] raise 'Unhandled output type', spec['type']
@ -655,6 +661,11 @@ def GenerateOutput(target_list, target_dicts, data, params):
description='SOLINK $out', description='SOLINK $out',
command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname '
'-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs'))
master_ninja.rule(
'solink_module',
description='SOLINK(module) $out',
command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname '
'-Wl,--start-group $in -Wl,--end-group $libs'))
master_ninja.rule( master_ninja.rule(
'link', 'link',
description='LINK $out', description='LINK $out',

3
tools/gyp/pylib/gyp/generator/scons.py

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# Copyright (c) 2009 Google Inc. All rights reserved. # Copyright (c) 2011 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -30,6 +30,7 @@ generator_default_variables = {
'SHARED_LIB_DIR': '$LIB_DIR', 'SHARED_LIB_DIR': '$LIB_DIR',
'LIB_DIR': '$LIB_DIR', 'LIB_DIR': '$LIB_DIR',
'RULE_INPUT_ROOT': '${SOURCE.filebase}', 'RULE_INPUT_ROOT': '${SOURCE.filebase}',
'RULE_INPUT_DIRNAME': '${SOURCE.dir}',
'RULE_INPUT_EXT': '${SOURCE.suffix}', 'RULE_INPUT_EXT': '${SOURCE.suffix}',
'RULE_INPUT_NAME': '${SOURCE.file}', 'RULE_INPUT_NAME': '${SOURCE.file}',
'RULE_INPUT_PATH': '${SOURCE.abspath}', 'RULE_INPUT_PATH': '${SOURCE.abspath}',

5
tools/gyp/pylib/gyp/generator/xcode.py

@ -53,6 +53,7 @@ generator_default_variables = {
'RULE_INPUT_EXT': '$(INPUT_FILE_SUFFIX)', 'RULE_INPUT_EXT': '$(INPUT_FILE_SUFFIX)',
'RULE_INPUT_NAME': '$(INPUT_FILE_NAME)', 'RULE_INPUT_NAME': '$(INPUT_FILE_NAME)',
'RULE_INPUT_PATH': '$(INPUT_FILE_PATH)', 'RULE_INPUT_PATH': '$(INPUT_FILE_PATH)',
'RULE_INPUT_DIRNAME': '$(INPUT_FILE_DIRNAME)',
'SHARED_INTERMEDIATE_DIR': '$(%s)' % _shared_intermediate_var, 'SHARED_INTERMEDIATE_DIR': '$(%s)' % _shared_intermediate_var,
'CONFIGURATION_NAME': '$(CONFIGURATION)', 'CONFIGURATION_NAME': '$(CONFIGURATION)',
} }
@ -865,7 +866,8 @@ def GenerateOutput(target_list, target_dicts, data, params):
actions = [] actions = []
for rule_source in rule.get('rule_sources', []): for rule_source in rule.get('rule_sources', []):
rule_source_basename = posixpath.basename(rule_source) rule_source_dirname, rule_source_basename = \
posixpath.split(rule_source)
(rule_source_root, rule_source_ext) = \ (rule_source_root, rule_source_ext) = \
posixpath.splitext(rule_source_basename) posixpath.splitext(rule_source_basename)
@ -877,6 +879,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
'INPUT_FILE_SUFFIX': rule_source_ext, 'INPUT_FILE_SUFFIX': rule_source_ext,
'INPUT_FILE_NAME': rule_source_basename, 'INPUT_FILE_NAME': rule_source_basename,
'INPUT_FILE_PATH': rule_source, 'INPUT_FILE_PATH': rule_source,
'INPUT_FILE_DIRNAME': rule_source_dirname,
} }
concrete_outputs_for_this_rule_source = [] concrete_outputs_for_this_rule_source = []

10
tools/gyp/pylib/gyp/mac_tool.py

@ -73,12 +73,14 @@ class MacTool(object):
if not plist: if not plist:
return return
# Only create PkgInfo for executable types.
package_type = plist['CFBundlePackageType']
if package_type != 'APPL':
return
# The format of PkgInfo is eight characters, representing the bundle type # The format of PkgInfo is eight characters, representing the bundle type
# and bundle signature, each four characters. If either is missing, four # and bundle signature, each four characters. If that is missing, four
# '?' characters are used instead. # '?' characters are used instead.
package_type = plist['CFBundlePackageType']
if len(package_type) != 4:
package_type = '?' * 4
signature_code = plist['CFBundleSignature'] signature_code = plist['CFBundleSignature']
if len(signature_code) != 4: if len(signature_code) != 4:
signature_code = '?' * 4 signature_code = '?' * 4

Loading…
Cancel
Save