mirror of https://github.com/lukechilds/node.git
Ben Noordhuis
13 years ago
611 changed files with 2983 additions and 22714 deletions
@ -0,0 +1,44 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
|
||||
|
# Copyright (c) 2012 Google Inc. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""Unit tests for the common.py file.""" |
||||
|
|
||||
|
import gyp.common |
||||
|
import unittest |
||||
|
|
||||
|
|
||||
|
class TestTopologicallySorted(unittest.TestCase): |
||||
|
def test_Valid(self): |
||||
|
"""Test that sorting works on a valid graph with one possible order.""" |
||||
|
graph = { |
||||
|
'a': ['b', 'c'], |
||||
|
'b': [], |
||||
|
'c': ['d'], |
||||
|
'd': ['b'], |
||||
|
} |
||||
|
def GetEdge(node): |
||||
|
return tuple(graph[node]) |
||||
|
self.assertEqual( |
||||
|
gyp.common.TopologicallySorted(graph.keys(), GetEdge), |
||||
|
['a', 'c', 'd', 'b']) |
||||
|
|
||||
|
def test_Cycle(self): |
||||
|
"""Test that an exception is thrown on a cyclic graph.""" |
||||
|
graph = { |
||||
|
'a': ['b'], |
||||
|
'b': ['c'], |
||||
|
'c': ['d'], |
||||
|
'd': ['a'], |
||||
|
} |
||||
|
def GetEdge(node): |
||||
|
return tuple(graph[node]) |
||||
|
self.assertRaises( |
||||
|
gyp.common.CycleError, gyp.common.TopologicallySorted, |
||||
|
graph.keys(), GetEdge) |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
unittest.main() |
@ -0,0 +1,271 @@ |
|||||
|
# Copyright (c) 2012 Google Inc. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""GYP backend that generates Eclipse CDT settings files. |
||||
|
|
||||
|
This backend DOES NOT generate Eclipse CDT projects. Instead, it generates XML |
||||
|
files that can be imported into an Eclipse CDT project. The XML file contains a |
||||
|
list of include paths and symbols (i.e. defines). |
||||
|
|
||||
|
Because a full .cproject definition is not created by this generator, it's not |
||||
|
possible to properly define the include dirs and symbols for each file |
||||
|
individually. Instead, one set of includes/symbols is generated for the entire |
||||
|
project. This works fairly well (and is a vast improvement in general), but may |
||||
|
still result in a few indexer issues here and there. |
||||
|
|
||||
|
This generator has no automated tests, so expect it to be broken. |
||||
|
""" |
||||
|
|
||||
|
import os.path |
||||
|
import subprocess |
||||
|
import gyp |
||||
|
import gyp.common |
||||
|
import shlex |
||||
|
|
||||
|
generator_wants_static_library_dependencies_adjusted = False |
||||
|
|
||||
|
generator_default_variables = { |
||||
|
} |
||||
|
|
||||
|
for dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']: |
||||
|
# Some gyp steps fail if these are empty(!). |
||||
|
generator_default_variables[dirname] = 'dir' |
||||
|
|
||||
|
for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME', |
||||
|
'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT', |
||||
|
'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX', |
||||
|
'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX', |
||||
|
'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX']: |
||||
|
generator_default_variables[unused] = '' |
||||
|
|
||||
|
# Include dirs will occasionaly use the SHARED_INTERMEDIATE_DIR variable as |
||||
|
# part of the path when dealing with generated headers. This value will be |
||||
|
# replaced dynamically for each configuration. |
||||
|
generator_default_variables['SHARED_INTERMEDIATE_DIR'] = \ |
||||
|
'$SHARED_INTERMEDIATES_DIR' |
||||
|
|
||||
|
|
||||
|
def CalculateVariables(default_variables, params): |
||||
|
generator_flags = params.get('generator_flags', {}) |
||||
|
for key, val in generator_flags.items(): |
||||
|
default_variables.setdefault(key, val) |
||||
|
default_variables.setdefault('OS', gyp.common.GetFlavor(params)) |
||||
|
|
||||
|
|
||||
|
def CalculateGeneratorInputInfo(params): |
||||
|
"""Calculate the generator specific info that gets fed to input (called by |
||||
|
gyp).""" |
||||
|
generator_flags = params.get('generator_flags', {}) |
||||
|
if generator_flags.get('adjust_static_libraries', False): |
||||
|
global generator_wants_static_library_dependencies_adjusted |
||||
|
generator_wants_static_library_dependencies_adjusted = True |
||||
|
|
||||
|
|
||||
|
def GetAllIncludeDirectories(target_list, target_dicts, |
||||
|
shared_intermediates_dir, config_name): |
||||
|
"""Calculate the set of include directories to be used. |
||||
|
|
||||
|
Returns: |
||||
|
A list including all the include_dir's specified for every target followed |
||||
|
by any include directories that were added as cflag compiler options. |
||||
|
""" |
||||
|
|
||||
|
gyp_includes_set = set() |
||||
|
compiler_includes_list = [] |
||||
|
|
||||
|
for target_name in target_list: |
||||
|
target = target_dicts[target_name] |
||||
|
if config_name in target['configurations']: |
||||
|
config = target['configurations'][config_name] |
||||
|
|
||||
|
# Look for any include dirs that were explicitly added via cflags. This |
||||
|
# may be done in gyp files to force certain includes to come at the end. |
||||
|
# TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and |
||||
|
# remove this. |
||||
|
cflags = config['cflags'] |
||||
|
for cflag in cflags: |
||||
|
include_dir = '' |
||||
|
if cflag.startswith('-I'): |
||||
|
include_dir = cflag[2:] |
||||
|
if include_dir and not include_dir in compiler_includes_list: |
||||
|
compiler_includes_list.append(include_dir) |
||||
|
|
||||
|
# Find standard gyp include dirs. |
||||
|
if config.has_key('include_dirs'): |
||||
|
include_dirs = config['include_dirs'] |
||||
|
for include_dir in include_dirs: |
||||
|
include_dir = include_dir.replace('$SHARED_INTERMEDIATES_DIR', |
||||
|
shared_intermediates_dir) |
||||
|
if not os.path.isabs(include_dir): |
||||
|
base_dir = os.path.dirname(target_name) |
||||
|
|
||||
|
include_dir = base_dir + '/' + include_dir |
||||
|
include_dir = os.path.abspath(include_dir) |
||||
|
|
||||
|
if not include_dir in gyp_includes_set: |
||||
|
gyp_includes_set.add(include_dir) |
||||
|
|
||||
|
|
||||
|
# Generate a list that has all the include dirs. |
||||
|
all_includes_list = list(gyp_includes_set) |
||||
|
all_includes_list.sort() |
||||
|
for compiler_include in compiler_includes_list: |
||||
|
if not compiler_include in gyp_includes_set: |
||||
|
all_includes_list.append(compiler_include) |
||||
|
|
||||
|
# All done. |
||||
|
return all_includes_list |
||||
|
|
||||
|
|
||||
|
def GetCompilerPath(target_list, target_dicts, data): |
||||
|
"""Determine a command that can be used to invoke the compiler. |
||||
|
|
||||
|
Returns: |
||||
|
If this is a gyp project that has explicit make settings, try to determine |
||||
|
the compiler from that. Otherwise, see if a compiler was specified via the |
||||
|
CC_target environment variable. |
||||
|
""" |
||||
|
|
||||
|
# First, see if the compiler is configured in make's settings. |
||||
|
build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) |
||||
|
make_global_settings_dict = data[build_file].get('make_global_settings', {}) |
||||
|
for key, value in make_global_settings_dict: |
||||
|
if key in ['CC', 'CXX']: |
||||
|
return value |
||||
|
|
||||
|
# Check to see if the compiler was specified as an environment variable. |
||||
|
for key in ['CC_target', 'CC', 'CXX']: |
||||
|
compiler = os.environ.get(key) |
||||
|
if compiler: |
||||
|
return compiler |
||||
|
|
||||
|
return 'gcc' |
||||
|
|
||||
|
|
||||
|
def GetAllDefines(target_list, target_dicts, data, config_name): |
||||
|
"""Calculate the defines for a project. |
||||
|
|
||||
|
Returns: |
||||
|
A dict that includes explict defines declared in gyp files along with all of |
||||
|
the default defines that the compiler uses. |
||||
|
""" |
||||
|
|
||||
|
# Get defines declared in the gyp files. |
||||
|
all_defines = {} |
||||
|
for target_name in target_list: |
||||
|
target = target_dicts[target_name] |
||||
|
|
||||
|
if config_name in target['configurations']: |
||||
|
config = target['configurations'][config_name] |
||||
|
for define in config['defines']: |
||||
|
split_define = define.split('=', 1) |
||||
|
if len(split_define) == 1: |
||||
|
split_define.append('1') |
||||
|
if split_define[0].strip() in all_defines: |
||||
|
# Already defined |
||||
|
continue |
||||
|
|
||||
|
all_defines[split_define[0].strip()] = split_define[1].strip() |
||||
|
|
||||
|
# Get default compiler defines (if possible). |
||||
|
cc_target = GetCompilerPath(target_list, target_dicts, data) |
||||
|
if cc_target: |
||||
|
command = shlex.split(cc_target) |
||||
|
command.extend(['-E', '-dM', '-']) |
||||
|
cpp_proc = subprocess.Popen(args=command, cwd='.', |
||||
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
||||
|
cpp_output = cpp_proc.communicate()[0] |
||||
|
cpp_lines = cpp_output.split('\n') |
||||
|
for cpp_line in cpp_lines: |
||||
|
if not cpp_line.strip(): |
||||
|
continue |
||||
|
cpp_line_parts = cpp_line.split(' ', 2) |
||||
|
key = cpp_line_parts[1] |
||||
|
if len(cpp_line_parts) >= 3: |
||||
|
val = cpp_line_parts[2] |
||||
|
else: |
||||
|
val = '1' |
||||
|
all_defines[key] = val |
||||
|
|
||||
|
return all_defines |
||||
|
|
||||
|
|
||||
|
def WriteIncludePaths(out, eclipse_langs, include_dirs): |
||||
|
"""Write the includes section of a CDT settings export file.""" |
||||
|
|
||||
|
out.write(' <section name="org.eclipse.cdt.internal.ui.wizards.' \ |
||||
|
'settingswizards.IncludePaths">\n') |
||||
|
out.write(' <language name="holder for library settings"></language>\n') |
||||
|
for lang in eclipse_langs: |
||||
|
out.write(' <language name="%s">\n' % lang) |
||||
|
for include_dir in include_dirs: |
||||
|
out.write(' <includepath workspace_path="false">%s</includepath>\n' % |
||||
|
include_dir) |
||||
|
out.write(' </language>\n') |
||||
|
out.write(' </section>\n') |
||||
|
|
||||
|
|
||||
|
def WriteMacros(out, eclipse_langs, defines): |
||||
|
"""Write the macros section of a CDT settings export file.""" |
||||
|
|
||||
|
out.write(' <section name="org.eclipse.cdt.internal.ui.wizards.' \ |
||||
|
'settingswizards.Macros">\n') |
||||
|
out.write(' <language name="holder for library settings"></language>\n') |
||||
|
for lang in eclipse_langs: |
||||
|
out.write(' <language name="%s">\n' % lang) |
||||
|
for key in sorted(defines.iterkeys()): |
||||
|
out.write(' <macro><name>%s</name><value>%s</value></macro>\n' % |
||||
|
(key, defines[key])) |
||||
|
out.write(' </language>\n') |
||||
|
out.write(' </section>\n') |
||||
|
|
||||
|
|
||||
|
def GenerateOutputForConfig(target_list, target_dicts, data, params, |
||||
|
config_name): |
||||
|
options = params['options'] |
||||
|
generator_flags = params.get('generator_flags', {}) |
||||
|
|
||||
|
# build_dir: relative path from source root to our output files. |
||||
|
# e.g. "out/Debug" |
||||
|
build_dir = os.path.join(generator_flags.get('output_dir', 'out'), |
||||
|
config_name) |
||||
|
|
||||
|
toplevel_build = os.path.join(options.toplevel_dir, build_dir) |
||||
|
shared_intermediate_dir = os.path.join(toplevel_build, 'obj', 'gen') |
||||
|
|
||||
|
if not os.path.exists(toplevel_build): |
||||
|
os.makedirs(toplevel_build) |
||||
|
out = open(os.path.join(toplevel_build, 'eclipse-cdt-settings.xml'), 'w') |
||||
|
|
||||
|
out.write('<?xml version="1.0" encoding="UTF-8"?>\n') |
||||
|
out.write('<cdtprojectproperties>\n') |
||||
|
|
||||
|
eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File', |
||||
|
'GNU C++', 'GNU C', 'Assembly'] |
||||
|
include_dirs = GetAllIncludeDirectories(target_list, target_dicts, |
||||
|
shared_intermediate_dir, config_name) |
||||
|
WriteIncludePaths(out, eclipse_langs, include_dirs) |
||||
|
defines = GetAllDefines(target_list, target_dicts, data, config_name) |
||||
|
WriteMacros(out, eclipse_langs, defines) |
||||
|
|
||||
|
out.write('</cdtprojectproperties>\n') |
||||
|
out.close() |
||||
|
|
||||
|
|
||||
|
def GenerateOutput(target_list, target_dicts, data, params): |
||||
|
"""Generate an XML settings file that can be imported into a CDT project.""" |
||||
|
|
||||
|
if params['options'].generator_output: |
||||
|
raise NotImplementedError, "--generator_output not implemented for eclipse" |
||||
|
|
||||
|
user_config = params.get('generator_flags', {}).get('config', None) |
||||
|
if user_config: |
||||
|
GenerateOutputForConfig(target_list, target_dicts, data, params, |
||||
|
user_config) |
||||
|
else: |
||||
|
config_names = target_dicts[target_list[0]]['configurations'].keys() |
||||
|
for config_name in config_names: |
||||
|
GenerateOutputForConfig(target_list, target_dicts, data, params, |
||||
|
config_name) |
||||
|
|
File diff suppressed because it is too large
@ -0,0 +1,642 @@ |
|||||
|
# Copyright (c) 2012 Google Inc. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
""" |
||||
|
This module helps emulate Visual Studio 2008 behavior on top of other |
||||
|
build systems, primarily ninja. |
||||
|
""" |
||||
|
|
||||
|
import os |
||||
|
import re |
||||
|
import subprocess |
||||
|
import sys |
||||
|
|
||||
|
import gyp.MSVSVersion |
||||
|
|
||||
|
windows_quoter_regex = re.compile(r'(\\*)"') |
||||
|
|
||||
|
def QuoteForRspFile(arg): |
||||
|
"""Quote a command line argument so that it appears as one argument when |
||||
|
processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for |
||||
|
Windows programs).""" |
||||
|
# See http://goo.gl/cuFbX and http://goo.gl/dhPnp including the comment |
||||
|
# threads. This is actually the quoting rules for CommandLineToArgvW, not |
||||
|
# for the shell, because the shell doesn't do anything in Windows. This |
||||
|
# works more or less because most programs (including the compiler, etc.) |
||||
|
# use that function to handle command line arguments. |
||||
|
|
||||
|
# For a literal quote, CommandLineToArgvW requires 2n+1 backslashes |
||||
|
# preceding it, and results in n backslashes + the quote. So we substitute |
||||
|
# in 2* what we match, +1 more, plus the quote. |
||||
|
arg = windows_quoter_regex.sub(lambda mo: 2 * mo.group(1) + '\\"', arg) |
||||
|
|
||||
|
# %'s also need to be doubled otherwise they're interpreted as batch |
||||
|
# positional arguments. Also make sure to escape the % so that they're |
||||
|
# passed literally through escaping so they can be singled to just the |
||||
|
# original %. Otherwise, trying to pass the literal representation that |
||||
|
# looks like an environment variable to the shell (e.g. %PATH%) would fail. |
||||
|
arg = arg.replace('%', '%%') |
||||
|
|
||||
|
# These commands are used in rsp files, so no escaping for the shell (via ^) |
||||
|
# is necessary. |
||||
|
|
||||
|
# Finally, wrap the whole thing in quotes so that the above quote rule |
||||
|
# applies and whitespace isn't a word break. |
||||
|
return '"' + arg + '"' |
||||
|
|
||||
|
|
||||
|
def EncodeRspFileList(args): |
||||
|
"""Process a list of arguments using QuoteCmdExeArgument.""" |
||||
|
# Note that the first argument is assumed to be the command. Don't add |
||||
|
# quotes around it because then built-ins like 'echo', etc. won't work. |
||||
|
# Take care to normpath only the path in the case of 'call ../x.bat' because |
||||
|
# otherwise the whole thing is incorrectly interpreted as a path and not |
||||
|
# normalized correctly. |
||||
|
if not args: return '' |
||||
|
if args[0].startswith('call '): |
||||
|
call, program = args[0].split(' ', 1) |
||||
|
program = call + ' ' + os.path.normpath(program) |
||||
|
else: |
||||
|
program = os.path.normpath(args[0]) |
||||
|
return program + ' ' + ' '.join(QuoteForRspFile(arg) for arg in args[1:]) |
||||
|
|
||||
|
|
||||
|
def _GenericRetrieve(root, default, path): |
||||
|
"""Given a list of dictionary keys |path| and a tree of dicts |root|, find |
||||
|
value at path, or return |default| if any of the path doesn't exist.""" |
||||
|
if not root: |
||||
|
return default |
||||
|
if not path: |
||||
|
return root |
||||
|
return _GenericRetrieve(root.get(path[0]), default, path[1:]) |
||||
|
|
||||
|
|
||||
|
def _AddPrefix(element, prefix): |
||||
|
"""Add |prefix| to |element| or each subelement if element is iterable.""" |
||||
|
if element is None: |
||||
|
return element |
||||
|
# Note, not Iterable because we don't want to handle strings like that. |
||||
|
if isinstance(element, list) or isinstance(element, tuple): |
||||
|
return [prefix + e for e in element] |
||||
|
else: |
||||
|
return prefix + element |
||||
|
|
||||
|
|
||||
|
def _DoRemapping(element, map): |
||||
|
"""If |element| then remap it through |map|. If |element| is iterable then |
||||
|
each item will be remapped. Any elements not found will be removed.""" |
||||
|
if map is not None and element is not None: |
||||
|
if not callable(map): |
||||
|
map = map.get # Assume it's a dict, otherwise a callable to do the remap. |
||||
|
if isinstance(element, list) or isinstance(element, tuple): |
||||
|
element = filter(None, [map(elem) for elem in element]) |
||||
|
else: |
||||
|
element = map(element) |
||||
|
return element |
||||
|
|
||||
|
|
||||
|
def _AppendOrReturn(append, element): |
||||
|
"""If |append| is None, simply return |element|. If |append| is not None, |
||||
|
then add |element| to it, adding each item in |element| if it's a list or |
||||
|
tuple.""" |
||||
|
if append is not None and element is not None: |
||||
|
if isinstance(element, list) or isinstance(element, tuple): |
||||
|
append.extend(element) |
||||
|
else: |
||||
|
append.append(element) |
||||
|
else: |
||||
|
return element |
||||
|
|
||||
|
|
||||
|
def _FindDirectXInstallation(): |
||||
|
"""Try to find an installation location for the DirectX SDK. Check for the |
||||
|
standard environment variable, and if that doesn't exist, try to find |
||||
|
via the registry. May return None if not found in either location.""" |
||||
|
dxsdk_dir = os.environ.get('DXSDK_DIR') |
||||
|
if not dxsdk_dir: |
||||
|
# Setup params to pass to and attempt to launch reg.exe. |
||||
|
cmd = ['reg.exe', 'query', r'HKLM\Software\Microsoft\DirectX', '/s'] |
||||
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
||||
|
for line in p.communicate()[0].splitlines(): |
||||
|
if 'InstallPath' in line: |
||||
|
dxsdk_dir = line.split(' ')[3] + "\\" |
||||
|
return dxsdk_dir |
||||
|
|
||||
|
|
||||
|
class MsvsSettings(object): |
||||
|
"""A class that understands the gyp 'msvs_...' values (especially the |
||||
|
msvs_settings field). They largely correpond to the VS2008 IDE DOM. This |
||||
|
class helps map those settings to command line options.""" |
||||
|
|
||||
|
def __init__(self, spec, generator_flags): |
||||
|
self.spec = spec |
||||
|
self.vs_version = GetVSVersion(generator_flags) |
||||
|
self.dxsdk_dir = _FindDirectXInstallation() |
||||
|
|
||||
|
# Try to find an installation location for the Windows DDK by checking |
||||
|
# the WDK_DIR environment variable, may be None. |
||||
|
self.wdk_dir = os.environ.get('WDK_DIR') |
||||
|
|
||||
|
supported_fields = [ |
||||
|
('msvs_configuration_attributes', dict), |
||||
|
('msvs_settings', dict), |
||||
|
('msvs_system_include_dirs', list), |
||||
|
('msvs_disabled_warnings', list), |
||||
|
('msvs_precompiled_header', str), |
||||
|
('msvs_precompiled_source', str), |
||||
|
('msvs_target_platform', str), |
||||
|
] |
||||
|
configs = spec['configurations'] |
||||
|
for field, default in supported_fields: |
||||
|
setattr(self, field, {}) |
||||
|
for configname, config in configs.iteritems(): |
||||
|
getattr(self, field)[configname] = config.get(field, default()) |
||||
|
|
||||
|
self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) |
||||
|
|
||||
|
def GetVSMacroEnv(self, base_to_build=None, config=None): |
||||
|
"""Get a dict of variables mapping internal VS macro names to their gyp |
||||
|
equivalents.""" |
||||
|
target_platform = self.GetTargetPlatform(config) |
||||
|
target_platform = {'x86': 'Win32'}.get(target_platform, target_platform) |
||||
|
replacements = { |
||||
|
'$(VSInstallDir)': self.vs_version.Path(), |
||||
|
'$(VCInstallDir)': os.path.join(self.vs_version.Path(), 'VC') + '\\', |
||||
|
'$(OutDir)\\': base_to_build + '\\' if base_to_build else '', |
||||
|
'$(IntDir)': '$!INTERMEDIATE_DIR', |
||||
|
'$(InputPath)': '${source}', |
||||
|
'$(InputName)': '${root}', |
||||
|
'$(ProjectName)': self.spec['target_name'], |
||||
|
'$(PlatformName)': target_platform, |
||||
|
} |
||||
|
# Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be |
||||
|
# set. This happens when the SDK is sync'd via src-internal, rather than |
||||
|
# by typical end-user installation of the SDK. If it's not set, we don't |
||||
|
# want to leave the unexpanded variable in the path, so simply strip it. |
||||
|
replacements['$(DXSDK_DIR)'] = self.dxsdk_dir if self.dxsdk_dir else '' |
||||
|
replacements['$(WDK_DIR)'] = self.wdk_dir if self.wdk_dir else '' |
||||
|
return replacements |
||||
|
|
||||
|
def ConvertVSMacros(self, s, base_to_build=None, config=None): |
||||
|
"""Convert from VS macro names to something equivalent.""" |
||||
|
env = self.GetVSMacroEnv(base_to_build, config=config) |
||||
|
return ExpandMacros(s, env) |
||||
|
|
||||
|
def AdjustLibraries(self, libraries): |
||||
|
"""Strip -l from library if it's specified with that.""" |
||||
|
return [lib[2:] if lib.startswith('-l') else lib for lib in libraries] |
||||
|
|
||||
|
def _GetAndMunge(self, field, path, default, prefix, append, map): |
||||
|
"""Retrieve a value from |field| at |path| or return |default|. If |
||||
|
|append| is specified, and the item is found, it will be appended to that |
||||
|
object instead of returned. If |map| is specified, results will be |
||||
|
remapped through |map| before being returned or appended.""" |
||||
|
result = _GenericRetrieve(field, default, path) |
||||
|
result = _DoRemapping(result, map) |
||||
|
result = _AddPrefix(result, prefix) |
||||
|
return _AppendOrReturn(append, result) |
||||
|
|
||||
|
class _GetWrapper(object): |
||||
|
def __init__(self, parent, field, base_path, append=None): |
||||
|
self.parent = parent |
||||
|
self.field = field |
||||
|
self.base_path = [base_path] |
||||
|
self.append = append |
||||
|
def __call__(self, name, map=None, prefix='', default=None): |
||||
|
return self.parent._GetAndMunge(self.field, self.base_path + [name], |
||||
|
default=default, prefix=prefix, append=self.append, map=map) |
||||
|
|
||||
|
def GetTargetPlatform(self, config): |
||||
|
target_platform = self.msvs_target_platform.get(config, '') |
||||
|
if not target_platform: |
||||
|
target_platform = 'Win32' |
||||
|
return {'Win32': 'x86'}.get(target_platform, target_platform) |
||||
|
|
||||
|
def _RealConfig(self, config): |
||||
|
target_platform = self.GetTargetPlatform(config) |
||||
|
if target_platform == 'x64' and not config.endswith('_x64'): |
||||
|
config += '_x64' |
||||
|
return config |
||||
|
|
||||
|
def _Setting(self, path, config, |
||||
|
default=None, prefix='', append=None, map=None): |
||||
|
"""_GetAndMunge for msvs_settings.""" |
||||
|
config = self._RealConfig(config) |
||||
|
return self._GetAndMunge( |
||||
|
self.msvs_settings[config], path, default, prefix, append, map) |
||||
|
|
||||
|
def _ConfigAttrib(self, path, config, |
||||
|
default=None, prefix='', append=None, map=None): |
||||
|
"""_GetAndMunge for msvs_configuration_attributes.""" |
||||
|
config = self._RealConfig(config) |
||||
|
return self._GetAndMunge( |
||||
|
self.msvs_configuration_attributes[config], |
||||
|
path, default, prefix, append, map) |
||||
|
|
||||
|
def AdjustIncludeDirs(self, include_dirs, config): |
||||
|
"""Updates include_dirs to expand VS specific paths, and adds the system |
||||
|
include dirs used for platform SDK and similar.""" |
||||
|
config = self._RealConfig(config) |
||||
|
includes = include_dirs + self.msvs_system_include_dirs[config] |
||||
|
includes.extend(self._Setting( |
||||
|
('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[])) |
||||
|
return [self.ConvertVSMacros(p, config=config) for p in includes] |
||||
|
|
||||
|
def GetComputedDefines(self, config): |
||||
|
"""Returns the set of defines that are injected to the defines list based |
||||
|
on other VS settings.""" |
||||
|
config = self._RealConfig(config) |
||||
|
defines = [] |
||||
|
if self._ConfigAttrib(['CharacterSet'], config) == '1': |
||||
|
defines.extend(('_UNICODE', 'UNICODE')) |
||||
|
if self._ConfigAttrib(['CharacterSet'], config) == '2': |
||||
|
defines.append('_MBCS') |
||||
|
defines.extend(self._Setting( |
||||
|
('VCCLCompilerTool', 'PreprocessorDefinitions'), config, default=[])) |
||||
|
return defines |
||||
|
|
||||
|
def GetOutputName(self, config, expand_special): |
||||
|
"""Gets the explicitly overridden output name for a target or returns None |
||||
|
if it's not overridden.""" |
||||
|
config = self._RealConfig(config) |
||||
|
type = self.spec['type'] |
||||
|
root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool' |
||||
|
# TODO(scottmg): Handle OutputDirectory without OutputFile. |
||||
|
output_file = self._Setting((root, 'OutputFile'), config) |
||||
|
if output_file: |
||||
|
output_file = expand_special(self.ConvertVSMacros( |
||||
|
output_file, config=config)) |
||||
|
return output_file |
||||
|
|
||||
|
def GetCflags(self, config): |
||||
|
"""Returns the flags that need to be added to .c and .cc compilations.""" |
||||
|
config = self._RealConfig(config) |
||||
|
cflags = [] |
||||
|
cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]]) |
||||
|
cl = self._GetWrapper(self, self.msvs_settings[config], |
||||
|
'VCCLCompilerTool', append=cflags) |
||||
|
cl('Optimization', |
||||
|
map={'0': 'd', '1': '1', '2': '2', '3': 'x'}, prefix='/O') |
||||
|
cl('InlineFunctionExpansion', prefix='/Ob') |
||||
|
cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy') |
||||
|
cl('FavorSizeOrSpeed', map={'1': 't', '2': 's'}, prefix='/O') |
||||
|
cl('WholeProgramOptimization', map={'true': '/GL'}) |
||||
|
cl('WarningLevel', prefix='/W') |
||||
|
cl('WarnAsError', map={'true': '/WX'}) |
||||
|
cl('DebugInformationFormat', |
||||
|
map={'1': '7', '3': 'i', '4': 'I'}, prefix='/Z') |
||||
|
cl('RuntimeTypeInfo', map={'true': '/GR', 'false': '/GR-'}) |
||||
|
cl('EnableFunctionLevelLinking', map={'true': '/Gy', 'false': '/Gy-'}) |
||||
|
cl('MinimalRebuild', map={'true': '/Gm'}) |
||||
|
cl('BufferSecurityCheck', map={'true': '/GS', 'false': '/GS-'}) |
||||
|
cl('BasicRuntimeChecks', map={'1': 's', '2': 'u', '3': '1'}, prefix='/RTC') |
||||
|
cl('RuntimeLibrary', |
||||
|
map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M') |
||||
|
cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH') |
||||
|
cl('AdditionalOptions', prefix='') |
||||
|
# ninja handles parallelism by itself, don't have the compiler do it too. |
||||
|
cflags = filter(lambda x: not x.startswith('/MP'), cflags) |
||||
|
return cflags |
||||
|
|
||||
|
def GetPrecompiledHeader(self, config, gyp_to_build_path): |
||||
|
"""Returns an object that handles the generation of precompiled header |
||||
|
build steps.""" |
||||
|
config = self._RealConfig(config) |
||||
|
return _PchHelper(self, config, gyp_to_build_path) |
||||
|
|
||||
|
def _GetPchFlags(self, config, extension): |
||||
|
"""Get the flags to be added to the cflags for precompiled header support. |
||||
|
""" |
||||
|
config = self._RealConfig(config) |
||||
|
# The PCH is only built once by a particular source file. Usage of PCH must |
||||
|
# only be for the same language (i.e. C vs. C++), so only include the pch |
||||
|
# flags when the language matches. |
||||
|
if self.msvs_precompiled_header[config]: |
||||
|
source_ext = os.path.splitext(self.msvs_precompiled_source[config])[1] |
||||
|
if _LanguageMatchesForPch(source_ext, extension): |
||||
|
pch = os.path.split(self.msvs_precompiled_header[config])[1] |
||||
|
return ['/Yu' + pch, '/FI' + pch, '/Fp${pchprefix}.' + pch + '.pch'] |
||||
|
return [] |
||||
|
|
||||
|
def GetCflagsC(self, config): |
||||
|
"""Returns the flags that need to be added to .c compilations.""" |
||||
|
config = self._RealConfig(config) |
||||
|
return self._GetPchFlags(config, '.c') |
||||
|
|
||||
|
def GetCflagsCC(self, config): |
||||
|
"""Returns the flags that need to be added to .cc compilations.""" |
||||
|
config = self._RealConfig(config) |
||||
|
return ['/TP'] + self._GetPchFlags(config, '.cc') |
||||
|
|
||||
|
def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path): |
||||
|
"""Get and normalize the list of paths in AdditionalLibraryDirectories |
||||
|
setting.""" |
||||
|
config = self._RealConfig(config) |
||||
|
libpaths = self._Setting((root, 'AdditionalLibraryDirectories'), |
||||
|
config, default=[]) |
||||
|
libpaths = [os.path.normpath( |
||||
|
gyp_to_build_path(self.ConvertVSMacros(p, config=config))) |
||||
|
for p in libpaths] |
||||
|
return ['/LIBPATH:"' + p + '"' for p in libpaths] |
||||
|
|
||||
|
def GetLibFlags(self, config, gyp_to_build_path): |
||||
|
"""Returns the flags that need to be added to lib commands.""" |
||||
|
config = self._RealConfig(config) |
||||
|
libflags = [] |
||||
|
lib = self._GetWrapper(self, self.msvs_settings[config], |
||||
|
'VCLibrarianTool', append=libflags) |
||||
|
libflags.extend(self._GetAdditionalLibraryDirectories( |
||||
|
'VCLibrarianTool', config, gyp_to_build_path)) |
||||
|
lib('AdditionalOptions') |
||||
|
return libflags |
||||
|
|
||||
|
def _GetDefFileAsLdflags(self, spec, ldflags, gyp_to_build_path): |
||||
|
""".def files get implicitly converted to a ModuleDefinitionFile for the |
||||
|
linker in the VS generator. Emulate that behaviour here.""" |
||||
|
def_file = '' |
||||
|
if spec['type'] in ('shared_library', 'loadable_module', 'executable'): |
||||
|
def_files = [s for s in spec.get('sources', []) if s.endswith('.def')] |
||||
|
if len(def_files) == 1: |
||||
|
ldflags.append('/DEF:"%s"' % gyp_to_build_path(def_files[0])) |
||||
|
elif len(def_files) > 1: |
||||
|
raise Exception("Multiple .def files") |
||||
|
|
||||
|
def GetLdflags(self, config, gyp_to_build_path, expand_special): |
||||
|
"""Returns the flags that need to be added to link commands.""" |
||||
|
config = self._RealConfig(config) |
||||
|
ldflags = [] |
||||
|
ld = self._GetWrapper(self, self.msvs_settings[config], |
||||
|
'VCLinkerTool', append=ldflags) |
||||
|
self._GetDefFileAsLdflags(self.spec, ldflags, gyp_to_build_path) |
||||
|
ld('GenerateDebugInformation', map={'true': '/DEBUG'}) |
||||
|
ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:') |
||||
|
ldflags.extend(self._GetAdditionalLibraryDirectories( |
||||
|
'VCLinkerTool', config, gyp_to_build_path)) |
||||
|
ld('DelayLoadDLLs', prefix='/DELAYLOAD:') |
||||
|
out = self.GetOutputName(config, expand_special) |
||||
|
if out: |
||||
|
ldflags.append('/OUT:' + out) |
||||
|
ld('AdditionalOptions', prefix='') |
||||
|
ld('SubSystem', map={'1': 'CONSOLE', '2': 'WINDOWS'}, prefix='/SUBSYSTEM:') |
||||
|
ld('LinkIncremental', map={'1': ':NO', '2': ''}, prefix='/INCREMENTAL') |
||||
|
ld('FixedBaseAddress', map={'1': ':NO', '2': ''}, prefix='/FIXED') |
||||
|
ld('RandomizedBaseAddress', |
||||
|
map={'1': ':NO', '2': ''}, prefix='/DYNAMICBASE') |
||||
|
ld('DataExecutionPrevention', |
||||
|
map={'1': ':NO', '2': ''}, prefix='/NXCOMPAT') |
||||
|
ld('OptimizeReferences', map={'1': 'NOREF', '2': 'REF'}, prefix='/OPT:') |
||||
|
ld('EnableCOMDATFolding', map={'1': 'NOICF', '2': 'ICF'}, prefix='/OPT:') |
||||
|
ld('LinkTimeCodeGeneration', map={'1': '/LTCG'}) |
||||
|
ld('IgnoreDefaultLibraryNames', prefix='/NODEFAULTLIB:') |
||||
|
ld('ResourceOnlyDLL', map={'true': '/NOENTRY'}) |
||||
|
ld('EntryPointSymbol', prefix='/ENTRY:') |
||||
|
# TODO(scottmg): This should sort of be somewhere else (not really a flag). |
||||
|
ld('AdditionalDependencies', prefix='') |
||||
|
# TODO(scottmg): These too. |
||||
|
ldflags.extend(('kernel32.lib', 'user32.lib', 'gdi32.lib', 'winspool.lib', |
||||
|
'comdlg32.lib', 'advapi32.lib', 'shell32.lib', 'ole32.lib', |
||||
|
'oleaut32.lib', 'uuid.lib', 'odbc32.lib', 'DelayImp.lib')) |
||||
|
|
||||
|
# If the base address is not specifically controlled, DYNAMICBASE should |
||||
|
# be on by default. |
||||
|
base_flags = filter(lambda x: 'DYNAMICBASE' in x or x == '/FIXED', |
||||
|
ldflags) |
||||
|
if not base_flags: |
||||
|
ldflags.append('/DYNAMICBASE') |
||||
|
|
||||
|
# If the NXCOMPAT flag has not been specified, default to on. Despite the |
||||
|
# documentation that says this only defaults to on when the subsystem is |
||||
|
# Vista or greater (which applies to the linker), the IDE defaults it on |
||||
|
# unless it's explicitly off. |
||||
|
if not filter(lambda x: 'NXCOMPAT' in x, ldflags): |
||||
|
ldflags.append('/NXCOMPAT') |
||||
|
|
||||
|
return ldflags |
||||
|
|
||||
|
def IsUseLibraryDependencyInputs(self, config): |
||||
|
"""Returns whether the target should be linked via Use Library Dependency |
||||
|
Inputs (using component .objs of a given .lib).""" |
||||
|
config = self._RealConfig(config) |
||||
|
uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config) |
||||
|
return uldi == 'true' |
||||
|
|
||||
|
def GetRcflags(self, config, gyp_to_ninja_path): |
||||
|
"""Returns the flags that need to be added to invocations of the resource |
||||
|
compiler.""" |
||||
|
config = self._RealConfig(config) |
||||
|
rcflags = [] |
||||
|
rc = self._GetWrapper(self, self.msvs_settings[config], |
||||
|
'VCResourceCompilerTool', append=rcflags) |
||||
|
rc('AdditionalIncludeDirectories', map=gyp_to_ninja_path, prefix='/I') |
||||
|
rcflags.append('/I' + gyp_to_ninja_path('.')) |
||||
|
rc('PreprocessorDefinitions', prefix='/d') |
||||
|
# /l arg must be in hex without leading '0x' |
||||
|
rc('Culture', prefix='/l', map=lambda x: hex(int(x))[2:]) |
||||
|
return rcflags |
||||
|
|
||||
|
def BuildCygwinBashCommandLine(self, args, path_to_base): |
||||
|
"""Build a command line that runs args via cygwin bash. We assume that all |
||||
|
incoming paths are in Windows normpath'd form, so they need to be |
||||
|
converted to posix style for the part of the command line that's passed to |
||||
|
bash. We also have to do some Visual Studio macro emulation here because |
||||
|
various rules use magic VS names for things. Also note that rules that |
||||
|
contain ninja variables cannot be fixed here (for example ${source}), so |
||||
|
the outer generator needs to make sure that the paths that are written out |
||||
|
are in posix style, if the command line will be used here.""" |
||||
|
cygwin_dir = os.path.normpath( |
||||
|
os.path.join(path_to_base, self.msvs_cygwin_dirs[0])) |
||||
|
cd = ('cd %s' % path_to_base).replace('\\', '/') |
||||
|
args = [a.replace('\\', '/') for a in args] |
||||
|
args = ["'%s'" % a.replace("'", "\\'") for a in args] |
||||
|
bash_cmd = ' '.join(args) |
||||
|
cmd = ( |
||||
|
'call "%s\\setup_env.bat" && set CYGWIN=nontsec && ' % cygwin_dir + |
||||
|
'bash -c "%s ; %s"' % (cd, bash_cmd)) |
||||
|
return cmd |
||||
|
|
||||
|
def IsRuleRunUnderCygwin(self, rule): |
||||
|
"""Determine if an action should be run under cygwin. If the variable is |
||||
|
unset, or set to 1 we use cygwin.""" |
||||
|
return int(rule.get('msvs_cygwin_shell', |
||||
|
self.spec.get('msvs_cygwin_shell', 1))) != 0 |
||||
|
|
||||
|
def HasExplicitIdlRules(self, spec): |
||||
|
"""Determine if there's an explicit rule for idl files. When there isn't we |
||||
|
need to generate implicit rules to build MIDL .idl files.""" |
||||
|
for rule in spec.get('rules', []): |
||||
|
if rule['extension'] == 'idl' and int(rule.get('msvs_external_rule', 0)): |
||||
|
return True |
||||
|
return False |
||||
|
|
||||
|
def GetIdlBuildData(self, source, config): |
||||
|
"""Determine the implicit outputs for an idl file. Returns output |
||||
|
directory, outputs, and variables and flags that are required.""" |
||||
|
config = self._RealConfig(config) |
||||
|
midl_get = self._GetWrapper(self, self.msvs_settings[config], 'VCMIDLTool') |
||||
|
def midl(name, default=None): |
||||
|
return self.ConvertVSMacros(midl_get(name, default=default), |
||||
|
config=config) |
||||
|
tlb = midl('TypeLibraryName', default='${root}.tlb') |
||||
|
header = midl('HeaderFileName', default='${root}.h') |
||||
|
dlldata = midl('DLLDataFileName', default='dlldata.c') |
||||
|
iid = midl('InterfaceIdentifierFileName', default='${root}_i.c') |
||||
|
proxy = midl('ProxyFileName', default='${root}_p.c') |
||||
|
# Note that .tlb is not included in the outputs as it is not always |
||||
|
# generated depending on the content of the input idl file. |
||||
|
outdir = midl('OutputDirectory', default='') |
||||
|
output = [header, dlldata, iid, proxy] |
||||
|
variables = [('tlb', tlb), |
||||
|
('h', header), |
||||
|
('dlldata', dlldata), |
||||
|
('iid', iid), |
||||
|
('proxy', proxy)] |
||||
|
# TODO(scottmg): Are there configuration settings to set these flags? |
||||
|
flags = ['/char', 'signed', '/env', 'win32', '/Oicf'] |
||||
|
return outdir, output, variables, flags |
||||
|
|
||||
|
|
||||
|
def _LanguageMatchesForPch(source_ext, pch_source_ext): |
||||
|
c_exts = ('.c',) |
||||
|
cc_exts = ('.cc', '.cxx', '.cpp') |
||||
|
return ((source_ext in c_exts and pch_source_ext in c_exts) or |
||||
|
(source_ext in cc_exts and pch_source_ext in cc_exts)) |
||||
|
|
||||
|
class PrecompiledHeader(object): |
||||
|
"""Helper to generate dependencies and build rules to handle generation of |
||||
|
precompiled headers. Interface matches the GCH handler in xcode_emulation.py. |
||||
|
""" |
||||
|
def __init__(self, settings, config, gyp_to_build_path): |
||||
|
self.settings = settings |
||||
|
self.config = config |
||||
|
self.gyp_to_build_path = gyp_to_build_path |
||||
|
|
||||
|
def _PchHeader(self): |
||||
|
"""Get the header that will appear in an #include line for all source |
||||
|
files.""" |
||||
|
return os.path.split(self.settings.msvs_precompiled_header[self.config])[1] |
||||
|
|
||||
|
def _PchSource(self): |
||||
|
"""Get the source file that is built once to compile the pch data.""" |
||||
|
return self.gyp_to_build_path( |
||||
|
self.settings.msvs_precompiled_source[self.config]) |
||||
|
|
||||
|
def _PchOutput(self): |
||||
|
"""Get the name of the output of the compiled pch data.""" |
||||
|
return '${pchprefix}.' + self._PchHeader() + '.pch' |
||||
|
|
||||
|
def GetObjDependencies(self, sources, objs): |
||||
|
"""Given a list of sources files and the corresponding object files, |
||||
|
returns a list of the pch files that should be depended upon. The |
||||
|
additional wrapping in the return value is for interface compatability |
||||
|
with make.py on Mac, and xcode_emulation.py.""" |
||||
|
if not self._PchHeader(): |
||||
|
return [] |
||||
|
source = self._PchSource() |
||||
|
assert source |
||||
|
pch_ext = os.path.splitext(self._PchSource())[1] |
||||
|
for source in sources: |
||||
|
if _LanguageMatchesForPch(os.path.splitext(source)[1], pch_ext): |
||||
|
return [(None, None, self._PchOutput())] |
||||
|
return [] |
||||
|
|
||||
|
def GetPchBuildCommands(self): |
||||
|
"""Returns [(path_to_pch, language_flag, language, header)]. |
||||
|
|path_to_gch| and |header| are relative to the build directory.""" |
||||
|
header = self._PchHeader() |
||||
|
source = self._PchSource() |
||||
|
if not source or not header: |
||||
|
return [] |
||||
|
ext = os.path.splitext(source)[1] |
||||
|
lang = 'c' if ext == '.c' else 'cc' |
||||
|
return [(self._PchOutput(), '/Yc' + header, lang, source)] |
||||
|
|
||||
|
|
||||
|
vs_version = None |
||||
|
def GetVSVersion(generator_flags): |
||||
|
global vs_version |
||||
|
if not vs_version: |
||||
|
vs_version = gyp.MSVSVersion.SelectVisualStudioVersion( |
||||
|
generator_flags.get('msvs_version', 'auto')) |
||||
|
return vs_version |
||||
|
|
||||
|
def _GetVsvarsSetupArgs(generator_flags, arch): |
||||
|
vs = GetVSVersion(generator_flags) |
||||
|
return vs.SetupScript() |
||||
|
|
||||
|
def ExpandMacros(string, expansions): |
||||
|
"""Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv |
||||
|
for the canonical way to retrieve a suitable dict.""" |
||||
|
if '$' in string: |
||||
|
for old, new in expansions.iteritems(): |
||||
|
assert '$(' not in new, new |
||||
|
string = string.replace(old, new) |
||||
|
return string |
||||
|
|
||||
|
def _ExtractImportantEnvironment(output_of_set): |
||||
|
"""Extracts environment variables required for the toolchain to run from |
||||
|
a textual dump output by the cmd.exe 'set' command.""" |
||||
|
envvars_to_save = ( |
||||
|
'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. |
||||
|
'include', |
||||
|
'lib', |
||||
|
'libpath', |
||||
|
'path', |
||||
|
'pathext', |
||||
|
'systemroot', |
||||
|
'temp', |
||||
|
'tmp', |
||||
|
) |
||||
|
env = {} |
||||
|
for line in output_of_set.splitlines(): |
||||
|
for envvar in envvars_to_save: |
||||
|
if re.match(envvar + '=', line.lower()): |
||||
|
var, setting = line.split('=', 1) |
||||
|
if envvar == 'path': |
||||
|
# Our own rules (for running gyp-win-tool) and other actions in |
||||
|
# Chromium rely on python being in the path. Add the path to this |
||||
|
# python here so that if it's not in the path when ninja is run |
||||
|
# later, python will still be found. |
||||
|
setting = os.path.dirname(sys.executable) + os.pathsep + setting |
||||
|
env[var.upper()] = setting |
||||
|
break |
||||
|
for required in ('SYSTEMROOT', 'TEMP', 'TMP'): |
||||
|
if required not in env: |
||||
|
raise Exception('Environment variable "%s" ' |
||||
|
'required to be set to valid path' % required) |
||||
|
return env |
||||
|
|
||||
|
def _FormatAsEnvironmentBlock(envvar_dict): |
||||
|
"""Format as an 'environment block' directly suitable for CreateProcess. |
||||
|
Briefly this is a list of key=value\0, terminated by an additional \0. See |
||||
|
CreateProcess documentation for more details.""" |
||||
|
block = '' |
||||
|
nul = '\0' |
||||
|
for key, value in envvar_dict.iteritems(): |
||||
|
block += key + '=' + value + nul |
||||
|
block += nul |
||||
|
return block |
||||
|
|
||||
|
def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, open_out): |
||||
|
"""It's not sufficient to have the absolute path to the compiler, linker, |
||||
|
etc. on Windows, as those tools rely on .dlls being in the PATH. We also |
||||
|
need to support both x86 and x64 compilers within the same build (to support |
||||
|
msvs_target_platform hackery). Different architectures require a different |
||||
|
compiler binary, and different supporting environment variables (INCLUDE, |
||||
|
LIB, LIBPATH). So, we extract the environment here, wrap all invocations |
||||
|
of compiler tools (cl, link, lib, rc, midl, etc.) via win_tool.py which |
||||
|
sets up the environment, and then we do not prefix the compiler with |
||||
|
an absolute path, instead preferring something like "cl.exe" in the rule |
||||
|
which will then run whichever the environment setup has put in the path.""" |
||||
|
vs = GetVSVersion(generator_flags) |
||||
|
for arch in ('x86', 'x64'): |
||||
|
args = vs.SetupScript(arch) |
||||
|
args.extend(('&&', 'set')) |
||||
|
popen = subprocess.Popen( |
||||
|
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
||||
|
variables, _ = popen.communicate() |
||||
|
env = _ExtractImportantEnvironment(variables) |
||||
|
env_block = _FormatAsEnvironmentBlock(env) |
||||
|
f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb') |
||||
|
f.write(env_block) |
||||
|
f.close() |
@ -0,0 +1,161 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
|
||||
|
# Copyright (c) 2012 Google Inc. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""Utility functions for Windows builds. |
||||
|
|
||||
|
These functions are executed via gyp-win-tool when using the ninja generator. |
||||
|
""" |
||||
|
|
||||
|
import os |
||||
|
import shutil |
||||
|
import subprocess |
||||
|
import sys |
||||
|
|
||||
|
|
||||
|
def main(args): |
||||
|
executor = WinTool() |
||||
|
exit_code = executor.Dispatch(args) |
||||
|
if exit_code is not None: |
||||
|
sys.exit(exit_code) |
||||
|
|
||||
|
|
||||
|
class WinTool(object): |
||||
|
"""This class performs all the Windows tooling steps. The methods can either |
||||
|
be executed directly, or dispatched from an argument list.""" |
||||
|
|
||||
|
def Dispatch(self, args): |
||||
|
"""Dispatches a string command to a method.""" |
||||
|
if len(args) < 1: |
||||
|
raise Exception("Not enough arguments") |
||||
|
|
||||
|
method = "Exec%s" % self._CommandifyName(args[0]) |
||||
|
return getattr(self, method)(*args[1:]) |
||||
|
|
||||
|
def _CommandifyName(self, name_string): |
||||
|
"""Transforms a tool name like recursive-mirror to RecursiveMirror.""" |
||||
|
return name_string.title().replace('-', '') |
||||
|
|
||||
|
def _GetEnv(self, arch): |
||||
|
"""Gets the saved environment from a file for a given architecture.""" |
||||
|
# The environment is saved as an "environment block" (see CreateProcess |
||||
|
# and msvs_emulation for details). We convert to a dict here. |
||||
|
# Drop last 2 NULs, one for list terminator, one for trailing vs. separator. |
||||
|
pairs = open(arch).read()[:-2].split('\0') |
||||
|
kvs = [item.split('=', 1) for item in pairs] |
||||
|
return dict(kvs) |
||||
|
|
||||
|
def ExecStamp(self, path): |
||||
|
"""Simple stamp command.""" |
||||
|
open(path, 'w').close() |
||||
|
|
||||
|
def ExecRecursiveMirror(self, source, dest): |
||||
|
"""Emulation of rm -rf out && cp -af in out.""" |
||||
|
if os.path.exists(dest): |
||||
|
if os.path.isdir(dest): |
||||
|
shutil.rmtree(dest) |
||||
|
else: |
||||
|
os.unlink(dest) |
||||
|
if os.path.isdir(source): |
||||
|
shutil.copytree(source, dest) |
||||
|
else: |
||||
|
shutil.copy2(source, dest) |
||||
|
|
||||
|
def ExecLinkWrapper(self, arch, *args): |
||||
|
"""Filter diagnostic output from link that looks like: |
||||
|
' Creating library ui.dll.lib and object ui.dll.exp' |
||||
|
This happens when there are exports from the dll or exe. |
||||
|
""" |
||||
|
env = self._GetEnv(arch) |
||||
|
popen = subprocess.Popen(args, shell=True, env=env, |
||||
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
||||
|
out, _ = popen.communicate() |
||||
|
for line in out.splitlines(): |
||||
|
if not line.startswith(' Creating library '): |
||||
|
print line |
||||
|
return popen.returncode |
||||
|
|
||||
|
def ExecMidlWrapper(self, arch, outdir, tlb, h, dlldata, iid, proxy, idl, |
||||
|
*flags): |
||||
|
"""Filter noisy filenames output from MIDL compile step that isn't |
||||
|
quietable via command line flags. |
||||
|
""" |
||||
|
args = ['midl', '/nologo'] + list(flags) + [ |
||||
|
'/out', outdir, |
||||
|
'/tlb', tlb, |
||||
|
'/h', h, |
||||
|
'/dlldata', dlldata, |
||||
|
'/iid', iid, |
||||
|
'/proxy', proxy, |
||||
|
idl] |
||||
|
env = self._GetEnv(arch) |
||||
|
popen = subprocess.Popen(args, shell=True, env=env, |
||||
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
||||
|
out, _ = popen.communicate() |
||||
|
# Filter junk out of stdout, and write filtered versions. Output we want |
||||
|
# to filter is pairs of lines that look like this: |
||||
|
# Processing C:\Program Files (x86)\Microsoft SDKs\...\include\objidl.idl |
||||
|
# objidl.idl |
||||
|
lines = out.splitlines() |
||||
|
prefix = 'Processing ' |
||||
|
processing = set(os.path.basename(x) for x in lines if x.startswith(prefix)) |
||||
|
for line in lines: |
||||
|
if not line.startswith(prefix) and line not in processing: |
||||
|
print line |
||||
|
return popen.returncode |
||||
|
|
||||
|
def ExecAsmWrapper(self, arch, *args): |
||||
|
"""Filter logo banner from invocations of asm.exe.""" |
||||
|
env = self._GetEnv(arch) |
||||
|
# MSVS doesn't assemble x64 asm files. |
||||
|
if arch == 'environment.x64': |
||||
|
return 0 |
||||
|
popen = subprocess.Popen(args, shell=True, env=env, |
||||
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
||||
|
out, _ = popen.communicate() |
||||
|
for line in out.splitlines(): |
||||
|
if (not line.startswith('Copyright (C) Microsoft Corporation') and |
||||
|
not line.startswith('Microsoft (R) Macro Assembler') and |
||||
|
not line.startswith(' Assembling: ') and |
||||
|
line): |
||||
|
print line |
||||
|
return popen.returncode |
||||
|
|
||||
|
def ExecRcWrapper(self, arch, *args): |
||||
|
"""Filter logo banner from invocations of rc.exe. Older versions of RC |
||||
|
don't support the /nologo flag.""" |
||||
|
env = self._GetEnv(arch) |
||||
|
popen = subprocess.Popen(args, shell=True, env=env, |
||||
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
||||
|
out, _ = popen.communicate() |
||||
|
for line in out.splitlines(): |
||||
|
if (not line.startswith('Microsoft (R) Windows (R) Resource Compiler') and |
||||
|
not line.startswith('Copyright (C) Microsoft Corporation') and |
||||
|
line): |
||||
|
print line |
||||
|
return popen.returncode |
||||
|
|
||||
|
def ExecClWrapper(self, arch, depname, *args): |
||||
|
"""Runs cl.exe and filters output through ninja-deplist-helper to get |
||||
|
dependendency information which is stored in |depname|.""" |
||||
|
env = self._GetEnv(arch) |
||||
|
args = ' '.join(args) + \ |
||||
|
'| ninja-deplist-helper -r . -q -f cl -o ' + depname + '"' |
||||
|
popen = subprocess.Popen(args, shell=True, env=env) |
||||
|
popen.wait() |
||||
|
return popen.returncode |
||||
|
|
||||
|
def ExecActionWrapper(self, arch, rspfile, *dir): |
||||
|
"""Runs an action command line from a response file using the environment |
||||
|
for |arch|. If |dir| is supplied, use that as the working directory.""" |
||||
|
env = self._GetEnv(arch) |
||||
|
args = open(rspfile).read() |
||||
|
dir = dir[0] if dir else None |
||||
|
popen = subprocess.Popen(args, shell=True, env=env, cwd=dir) |
||||
|
popen.wait() |
||||
|
return popen.returncode |
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
sys.exit(main(sys.argv[1:])) |
@ -1,23 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies actions which are not depended on by other targets get executed. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp() |
|
||||
|
|
||||
test.run_gyp('bare.gyp', chdir='src') |
|
||||
test.relocate('src', 'relocate/src') |
|
||||
test.build('bare.gyp', chdir='relocate/src') |
|
||||
|
|
||||
file_content = 'Hello from bare.py\n' |
|
||||
|
|
||||
test.built_file_must_match('out.txt', file_content, chdir='relocate/src') |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,25 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'bare', |
|
||||
'type': 'none', |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'action1', |
|
||||
'inputs': [ |
|
||||
'bare.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(PRODUCT_DIR)/out.txt', |
|
||||
], |
|
||||
'action': ['python', 'bare.py', '<(PRODUCT_DIR)/out.txt'], |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,11 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
f = open(sys.argv[1], 'wb') |
|
||||
f.write('Hello from bare.py\n') |
|
||||
f.close() |
|
@ -1,42 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies two actions can be attached to the same input files. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp() |
|
||||
|
|
||||
test.run_gyp('actions.gyp', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
# Test that two actions can be attached to the same inputs. |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
test.must_contain('relocate/src/output1.txt', 'hello there') |
|
||||
test.must_contain('relocate/src/output2.txt', 'hello there') |
|
||||
test.must_contain('relocate/src/output3.txt', 'hello there') |
|
||||
test.must_contain('relocate/src/output4.txt', 'hello there') |
|
||||
|
|
||||
# Test that process_outputs_as_sources works in conjuction with merged |
|
||||
# actions. |
|
||||
test.run_built_executable( |
|
||||
'multiple_action_source_filter', |
|
||||
chdir='relocate/src', |
|
||||
stdout=( |
|
||||
'{\n' |
|
||||
'bar\n' |
|
||||
'car\n' |
|
||||
'dar\n' |
|
||||
'ear\n' |
|
||||
'}\n' |
|
||||
), |
|
||||
) |
|
||||
|
|
||||
|
|
||||
test.pass_test() |
|
@ -1,165 +0,0 @@ |
|||||
# Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'variables': { |
|
||||
# Have a long string so that actions will exceed xp 512 character |
|
||||
# command limit on xp. |
|
||||
'long_string': |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
'abcdefghijklmnopqrstuvwxyz0123456789' |
|
||||
}, |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'multiple_action_target', |
|
||||
'type': 'none', |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'action1', |
|
||||
'inputs': [ |
|
||||
'copy.py', |
|
||||
'input.txt', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'output1.txt', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<@(_inputs)', '<(_outputs)', '<(long_string)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'action2', |
|
||||
'inputs': [ |
|
||||
'copy.py', |
|
||||
'input.txt', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'output2.txt', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<@(_inputs)', '<(_outputs)', '<(long_string)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'action3', |
|
||||
'inputs': [ |
|
||||
'copy.py', |
|
||||
'input.txt', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'output3.txt', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<@(_inputs)', '<(_outputs)', '<(long_string)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'action4', |
|
||||
'inputs': [ |
|
||||
'copy.py', |
|
||||
'input.txt', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'output4.txt', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<@(_inputs)', '<(_outputs)', '<(long_string)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'multiple_action_source_filter', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'main.c', |
|
||||
# TODO(bradnelson): add foo.c here once this issue is fixed: |
|
||||
# http://code.google.com/p/gyp/issues/detail?id=175 |
|
||||
], |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'action1', |
|
||||
'inputs': [ |
|
||||
'foo.c', |
|
||||
'filter.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/output1.c', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
'action': [ |
|
||||
'python', 'filter.py', 'foo', 'bar', 'foo.c', '<@(_outputs)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'action2', |
|
||||
'inputs': [ |
|
||||
'foo.c', |
|
||||
'filter.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/output2.c', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
'action': [ |
|
||||
'python', 'filter.py', 'foo', 'car', 'foo.c', '<@(_outputs)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'action3', |
|
||||
'inputs': [ |
|
||||
'foo.c', |
|
||||
'filter.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/output3.c', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
'action': [ |
|
||||
'python', 'filter.py', 'foo', 'dar', 'foo.c', '<@(_outputs)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'action4', |
|
||||
'inputs': [ |
|
||||
'foo.c', |
|
||||
'filter.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/output4.c', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
'action': [ |
|
||||
'python', 'filter.py', 'foo', 'ear', 'foo.c', '<@(_outputs)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,9 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
# Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import shutil |
|
||||
import sys |
|
||||
|
|
||||
shutil.copyfile(sys.argv[1], sys.argv[2]) |
|
@ -1,12 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
# Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
data = open(sys.argv[3], 'r').read() |
|
||||
fh = open(sys.argv[4], 'w') |
|
||||
fh.write(data.replace(sys.argv[1], sys.argv[2])) |
|
||||
fh.close() |
|
@ -1,11 +0,0 @@ |
|||||
/*
|
|
||||
* Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
* Use of this source code is governed by a BSD-style license that can be |
|
||||
* found in the LICENSE file. |
|
||||
*/ |
|
||||
|
|
||||
#include <stdio.h> |
|
||||
|
|
||||
void foo(void) { |
|
||||
printf("foo\n"); |
|
||||
} |
|
@ -1 +0,0 @@ |
|||||
hello there |
|
@ -1,22 +0,0 @@ |
|||||
/*
|
|
||||
* Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
* Use of this source code is governed by a BSD-style license that can be |
|
||||
* found in the LICENSE file. |
|
||||
*/ |
|
||||
|
|
||||
#include <stdio.h> |
|
||||
|
|
||||
void bar(void); |
|
||||
void car(void); |
|
||||
void dar(void); |
|
||||
void ear(void); |
|
||||
|
|
||||
int main() { |
|
||||
printf("{\n"); |
|
||||
bar(); |
|
||||
car(); |
|
||||
dar(); |
|
||||
ear(); |
|
||||
printf("}\n"); |
|
||||
return 0; |
|
||||
} |
|
@ -1,26 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Test actions that output to PRODUCT_DIR. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
# TODO fix this for xcode: http://code.google.com/p/gyp/issues/detail?id=88 |
|
||||
test = TestGyp.TestGyp(formats=['!xcode']) |
|
||||
|
|
||||
test.run_gyp('none.gyp', chdir='src') |
|
||||
|
|
||||
test.build('none.gyp', test.ALL, chdir='src') |
|
||||
|
|
||||
file_content = 'Hello from make-file.py\n' |
|
||||
subdir_file_content = 'Hello from make-subdir-file.py\n' |
|
||||
|
|
||||
test.built_file_must_match('file.out', file_content, chdir='src') |
|
||||
test.built_file_must_match('subdir_file.out', subdir_file_content, chdir='src') |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,11 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
contents = 'Hello from make-file.py\n' |
|
||||
|
|
||||
open(sys.argv[1], 'wb').write(contents) |
|
@ -1,31 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'file', |
|
||||
'type': 'none', |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'make-file', |
|
||||
'inputs': [ |
|
||||
'make-file.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(PRODUCT_DIR)/file.out', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<(_inputs)', '<@(_outputs)', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
} |
|
||||
], |
|
||||
'dependencies': [ |
|
||||
'subdir/subdir.gyp:subdir_file', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,11 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
contents = 'Hello from make-subdir-file.py\n' |
|
||||
|
|
||||
open(sys.argv[1], 'wb').write(contents) |
|
@ -1,28 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'subdir_file', |
|
||||
'type': 'none', |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'make-subdir-file', |
|
||||
'inputs': [ |
|
||||
'make-subdir-file.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(PRODUCT_DIR)/subdir_file.out', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<(_inputs)', '<@(_outputs)', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
} |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,101 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies simple actions when using an explicit build target of 'all'. |
|
||||
""" |
|
||||
|
|
||||
import glob |
|
||||
import os |
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp(workdir='workarea_all') |
|
||||
|
|
||||
test.run_gyp('actions.gyp', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
# Some gyp files use an action that mentions an output but never |
|
||||
# writes it as a means to making the action run on every build. That |
|
||||
# doesn't mesh well with ninja's semantics. TODO(evan): figure out |
|
||||
# how to work always-run actions in to ninja. |
|
||||
if test.format == 'ninja': |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
else: |
|
||||
# Test that an "always run" action increases a counter on multiple |
|
||||
# invocations, and that a dependent action updates in step. |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter.txt', '1') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter_2.txt', '1') |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter.txt', '2') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter_2.txt', '2') |
|
||||
|
|
||||
# The "always run" action only counts to 2, but the dependent target |
|
||||
# will count forever if it's allowed to run. This verifies that the |
|
||||
# dependent target only runs when the "always run" action generates |
|
||||
# new output, not just because the "always run" ran. |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter.txt', '2') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter_2.txt', '2') |
|
||||
|
|
||||
expect = """\ |
|
||||
Hello from program.c |
|
||||
Hello from make-prog1.py |
|
||||
Hello from make-prog2.py |
|
||||
""" |
|
||||
|
|
||||
if test.format == 'xcode': |
|
||||
chdir = 'relocate/src/subdir1' |
|
||||
else: |
|
||||
chdir = 'relocate/src' |
|
||||
test.run_built_executable('program', chdir=chdir, stdout=expect) |
|
||||
|
|
||||
|
|
||||
test.must_match('relocate/src/subdir2/file.out', "Hello from make-file.py\n") |
|
||||
|
|
||||
|
|
||||
expect = "Hello from generate_main.py\n" |
|
||||
|
|
||||
if test.format == 'xcode': |
|
||||
chdir = 'relocate/src/subdir3' |
|
||||
else: |
|
||||
chdir = 'relocate/src' |
|
||||
test.run_built_executable('null_input', chdir=chdir, stdout=expect) |
|
||||
|
|
||||
|
|
||||
# Clean out files which may have been created if test.ALL was run. |
|
||||
def clean_dep_files(): |
|
||||
for file in (glob.glob('relocate/src/dep_*.txt') + |
|
||||
glob.glob('relocate/src/deps_all_done_*.txt')): |
|
||||
if os.path.exists(file): |
|
||||
os.remove(file) |
|
||||
|
|
||||
# Confirm our clean. |
|
||||
clean_dep_files() |
|
||||
test.must_not_exist('relocate/src/dep_1.txt') |
|
||||
test.must_not_exist('relocate/src/deps_all_done_first_123.txt') |
|
||||
|
|
||||
# Make sure all deps finish before an action is run on a 'None' target. |
|
||||
# If using the Make builder, add -j to make things more difficult. |
|
||||
arguments = [] |
|
||||
if test.format == 'make': |
|
||||
arguments = ['-j'] |
|
||||
test.build('actions.gyp', 'action_with_dependencies_123', chdir='relocate/src', |
|
||||
arguments=arguments) |
|
||||
test.must_exist('relocate/src/deps_all_done_first_123.txt') |
|
||||
|
|
||||
# Try again with a target that has deps in reverse. Output files from |
|
||||
# previous tests deleted. Confirm this execution did NOT run the ALL |
|
||||
# target which would mess up our dep tests. |
|
||||
clean_dep_files() |
|
||||
test.build('actions.gyp', 'action_with_dependencies_321', chdir='relocate/src', |
|
||||
arguments=arguments) |
|
||||
test.must_exist('relocate/src/deps_all_done_first_321.txt') |
|
||||
test.must_not_exist('relocate/src/deps_all_done_first_123.txt') |
|
||||
|
|
||||
|
|
||||
test.pass_test() |
|
@ -1,68 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies simple actions when using the default build target. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp(workdir='workarea_default') |
|
||||
|
|
||||
test.run_gyp('actions.gyp', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
# Some gyp files use an action that mentions an output but never |
|
||||
# writes it as a means to making the action run on every build. That |
|
||||
# doesn't mesh well with ninja's semantics. TODO(evan): figure out |
|
||||
# how to work always-run actions in to ninja. |
|
||||
if test.format == 'ninja': |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
else: |
|
||||
# Test that an "always run" action increases a counter on multiple |
|
||||
# invocations, and that a dependent action updates in step. |
|
||||
test.build('actions.gyp', chdir='relocate/src') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter.txt', '1') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter_2.txt', '1') |
|
||||
test.build('actions.gyp', chdir='relocate/src') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter.txt', '2') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter_2.txt', '2') |
|
||||
|
|
||||
# The "always run" action only counts to 2, but the dependent target |
|
||||
# will count forever if it's allowed to run. This verifies that the |
|
||||
# dependent target only runs when the "always run" action generates |
|
||||
# new output, not just because the "always run" ran. |
|
||||
test.build('actions.gyp', test.ALL, chdir='relocate/src') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter.txt', '2') |
|
||||
test.must_match('relocate/src/subdir1/actions-out/action-counter_2.txt', '2') |
|
||||
|
|
||||
expect = """\ |
|
||||
Hello from program.c |
|
||||
Hello from make-prog1.py |
|
||||
Hello from make-prog2.py |
|
||||
""" |
|
||||
|
|
||||
if test.format == 'xcode': |
|
||||
chdir = 'relocate/src/subdir1' |
|
||||
else: |
|
||||
chdir = 'relocate/src' |
|
||||
test.run_built_executable('program', chdir=chdir, stdout=expect) |
|
||||
|
|
||||
|
|
||||
test.must_match('relocate/src/subdir2/file.out', "Hello from make-file.py\n") |
|
||||
|
|
||||
|
|
||||
expect = "Hello from generate_main.py\n" |
|
||||
|
|
||||
if test.format == 'xcode': |
|
||||
chdir = 'relocate/src/subdir3' |
|
||||
else: |
|
||||
chdir = 'relocate/src' |
|
||||
test.run_built_executable('null_input', chdir=chdir, stdout=expect) |
|
||||
|
|
||||
|
|
||||
test.pass_test() |
|
@ -1,24 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies behavior for different action configuration errors: |
|
||||
exit status of 1, and the expected error message must be in stderr. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp(workdir='workarea_errors') |
|
||||
|
|
||||
|
|
||||
test.run_gyp('action_missing_name.gyp', chdir='src', status=1, stderr=None) |
|
||||
expect = [ |
|
||||
"Anonymous action in target broken_actions2. An action must have an 'action_name' field.", |
|
||||
] |
|
||||
test.must_contain_all_lines(test.stderr(), expect) |
|
||||
|
|
||||
|
|
||||
test.pass_test() |
|
@ -1,24 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'broken_actions2', |
|
||||
'type': 'none', |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'inputs': [ |
|
||||
'no_name.input', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', |
|
||||
'-c', |
|
||||
'print \'missing name\'', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,114 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'pull_in_all_actions', |
|
||||
'type': 'none', |
|
||||
'dependencies': [ |
|
||||
'subdir1/executable.gyp:*', |
|
||||
'subdir2/none.gyp:*', |
|
||||
'subdir3/null_input.gyp:*', |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'depend_on_always_run_action', |
|
||||
'type': 'none', |
|
||||
'dependencies': [ 'subdir1/executable.gyp:counter' ], |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'use_always_run_output', |
|
||||
'inputs': [ |
|
||||
'subdir1/actions-out/action-counter.txt', |
|
||||
'subdir1/counter.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'subdir1/actions-out/action-counter_2.txt', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', 'subdir1/counter.py', '<(_outputs)', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
|
|
||||
# Three deps which don't finish immediately. |
|
||||
# Each one has a small delay then creates a file. |
|
||||
# Delays are 1.0, 1.1, and 2.0 seconds. |
|
||||
{ |
|
||||
'target_name': 'dep_1', |
|
||||
'type': 'none', |
|
||||
'actions': [{ |
|
||||
'inputs': [ 'actions.gyp' ], |
|
||||
'outputs': [ 'dep_1.txt' ], |
|
||||
'action_name': 'dep_1', |
|
||||
'action': [ 'python', '-c', |
|
||||
'import time; time.sleep(1); open(\'dep_1.txt\', \'w\')' ], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'dep_2', |
|
||||
'type': 'none', |
|
||||
'actions': [{ |
|
||||
'inputs': [ 'actions.gyp' ], |
|
||||
'outputs': [ 'dep_2.txt' ], |
|
||||
'action_name': 'dep_2', |
|
||||
'action': [ 'python', '-c', |
|
||||
'import time; time.sleep(1.1); open(\'dep_2.txt\', \'w\')' ], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'dep_3', |
|
||||
'type': 'none', |
|
||||
'actions': [{ |
|
||||
'inputs': [ 'actions.gyp' ], |
|
||||
'outputs': [ 'dep_3.txt' ], |
|
||||
'action_name': 'dep_3', |
|
||||
'action': [ 'python', '-c', |
|
||||
'import time; time.sleep(2.0); open(\'dep_3.txt\', \'w\')' ], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}], |
|
||||
}, |
|
||||
|
|
||||
# An action which assumes the deps have completed. |
|
||||
# Does NOT list the output files of it's deps as inputs. |
|
||||
# On success create the file deps_all_done_first.txt. |
|
||||
{ |
|
||||
'target_name': 'action_with_dependencies_123', |
|
||||
'type': 'none', |
|
||||
'dependencies': [ 'dep_1', 'dep_2', 'dep_3' ], |
|
||||
'actions': [{ |
|
||||
'inputs': [ 'actions.gyp' ], |
|
||||
'outputs': [ 'deps_all_done_first_123.txt' ], |
|
||||
'action_name': 'action_with_dependencies_123', |
|
||||
'action': [ 'python', 'confirm-dep-files.py', '<(_outputs)' ], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}], |
|
||||
}, |
|
||||
# Same as above but with deps in reverse. |
|
||||
{ |
|
||||
'target_name': 'action_with_dependencies_321', |
|
||||
'type': 'none', |
|
||||
'dependencies': [ 'dep_3', 'dep_2', 'dep_1' ], |
|
||||
'actions': [{ |
|
||||
'inputs': [ 'actions.gyp' ], |
|
||||
'outputs': [ 'deps_all_done_first_321.txt' ], |
|
||||
'action_name': 'action_with_dependencies_321', |
|
||||
'action': [ 'python', 'confirm-dep-files.py', '<(_outputs)' ], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}], |
|
||||
}, |
|
||||
|
|
||||
], |
|
||||
} |
|
@ -1,21 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2011 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
"""Confirms presence of files generated by our targets we depend on. |
|
||||
If they exist, create a new file. |
|
||||
|
|
||||
Note target's input files are explicitly NOT defined in the gyp file |
|
||||
so they can't easily be passed to this script as args. |
|
||||
""" |
|
||||
|
|
||||
import os |
|
||||
import sys |
|
||||
|
|
||||
outfile = sys.argv[1] # Example value we expect: deps_all_done_first_123.txt |
|
||||
if (os.path.exists("dep_1.txt") and |
|
||||
os.path.exists("dep_2.txt") and |
|
||||
os.path.exists("dep_3.txt")): |
|
||||
open(outfile, "w") |
|
@ -1,46 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2010 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
import time |
|
||||
|
|
||||
output = sys.argv[1] |
|
||||
persistoutput = "%s.persist" % sys.argv[1] |
|
||||
|
|
||||
count = 0 |
|
||||
try: |
|
||||
count = open(persistoutput, 'r').read() |
|
||||
except: |
|
||||
pass |
|
||||
count = int(count) + 1 |
|
||||
|
|
||||
if len(sys.argv) > 2: |
|
||||
max_count = int(sys.argv[2]) |
|
||||
if count > max_count: |
|
||||
count = max_count |
|
||||
|
|
||||
oldcount = 0 |
|
||||
try: |
|
||||
oldcount = open(output, 'r').read() |
|
||||
except: |
|
||||
pass |
|
||||
|
|
||||
# Save the count in a file that is undeclared, and thus hidden, to gyp. We need |
|
||||
# to do this because, prior to running commands, scons deletes any declared |
|
||||
# outputs, so we would lose our count if we just wrote to the given output file. |
|
||||
# (The other option is to use Precious() in the scons generator, but that seems |
|
||||
# too heavy-handed just to support this somewhat unrealistic test case, and |
|
||||
# might lead to unintended side-effects). |
|
||||
open(persistoutput, 'w').write('%d' % (count)) |
|
||||
|
|
||||
# Only write the given output file if the count has changed. |
|
||||
if int(oldcount) != count: |
|
||||
open(output, 'w').write('%d' % (count)) |
|
||||
# Sleep so the next run changes the file time sufficiently to make the build |
|
||||
# detect the file as changed. |
|
||||
time.sleep(1) |
|
||||
|
|
||||
sys.exit(0) |
|
@ -1,74 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'program', |
|
||||
'type': 'executable', |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
'sources': [ |
|
||||
'program.c', |
|
||||
], |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'make-prog1', |
|
||||
'inputs': [ |
|
||||
'make-prog1.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/prog1.c', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<(_inputs)', '<@(_outputs)', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
}, |
|
||||
{ |
|
||||
'action_name': 'make-prog2', |
|
||||
'inputs': [ |
|
||||
'make-prog2.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'actions-out/prog2.c', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<(_inputs)', '<@(_outputs)', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'counter', |
|
||||
'type': 'none', |
|
||||
'actions': [ |
|
||||
{ |
|
||||
# This action should always run, regardless of whether or not it's |
|
||||
# inputs or the command-line change. We do this by creating a dummy |
|
||||
# first output, which is always missing, thus causing the build to |
|
||||
# always try to recreate it. Actual output files should be listed |
|
||||
# after the dummy one, and dependent targets should list the real |
|
||||
# output(s) in their inputs |
|
||||
# (see '../actions.gyp:depend_on_always_run_action'). |
|
||||
'action_name': 'action_counter', |
|
||||
'inputs': [ |
|
||||
'counter.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'actions-out/action-counter.txt.always', |
|
||||
'actions-out/action-counter.txt', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<(_inputs)', 'actions-out/action-counter.txt', '2', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,20 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
contents = r""" |
|
||||
#include <stdio.h> |
|
||||
|
|
||||
void prog1(void) |
|
||||
{ |
|
||||
printf("Hello from make-prog1.py\n"); |
|
||||
} |
|
||||
""" |
|
||||
|
|
||||
open(sys.argv[1], 'w').write(contents) |
|
||||
|
|
||||
sys.exit(0) |
|
@ -1,20 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
contents = r""" |
|
||||
#include <stdio.h> |
|
||||
|
|
||||
void prog2(void) |
|
||||
{ |
|
||||
printf("Hello from make-prog2.py\n"); |
|
||||
} |
|
||||
""" |
|
||||
|
|
||||
open(sys.argv[1], 'w').write(contents) |
|
||||
|
|
||||
sys.exit(0) |
|
@ -1,12 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern void prog1(void); |
|
||||
extern void prog2(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from program.c\n"); |
|
||||
prog1(); |
|
||||
prog2(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,11 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
contents = "Hello from make-file.py\n" |
|
||||
|
|
||||
open(sys.argv[1], 'wb').write(contents) |
|
@ -1,33 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'file', |
|
||||
'type': 'none', |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'make-file', |
|
||||
'inputs': [ |
|
||||
'make-file.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'file.out', |
|
||||
# TODO: enhance testing infrastructure to test this |
|
||||
# without having to hard-code the intermediate dir paths. |
|
||||
#'<(INTERMEDIATE_DIR)/file.out', |
|
||||
], |
|
||||
'action': [ |
|
||||
'python', '<(_inputs)', '<@(_outputs)', |
|
||||
], |
|
||||
'process_outputs_as_sources': 1, |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
} |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,21 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
contents = """ |
|
||||
#include <stdio.h> |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from generate_main.py\\n"); |
|
||||
return 0; |
|
||||
} |
|
||||
""" |
|
||||
|
|
||||
open(sys.argv[1], 'w').write(contents) |
|
||||
|
|
||||
sys.exit(0) |
|
@ -1,29 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'null_input', |
|
||||
'type': 'executable', |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'generate_main', |
|
||||
'process_outputs_as_sources': 1, |
|
||||
'inputs': [], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/main.c', |
|
||||
], |
|
||||
'action': [ |
|
||||
# TODO: we can't just use <(_outputs) here?! |
|
||||
'python', 'generate_main.py', '<(INTERMEDIATE_DIR)/main.c', |
|
||||
], |
|
||||
# Allows the test to run without hermetic cygwin on windows. |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,55 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies simple actions when using an explicit build target of 'all'. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp() |
|
||||
|
|
||||
test.run_gyp('all.gyp', chdir='src') |
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
# Build all. |
|
||||
test.build('all.gyp', chdir='relocate/src') |
|
||||
|
|
||||
if test.format=='xcode': |
|
||||
chdir = 'relocate/src/dir1' |
|
||||
else: |
|
||||
chdir = 'relocate/src' |
|
||||
|
|
||||
# Output is as expected. |
|
||||
file_content = 'Hello from emit.py\n' |
|
||||
test.built_file_must_match('out2.txt', file_content, chdir=chdir) |
|
||||
|
|
||||
test.built_file_must_not_exist('out.txt', chdir='relocate/src') |
|
||||
test.built_file_must_not_exist('foolib1', |
|
||||
type=test.SHARED_LIB, |
|
||||
chdir=chdir) |
|
||||
|
|
||||
# TODO(mmoss) Make consistent with scons, with 'dir1' before 'out/Default'? |
|
||||
if test.format in ('make', 'ninja'): |
|
||||
chdir='relocate/src' |
|
||||
else: |
|
||||
chdir='relocate/src/dir1' |
|
||||
|
|
||||
# Build the action explicitly. |
|
||||
test.build('actions.gyp', 'action1_target', chdir=chdir) |
|
||||
|
|
||||
# Check that things got run. |
|
||||
file_content = 'Hello from emit.py\n' |
|
||||
test.built_file_must_exist('out.txt', chdir=chdir) |
|
||||
|
|
||||
# Build the shared library explicitly. |
|
||||
test.build('actions.gyp', 'foolib1', chdir=chdir) |
|
||||
|
|
||||
test.built_file_must_exist('foolib1', |
|
||||
type=test.SHARED_LIB, |
|
||||
chdir=chdir) |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,13 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'all_targets', |
|
||||
'type': 'none', |
|
||||
'dependencies': ['dir1/actions.gyp:*'], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,56 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'action1_target', |
|
||||
'type': 'none', |
|
||||
'suppress_wildcard': 1, |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'action1', |
|
||||
'inputs': [ |
|
||||
'emit.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(PRODUCT_DIR)/out.txt', |
|
||||
], |
|
||||
'action': ['python', 'emit.py', '<(PRODUCT_DIR)/out.txt'], |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'action2_target', |
|
||||
'type': 'none', |
|
||||
'actions': [ |
|
||||
{ |
|
||||
'action_name': 'action2', |
|
||||
'inputs': [ |
|
||||
'emit.py', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(PRODUCT_DIR)/out2.txt', |
|
||||
], |
|
||||
'action': ['python', 'emit.py', '<(PRODUCT_DIR)/out2.txt'], |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'foolib1', |
|
||||
'type': 'shared_library', |
|
||||
'suppress_wildcard': 1, |
|
||||
'sources': ['lib1.c'], |
|
||||
}, |
|
||||
], |
|
||||
'conditions': [ |
|
||||
['OS=="linux"', { |
|
||||
'target_defaults': { |
|
||||
'cflags': ['-fPIC'], |
|
||||
}, |
|
||||
}], |
|
||||
], |
|
||||
} |
|
@ -1,11 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
import sys |
|
||||
|
|
||||
f = open(sys.argv[1], 'wb') |
|
||||
f.write('Hello from emit.py\n') |
|
||||
f.close() |
|
@ -1,6 +0,0 @@ |
|||||
#ifdef _WIN32 |
|
||||
__declspec(dllexport) |
|
||||
#endif |
|
||||
int func1(void) { |
|
||||
return 42; |
|
||||
} |
|
@ -1,31 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies that .hpp files are ignored when included in the source list on all |
|
||||
platforms. |
|
||||
""" |
|
||||
|
|
||||
import sys |
|
||||
import TestGyp |
|
||||
|
|
||||
# TODO(bradnelson): get this working for windows. |
|
||||
test = TestGyp.TestGyp(formats=['make', 'ninja', 'scons', 'xcode']) |
|
||||
|
|
||||
test.run_gyp('assembly.gyp', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
test.build('assembly.gyp', test.ALL, chdir='relocate/src') |
|
||||
|
|
||||
expect = """\ |
|
||||
Hello from program.c |
|
||||
Got 42. |
|
||||
""" |
|
||||
test.run_built_executable('program', chdir='relocate/src', stdout=expect) |
|
||||
|
|
||||
|
|
||||
test.pass_test() |
|
@ -1,4 +0,0 @@ |
|||||
@echo off |
|
||||
:: Mock windows assembler. |
|
||||
cl /c %1 /Fo"%2" |
|
||||
|
|
@ -1,59 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'target_defaults': { |
|
||||
'conditions': [ |
|
||||
['OS=="win"', { |
|
||||
'defines': ['PLATFORM_WIN'], |
|
||||
}], |
|
||||
['OS=="mac"', { |
|
||||
'defines': ['PLATFORM_MAC'], |
|
||||
}], |
|
||||
['OS=="linux"', { |
|
||||
'defines': ['PLATFORM_LINUX'], |
|
||||
}], |
|
||||
], |
|
||||
}, |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'program', |
|
||||
'type': 'executable', |
|
||||
'dependencies': ['lib1'], |
|
||||
'sources': [ |
|
||||
'program.c', |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'lib1', |
|
||||
'type': 'static_library', |
|
||||
'sources': [ |
|
||||
'lib1.S', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
'conditions': [ |
|
||||
['OS=="win"', { |
|
||||
'target_defaults': { |
|
||||
'rules': [ |
|
||||
{ |
|
||||
'rule_name': 'assembler', |
|
||||
'msvs_cygwin_shell': 0, |
|
||||
'extension': 'S', |
|
||||
'inputs': [ |
|
||||
'as.bat', |
|
||||
], |
|
||||
'outputs': [ |
|
||||
'<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj', |
|
||||
], |
|
||||
'action': |
|
||||
['as.bat', 'lib1.c', '<(_outputs)'], |
|
||||
'message': 'Building assembly file <(RULE_INPUT_PATH)', |
|
||||
'process_outputs_as_sources': 1, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
},], |
|
||||
], |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
#if PLATFORM_WINDOWS || PLATFORM_MAC |
|
||||
# define IDENTIFIER(n) _##n |
|
||||
#else /* Linux */ |
|
||||
# define IDENTIFIER(n) n |
|
||||
#endif |
|
||||
|
|
||||
.globl IDENTIFIER(lib1_function) |
|
||||
IDENTIFIER(lib1_function): |
|
||||
movl $42, %eax |
|
||||
ret |
|
@ -1,3 +0,0 @@ |
|||||
int lib1_function(void) { |
|
||||
return 42; |
|
||||
} |
|
@ -1,12 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern int lib1_function(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
fprintf(stdout, "Hello from program.c\n"); |
|
||||
fflush(stdout); |
|
||||
fprintf(stdout, "Got %d.\n", lib1_function()); |
|
||||
fflush(stdout); |
|
||||
return 0; |
|
||||
} |
|
@ -1,77 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verify the settings that cause a set of programs to be created in |
|
||||
a specific build directory, and that no intermediate built files |
|
||||
get created outside of that build directory hierarchy even when |
|
||||
referred to with deeply-nested ../../.. paths. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
# TODO(mmoss): Make only supports (theoretically) a single, global build |
|
||||
# directory (through GYP_GENERATOR_FLAGS 'output_dir'), rather than |
|
||||
# gyp-file-specific settings (e.g. the stuff in builddir.gypi) that the other |
|
||||
# generators support, so this doesn't work yet for make. |
|
||||
# TODO(mmoss) Make also has the issue that the top-level Makefile is written to |
|
||||
# the "--depth" location, which is one level above 'src', but then this test |
|
||||
# moves 'src' somewhere else, leaving the Makefile behind, so make can't find |
|
||||
# its sources. I'm not sure if make is wrong for writing outside the current |
|
||||
# directory, or if the test is wrong for assuming everything generated is under |
|
||||
# the current directory. |
|
||||
test = TestGyp.TestGyp(formats=['!make', '!ninja']) |
|
||||
|
|
||||
test.run_gyp('prog1.gyp', '--depth=..', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
test.subdir('relocate/builddir') |
|
||||
|
|
||||
# Make sure that all the built ../../etc. files only get put under builddir, |
|
||||
# by making all of relocate read-only and then making only builddir writable. |
|
||||
test.writable('relocate', False) |
|
||||
test.writable('relocate/builddir', True) |
|
||||
|
|
||||
# Suppress the test infrastructure's setting SYMROOT on the command line. |
|
||||
test.build('prog1.gyp', test.ALL, SYMROOT=None, chdir='relocate/src') |
|
||||
|
|
||||
expect1 = """\ |
|
||||
Hello from prog1.c |
|
||||
Hello from func1.c |
|
||||
""" |
|
||||
|
|
||||
expect2 = """\ |
|
||||
Hello from subdir2/prog2.c |
|
||||
Hello from func2.c |
|
||||
""" |
|
||||
|
|
||||
expect3 = """\ |
|
||||
Hello from subdir2/subdir3/prog3.c |
|
||||
Hello from func3.c |
|
||||
""" |
|
||||
|
|
||||
expect4 = """\ |
|
||||
Hello from subdir2/subdir3/subdir4/prog4.c |
|
||||
Hello from func4.c |
|
||||
""" |
|
||||
|
|
||||
expect5 = """\ |
|
||||
Hello from subdir2/subdir3/subdir4/subdir5/prog5.c |
|
||||
Hello from func5.c |
|
||||
""" |
|
||||
|
|
||||
def run_builddir(prog, expect): |
|
||||
dir = 'relocate/builddir/Default/' |
|
||||
test.run(program=test.workpath(dir + prog), stdout=expect) |
|
||||
|
|
||||
run_builddir('prog1', expect1) |
|
||||
run_builddir('prog2', expect2) |
|
||||
run_builddir('prog3', expect3) |
|
||||
run_builddir('prog4', expect4) |
|
||||
run_builddir('prog5', expect5) |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,77 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verify the settings that cause a set of programs to be created in |
|
||||
a specific build directory, and that no intermediate built files |
|
||||
get created outside of that build directory hierarchy even when |
|
||||
referred to with deeply-nested ../../.. paths. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
# TODO(mmoss): Make only supports (theoretically) a single, global build |
|
||||
# directory (through GYP_GENERATOR_FLAGS 'output_dir'), rather than |
|
||||
# gyp-file-specific settings (e.g. the stuff in builddir.gypi) that the other |
|
||||
# generators support, so this doesn't work yet for make. |
|
||||
# TODO(mmoss) Make also has the issue that the top-level Makefile is written to |
|
||||
# the "--depth" location, which is one level above 'src', but then this test |
|
||||
# moves 'src' somewhere else, leaving the Makefile behind, so make can't find |
|
||||
# its sources. I'm not sure if make is wrong for writing outside the current |
|
||||
# directory, or if the test is wrong for assuming everything generated is under |
|
||||
# the current directory. |
|
||||
test = TestGyp.TestGyp(formats=['!make', '!ninja']) |
|
||||
|
|
||||
test.run_gyp('prog1.gyp', '--depth=..', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
test.subdir('relocate/builddir') |
|
||||
|
|
||||
# Make sure that all the built ../../etc. files only get put under builddir, |
|
||||
# by making all of relocate read-only and then making only builddir writable. |
|
||||
test.writable('relocate', False) |
|
||||
test.writable('relocate/builddir', True) |
|
||||
|
|
||||
# Suppress the test infrastructure's setting SYMROOT on the command line. |
|
||||
test.build('prog1.gyp', SYMROOT=None, chdir='relocate/src') |
|
||||
|
|
||||
expect1 = """\ |
|
||||
Hello from prog1.c |
|
||||
Hello from func1.c |
|
||||
""" |
|
||||
|
|
||||
expect2 = """\ |
|
||||
Hello from subdir2/prog2.c |
|
||||
Hello from func2.c |
|
||||
""" |
|
||||
|
|
||||
expect3 = """\ |
|
||||
Hello from subdir2/subdir3/prog3.c |
|
||||
Hello from func3.c |
|
||||
""" |
|
||||
|
|
||||
expect4 = """\ |
|
||||
Hello from subdir2/subdir3/subdir4/prog4.c |
|
||||
Hello from func4.c |
|
||||
""" |
|
||||
|
|
||||
expect5 = """\ |
|
||||
Hello from subdir2/subdir3/subdir4/subdir5/prog5.c |
|
||||
Hello from func5.c |
|
||||
""" |
|
||||
|
|
||||
def run_builddir(prog, expect): |
|
||||
dir = 'relocate/builddir/Default/' |
|
||||
test.run(program=test.workpath(dir + prog), stdout=expect) |
|
||||
|
|
||||
run_builddir('prog1', expect1) |
|
||||
run_builddir('prog2', expect2) |
|
||||
run_builddir('prog3', expect3) |
|
||||
run_builddir('prog4', expect4) |
|
||||
run_builddir('prog5', expect5) |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,21 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'target_defaults': { |
|
||||
'configurations': { |
|
||||
'Default': { |
|
||||
'msvs_configuration_attributes': { |
|
||||
'OutputDirectory': '<(DEPTH)\\builddir\Default', |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
'scons_settings': { |
|
||||
'sconsbuild_dir': '<(DEPTH)/builddir', |
|
||||
}, |
|
||||
'xcode_settings': { |
|
||||
'SYMROOT': '<(DEPTH)/builddir', |
|
||||
}, |
|
||||
} |
|
@ -1,6 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
void func1(void) |
|
||||
{ |
|
||||
printf("Hello from func1.c\n"); |
|
||||
} |
|
@ -1,6 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
void func2(void) |
|
||||
{ |
|
||||
printf("Hello from func2.c\n"); |
|
||||
} |
|
@ -1,6 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
void func3(void) |
|
||||
{ |
|
||||
printf("Hello from func3.c\n"); |
|
||||
} |
|
@ -1,6 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
void func4(void) |
|
||||
{ |
|
||||
printf("Hello from func4.c\n"); |
|
||||
} |
|
@ -1,6 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
void func5(void) |
|
||||
{ |
|
||||
printf("Hello from func5.c\n"); |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern void func1(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from prog1.c\n"); |
|
||||
func1(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,30 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'includes': [ |
|
||||
'builddir.gypi', |
|
||||
], |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'pull_in_all', |
|
||||
'type': 'none', |
|
||||
'dependencies': [ |
|
||||
'prog1', |
|
||||
'subdir2/prog2.gyp:prog2', |
|
||||
'subdir2/subdir3/prog3.gyp:prog3', |
|
||||
'subdir2/subdir3/subdir4/prog4.gyp:prog4', |
|
||||
'subdir2/subdir3/subdir4/subdir5/prog5.gyp:prog5', |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'prog1', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'prog1.c', |
|
||||
'func1.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern void func2(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from subdir2/prog2.c\n"); |
|
||||
func2(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,19 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'includes': [ |
|
||||
'../builddir.gypi', |
|
||||
], |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'prog2', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'prog2.c', |
|
||||
'../func2.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern void func3(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from subdir2/subdir3/prog3.c\n"); |
|
||||
func3(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,19 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'includes': [ |
|
||||
'../../builddir.gypi', |
|
||||
], |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'prog3', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'prog3.c', |
|
||||
'../../func3.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern void func4(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from subdir2/subdir3/subdir4/prog4.c\n"); |
|
||||
func4(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,19 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'includes': [ |
|
||||
'../../../builddir.gypi', |
|
||||
], |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'prog4', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'prog4.c', |
|
||||
'../../../func4.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
extern void func5(void); |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
printf("Hello from subdir2/subdir3/subdir4/subdir5/prog5.c\n"); |
|
||||
func5(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,19 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'includes': [ |
|
||||
'../../../../builddir.gypi', |
|
||||
], |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'prog5', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'prog5.c', |
|
||||
'../../../../func5.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,15 +0,0 @@ |
|||||
/* Copyright (c) 2010 Google Inc. All rights reserved.
|
|
||||
* Use of this source code is governed by a BSD-style license that can be |
|
||||
* found in the LICENSE file. */ |
|
||||
|
|
||||
#include <stdio.h> |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
#ifdef __OPTIMIZE__ |
|
||||
printf("Using an optimization flag\n"); |
|
||||
#else |
|
||||
printf("Using no optimization flag\n"); |
|
||||
#endif |
|
||||
return 0; |
|
||||
} |
|
@ -1,16 +0,0 @@ |
|||||
# Copyright (c) 2010 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'cflags', |
|
||||
'type': 'executable', |
|
||||
'opt': '-Os', |
|
||||
'sources': [ |
|
||||
'cflags.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,65 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2010 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies build of an executable with C++ define specified by a gyp define, and |
|
||||
the use of the environment during regeneration when the gyp file changes. |
|
||||
""" |
|
||||
|
|
||||
import os |
|
||||
import TestGyp |
|
||||
|
|
||||
env_stack = [] |
|
||||
|
|
||||
|
|
||||
def PushEnv(): |
|
||||
env_copy = os.environ.copy() |
|
||||
env_stack.append(env_copy) |
|
||||
|
|
||||
def PopEnv(): |
|
||||
os.eniron=env_stack.pop() |
|
||||
|
|
||||
# Regenerating build files when a gyp file changes is currently only supported |
|
||||
# by the make generator. |
|
||||
test = TestGyp.TestGyp(formats=['make']) |
|
||||
|
|
||||
try: |
|
||||
PushEnv() |
|
||||
os.environ['CFLAGS'] = '-O0' |
|
||||
test.run_gyp('cflags.gyp') |
|
||||
finally: |
|
||||
# We clear the environ after calling gyp. When the auto-regeneration happens, |
|
||||
# the same define should be reused anyway. Reset to empty string first in |
|
||||
# case the platform doesn't support unsetenv. |
|
||||
PopEnv() |
|
||||
|
|
||||
test.build('cflags.gyp') |
|
||||
|
|
||||
expect = """\ |
|
||||
Using no optimization flag |
|
||||
""" |
|
||||
test.run_built_executable('cflags', stdout=expect) |
|
||||
|
|
||||
test.sleep() |
|
||||
|
|
||||
try: |
|
||||
PushEnv() |
|
||||
os.environ['CFLAGS'] = '-O2' |
|
||||
test.run_gyp('cflags.gyp') |
|
||||
finally: |
|
||||
# We clear the environ after calling gyp. When the auto-regeneration happens, |
|
||||
# the same define should be reused anyway. Reset to empty string first in |
|
||||
# case the platform doesn't support unsetenv. |
|
||||
PopEnv() |
|
||||
|
|
||||
test.build('cflags.gyp') |
|
||||
|
|
||||
expect = """\ |
|
||||
Using an optimization flag |
|
||||
""" |
|
||||
test.run_built_executable('cflags', stdout=expect) |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,29 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies that .hpp files are ignored when included in the source list on all |
|
||||
platforms. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp() |
|
||||
|
|
||||
test.run_gyp('headers.gyp', chdir='src') |
|
||||
|
|
||||
test.relocate('src', 'relocate/src') |
|
||||
|
|
||||
test.build('headers.gyp', test.ALL, chdir='relocate/src') |
|
||||
|
|
||||
expect = """\ |
|
||||
Hello from program.c |
|
||||
Hello from lib1.c |
|
||||
""" |
|
||||
test.run_built_executable('program', chdir='relocate/src', stdout=expect) |
|
||||
|
|
||||
|
|
||||
test.pass_test() |
|
@ -1,26 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'program', |
|
||||
'type': 'executable', |
|
||||
'dependencies': [ |
|
||||
'lib1' |
|
||||
], |
|
||||
'sources': [ |
|
||||
'program.cpp', |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
'target_name': 'lib1', |
|
||||
'type': 'static_library', |
|
||||
'sources': [ |
|
||||
'lib1.hpp', |
|
||||
'lib1.cpp', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,7 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
#include "lib1.hpp" |
|
||||
|
|
||||
void lib1_function(void) { |
|
||||
fprintf(stdout, "Hello from lib1.c\n"); |
|
||||
fflush(stdout); |
|
||||
} |
|
@ -1,6 +0,0 @@ |
|||||
#ifndef _lib1_hpp |
|
||||
#define _lib1_hpp |
|
||||
|
|
||||
extern void lib1_function(void); |
|
||||
|
|
||||
#endif |
|
@ -1,9 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
#include "lib1.hpp" |
|
||||
|
|
||||
int main(int argc, char *argv[]) { |
|
||||
fprintf(stdout, "Hello from program.c\n"); |
|
||||
fflush(stdout); |
|
||||
lib1_function(); |
|
||||
return 0; |
|
||||
} |
|
@ -1,15 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
#ifdef FOO |
|
||||
printf("Foo configuration\n"); |
|
||||
#endif |
|
||||
#ifdef DEBUG |
|
||||
printf("Debug configuration\n"); |
|
||||
#endif |
|
||||
#ifdef RELEASE |
|
||||
printf("Release configuration\n"); |
|
||||
#endif |
|
||||
return 0; |
|
||||
} |
|
@ -1,32 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'configurations', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'configurations.c', |
|
||||
], |
|
||||
'configurations': { |
|
||||
'Debug': { |
|
||||
'defines': [ |
|
||||
'DEBUG', |
|
||||
], |
|
||||
}, |
|
||||
'Release': { |
|
||||
'defines': [ |
|
||||
'RELEASE', |
|
||||
], |
|
||||
}, |
|
||||
'Foo': { |
|
||||
'defines': [ |
|
||||
'FOO', |
|
||||
], |
|
||||
}, |
|
||||
} |
|
||||
}, |
|
||||
], |
|
||||
} |
|
@ -1,29 +0,0 @@ |
|||||
#!/usr/bin/env python |
|
||||
|
|
||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
""" |
|
||||
Verifies build of an executable in three different configurations. |
|
||||
""" |
|
||||
|
|
||||
import TestGyp |
|
||||
|
|
||||
test = TestGyp.TestGyp() |
|
||||
|
|
||||
test.run_gyp('configurations.gyp') |
|
||||
|
|
||||
test.set_configuration('Release') |
|
||||
test.build('configurations.gyp') |
|
||||
test.run_built_executable('configurations', stdout="Release configuration\n") |
|
||||
|
|
||||
test.set_configuration('Debug') |
|
||||
test.build('configurations.gyp') |
|
||||
test.run_built_executable('configurations', stdout="Debug configuration\n") |
|
||||
|
|
||||
test.set_configuration('Foo') |
|
||||
test.build('configurations.gyp') |
|
||||
test.run_built_executable('configurations', stdout="Foo configuration\n") |
|
||||
|
|
||||
test.pass_test() |
|
@ -1,21 +0,0 @@ |
|||||
#include <stdio.h> |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
#ifdef BASE |
|
||||
printf("Base configuration\n"); |
|
||||
#endif |
|
||||
#ifdef COMMON |
|
||||
printf("Common configuration\n"); |
|
||||
#endif |
|
||||
#ifdef COMMON2 |
|
||||
printf("Common2 configuration\n"); |
|
||||
#endif |
|
||||
#ifdef DEBUG |
|
||||
printf("Debug configuration\n"); |
|
||||
#endif |
|
||||
#ifdef RELEASE |
|
||||
printf("Release configuration\n"); |
|
||||
#endif |
|
||||
return 0; |
|
||||
} |
|
@ -1,40 +0,0 @@ |
|||||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|
||||
# Use of this source code is governed by a BSD-style license that can be |
|
||||
# found in the LICENSE file. |
|
||||
|
|
||||
{ |
|
||||
'target_defaults': { |
|
||||
'configurations': { |
|
||||
'Base': { |
|
||||
'abstract': 1, |
|
||||
'defines': ['BASE'], |
|
||||
}, |
|
||||
'Common': { |
|
||||
'abstract': 1, |
|
||||
'inherit_from': ['Base'], |
|
||||
'defines': ['COMMON'], |
|
||||
}, |
|
||||
'Common2': { |
|
||||
'abstract': 1, |
|
||||
'defines': ['COMMON2'], |
|
||||
}, |
|
||||
'Debug': { |
|
||||
'inherit_from': ['Common', 'Common2'], |
|
||||
'defines': ['DEBUG'], |
|
||||
}, |
|
||||
'Release': { |
|
||||
'inherit_from': ['Common', 'Common2'], |
|
||||
'defines': ['RELEASE'], |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
'targets': [ |
|
||||
{ |
|
||||
'target_name': 'configurations', |
|
||||
'type': 'executable', |
|
||||
'sources': [ |
|
||||
'configurations.c', |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
} |
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue