mirror of https://github.com/lukechilds/node.git
Timothy J Fontaine
11 years ago
40 changed files with 2225 additions and 2139 deletions
@ -1,21 +0,0 @@ |
|||
setup.py |
|||
gyp |
|||
LICENSE |
|||
AUTHORS |
|||
pylib/gyp/MSVSNew.py |
|||
pylib/gyp/MSVSProject.py |
|||
pylib/gyp/MSVSToolFile.py |
|||
pylib/gyp/MSVSUserFile.py |
|||
pylib/gyp/MSVSVersion.py |
|||
pylib/gyp/SCons.py |
|||
pylib/gyp/__init__.py |
|||
pylib/gyp/common.py |
|||
pylib/gyp/input.py |
|||
pylib/gyp/xcodeproj_file.py |
|||
pylib/gyp/generator/__init__.py |
|||
pylib/gyp/generator/gypd.py |
|||
pylib/gyp/generator/gypsh.py |
|||
pylib/gyp/generator/make.py |
|||
pylib/gyp/generator/msvs.py |
|||
pylib/gyp/generator/scons.py |
|||
pylib/gyp/generator/xcode.py |
@ -0,0 +1,148 @@ |
|||
#!/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. |
|||
|
|||
|
|||
"""Argument-less script to select what to run on the buildbots.""" |
|||
|
|||
|
|||
import os |
|||
import shutil |
|||
import subprocess |
|||
import sys |
|||
|
|||
|
|||
if sys.platform in ['win32', 'cygwin']: |
|||
EXE_SUFFIX = '.exe' |
|||
else: |
|||
EXE_SUFFIX = '' |
|||
|
|||
|
|||
BUILDBOT_DIR = os.path.dirname(os.path.abspath(__file__)) |
|||
TRUNK_DIR = os.path.dirname(BUILDBOT_DIR) |
|||
ROOT_DIR = os.path.dirname(TRUNK_DIR) |
|||
ANDROID_DIR = os.path.join(ROOT_DIR, 'android') |
|||
OUT_DIR = os.path.join(TRUNK_DIR, 'out') |
|||
|
|||
|
|||
def CallSubProcess(*args, **kwargs): |
|||
"""Wrapper around subprocess.call which treats errors as build exceptions.""" |
|||
retcode = subprocess.call(*args, **kwargs) |
|||
if retcode != 0: |
|||
print '@@@STEP_EXCEPTION@@@' |
|||
sys.exit(1) |
|||
|
|||
|
|||
def PrepareAndroidTree(): |
|||
"""Prepare an Android tree to run 'android' format tests.""" |
|||
if os.environ['BUILDBOT_CLOBBER'] == '1': |
|||
print '@@@BUILD_STEP Clobber Android checkout@@@' |
|||
shutil.rmtree(ANDROID_DIR) |
|||
|
|||
# The release of Android we use is static, so there's no need to do anything |
|||
# if the directory already exists. |
|||
if os.path.isdir(ANDROID_DIR): |
|||
return |
|||
|
|||
print '@@@BUILD_STEP Initialize Android checkout@@@' |
|||
os.mkdir(ANDROID_DIR) |
|||
CallSubProcess(['git', 'config', '--global', 'user.name', 'trybot']) |
|||
CallSubProcess(['git', 'config', '--global', |
|||
'user.email', 'chrome-bot@google.com']) |
|||
CallSubProcess(['git', 'config', '--global', 'color.ui', 'false']) |
|||
CallSubProcess( |
|||
['repo', 'init', |
|||
'-u', 'https://android.googlesource.com/platform/manifest', |
|||
'-b', 'android-4.2.1_r1', |
|||
'-g', 'all,-notdefault,-device,-darwin,-mips,-x86'], |
|||
cwd=ANDROID_DIR) |
|||
|
|||
print '@@@BUILD_STEP Sync Android@@@' |
|||
CallSubProcess(['repo', 'sync', '-j4'], cwd=ANDROID_DIR) |
|||
|
|||
print '@@@BUILD_STEP Build Android@@@' |
|||
CallSubProcess( |
|||
['/bin/bash', |
|||
'-c', 'source build/envsetup.sh && lunch full-eng && make -j4'], |
|||
cwd=ANDROID_DIR) |
|||
|
|||
|
|||
def GypTestFormat(title, format=None, msvs_version=None): |
|||
"""Run the gyp tests for a given format, emitting annotator tags. |
|||
|
|||
See annotator docs at: |
|||
https://sites.google.com/a/chromium.org/dev/developers/testing/chromium-build-infrastructure/buildbot-annotations |
|||
Args: |
|||
format: gyp format to test. |
|||
Returns: |
|||
0 for sucesss, 1 for failure. |
|||
""" |
|||
if not format: |
|||
format = title |
|||
|
|||
print '@@@BUILD_STEP ' + title + '@@@' |
|||
sys.stdout.flush() |
|||
env = os.environ.copy() |
|||
if msvs_version: |
|||
env['GYP_MSVS_VERSION'] = msvs_version |
|||
command = ' '.join( |
|||
[sys.executable, 'trunk/gyptest.py', |
|||
'--all', |
|||
'--passed', |
|||
'--format', format, |
|||
'--chdir', 'trunk']) |
|||
if format == 'android': |
|||
# gyptest needs the environment setup from envsetup/lunch in order to build |
|||
# using the 'android' backend, so this is done in a single shell. |
|||
retcode = subprocess.call( |
|||
['/bin/bash', |
|||
'-c', 'source build/envsetup.sh && lunch full-eng && cd %s && %s' |
|||
% (ROOT_DIR, command)], |
|||
cwd=ANDROID_DIR, env=env) |
|||
else: |
|||
retcode = subprocess.call(command, cwd=ROOT_DIR, env=env, shell=True) |
|||
if retcode: |
|||
# Emit failure tag, and keep going. |
|||
print '@@@STEP_FAILURE@@@' |
|||
return 1 |
|||
return 0 |
|||
|
|||
|
|||
def GypBuild(): |
|||
# Dump out/ directory. |
|||
print '@@@BUILD_STEP cleanup@@@' |
|||
print 'Removing %s...' % OUT_DIR |
|||
shutil.rmtree(OUT_DIR, ignore_errors=True) |
|||
print 'Done.' |
|||
|
|||
retcode = 0 |
|||
# The Android gyp bot runs on linux so this must be tested first. |
|||
if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-android': |
|||
PrepareAndroidTree() |
|||
retcode += GypTestFormat('android') |
|||
elif sys.platform.startswith('linux'): |
|||
retcode += GypTestFormat('ninja') |
|||
retcode += GypTestFormat('make') |
|||
elif sys.platform == 'darwin': |
|||
retcode += GypTestFormat('ninja') |
|||
retcode += GypTestFormat('xcode') |
|||
retcode += GypTestFormat('make') |
|||
elif sys.platform == 'win32': |
|||
retcode += GypTestFormat('ninja') |
|||
if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-win64': |
|||
retcode += GypTestFormat('msvs-2010', format='msvs', msvs_version='2010') |
|||
retcode += GypTestFormat('msvs-2012', format='msvs', msvs_version='2012') |
|||
else: |
|||
raise Exception('Unknown platform') |
|||
if retcode: |
|||
# TODO(bradnelson): once the annotator supports a postscript (section for |
|||
# after the build proper that could be used for cumulative failures), |
|||
# use that instead of this. This isolates the final return value so |
|||
# that it isn't misattributed to the last stage. |
|||
print '@@@BUILD_STEP failures@@@' |
|||
sys.exit(retcode) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
GypBuild() |
@ -1,18 +1,7 @@ |
|||
#!/usr/bin/env python |
|||
|
|||
# Copyright (c) 2009 Google Inc. All rights reserved. |
|||
#!/bin/bash |
|||
# Copyright 2013 The Chromium Authors. 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 |
|||
|
|||
# TODO(mark): sys.path manipulation is some temporary testing stuff. |
|||
try: |
|||
import gyp |
|||
except ImportError, e: |
|||
import os.path |
|||
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), 'pylib')) |
|||
import gyp |
|||
|
|||
if __name__ == '__main__': |
|||
sys.exit(gyp.main(sys.argv[1:])) |
|||
BASE=`dirname $0` |
|||
python $BASE/gyp_main.py "$@" |
|||
|
@ -0,0 +1,18 @@ |
|||
#!/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 |
|||
|
|||
# TODO(mark): sys.path manipulation is some temporary testing stuff. |
|||
try: |
|||
import gyp |
|||
except ImportError, e: |
|||
import os.path |
|||
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), 'pylib')) |
|||
import gyp |
|||
|
|||
if __name__ == '__main__': |
|||
sys.exit(gyp.script_main()) |
@ -1,199 +0,0 @@ |
|||
# 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. |
|||
|
|||
""" |
|||
SCons generator. |
|||
|
|||
This contains class definitions and supporting functions for generating |
|||
pieces of SCons files for the different types of GYP targets. |
|||
""" |
|||
|
|||
import os |
|||
|
|||
|
|||
def WriteList(fp, list, prefix='', |
|||
separator=',\n ', |
|||
preamble=None, |
|||
postamble=None): |
|||
fp.write(preamble or '') |
|||
fp.write((separator or ' ').join([prefix + l for l in list])) |
|||
fp.write(postamble or '') |
|||
|
|||
|
|||
class TargetBase(object): |
|||
""" |
|||
Base class for a SCons representation of a GYP target. |
|||
""" |
|||
is_ignored = False |
|||
target_prefix = '' |
|||
target_suffix = '' |
|||
def __init__(self, spec): |
|||
self.spec = spec |
|||
def full_product_name(self): |
|||
""" |
|||
Returns the full name of the product being built: |
|||
|
|||
* Uses 'product_name' if it's set, else prefix + 'target_name'. |
|||
* Prepends 'product_dir' if set. |
|||
* Appends SCons suffix variables for the target type (or |
|||
product_extension). |
|||
""" |
|||
suffix = self.target_suffix |
|||
product_extension = self.spec.get('product_extension') |
|||
if product_extension: |
|||
suffix = '.' + product_extension |
|||
prefix = self.spec.get('product_prefix', self.target_prefix) |
|||
name = self.spec['target_name'] |
|||
name = prefix + self.spec.get('product_name', name) + suffix |
|||
product_dir = self.spec.get('product_dir') |
|||
if product_dir: |
|||
name = os.path.join(product_dir, name) |
|||
else: |
|||
name = os.path.join(self.out_dir, name) |
|||
return name |
|||
|
|||
def write_input_files(self, fp): |
|||
""" |
|||
Writes the definition of the input files (sources). |
|||
""" |
|||
sources = self.spec.get('sources') |
|||
if not sources: |
|||
fp.write('\ninput_files = []\n') |
|||
return |
|||
preamble = '\ninput_files = [\n ' |
|||
postamble = ',\n]\n' |
|||
WriteList(fp, map(repr, sources), preamble=preamble, postamble=postamble) |
|||
|
|||
def builder_call(self): |
|||
""" |
|||
Returns the actual SCons builder call to build this target. |
|||
""" |
|||
name = self.full_product_name() |
|||
return 'env.%s(env.File(%r), input_files)' % (self.builder_name, name) |
|||
def write_target(self, fp, src_dir='', pre=''): |
|||
""" |
|||
Writes the lines necessary to build this target. |
|||
""" |
|||
fp.write('\n' + pre) |
|||
fp.write('_outputs = %s\n' % self.builder_call()) |
|||
fp.write('target_files.extend(_outputs)\n') |
|||
|
|||
|
|||
class NoneTarget(TargetBase): |
|||
""" |
|||
A GYP target type of 'none', implicitly or explicitly. |
|||
""" |
|||
def write_target(self, fp, src_dir='', pre=''): |
|||
fp.write('\ntarget_files.extend(input_files)\n') |
|||
|
|||
|
|||
class SettingsTarget(TargetBase): |
|||
""" |
|||
A GYP target type of 'settings'. |
|||
""" |
|||
is_ignored = True |
|||
|
|||
|
|||
compilable_sources_template = """ |
|||
_result = [] |
|||
for infile in input_files: |
|||
if env.compilable(infile): |
|||
if (type(infile) == type('') |
|||
and (infile.startswith(%(src_dir)r) |
|||
or not os.path.isabs(env.subst(infile)))): |
|||
# Force files below the build directory by replacing all '..' |
|||
# elements in the path with '__': |
|||
base, ext = os.path.splitext(os.path.normpath(infile)) |
|||
base = [d == '..' and '__' or d for d in base.split('/')] |
|||
base = os.path.join(*base) |
|||
object = '${OBJ_DIR}/${COMPONENT_NAME}/${TARGET_NAME}/' + base |
|||
if not infile.startswith(%(src_dir)r): |
|||
infile = %(src_dir)r + infile |
|||
infile = env.%(name)s(object, infile)[0] |
|||
else: |
|||
infile = env.%(name)s(infile)[0] |
|||
_result.append(infile) |
|||
input_files = _result |
|||
""" |
|||
|
|||
class CompilableSourcesTargetBase(TargetBase): |
|||
""" |
|||
An abstract base class for targets that compile their source files. |
|||
|
|||
We explicitly transform compilable files into object files, |
|||
even though SCons could infer that for us, because we want |
|||
to control where the object file ends up. (The implicit rules |
|||
in SCons always put the object file next to the source file.) |
|||
""" |
|||
intermediate_builder_name = None |
|||
def write_target(self, fp, src_dir='', pre=''): |
|||
if self.intermediate_builder_name is None: |
|||
raise NotImplementedError |
|||
if src_dir and not src_dir.endswith('/'): |
|||
src_dir += '/' |
|||
variables = { |
|||
'src_dir': src_dir, |
|||
'name': self.intermediate_builder_name, |
|||
} |
|||
fp.write(compilable_sources_template % variables) |
|||
super(CompilableSourcesTargetBase, self).write_target(fp) |
|||
|
|||
|
|||
class ProgramTarget(CompilableSourcesTargetBase): |
|||
""" |
|||
A GYP target type of 'executable'. |
|||
""" |
|||
builder_name = 'GypProgram' |
|||
intermediate_builder_name = 'StaticObject' |
|||
target_prefix = '${PROGPREFIX}' |
|||
target_suffix = '${PROGSUFFIX}' |
|||
out_dir = '${TOP_BUILDDIR}' |
|||
|
|||
|
|||
class StaticLibraryTarget(CompilableSourcesTargetBase): |
|||
""" |
|||
A GYP target type of 'static_library'. |
|||
""" |
|||
builder_name = 'GypStaticLibrary' |
|||
intermediate_builder_name = 'StaticObject' |
|||
target_prefix = '${LIBPREFIX}' |
|||
target_suffix = '${LIBSUFFIX}' |
|||
out_dir = '${LIB_DIR}' |
|||
|
|||
|
|||
class SharedLibraryTarget(CompilableSourcesTargetBase): |
|||
""" |
|||
A GYP target type of 'shared_library'. |
|||
""" |
|||
builder_name = 'GypSharedLibrary' |
|||
intermediate_builder_name = 'SharedObject' |
|||
target_prefix = '${SHLIBPREFIX}' |
|||
target_suffix = '${SHLIBSUFFIX}' |
|||
out_dir = '${LIB_DIR}' |
|||
|
|||
|
|||
class LoadableModuleTarget(CompilableSourcesTargetBase): |
|||
""" |
|||
A GYP target type of 'loadable_module'. |
|||
""" |
|||
builder_name = 'GypLoadableModule' |
|||
intermediate_builder_name = 'SharedObject' |
|||
target_prefix = '${SHLIBPREFIX}' |
|||
target_suffix = '${SHLIBSUFFIX}' |
|||
out_dir = '${TOP_BUILDDIR}' |
|||
|
|||
|
|||
TargetMap = { |
|||
None : NoneTarget, |
|||
'none' : NoneTarget, |
|||
'settings' : SettingsTarget, |
|||
'executable' : ProgramTarget, |
|||
'static_library' : StaticLibraryTarget, |
|||
'shared_library' : SharedLibraryTarget, |
|||
'loadable_module' : LoadableModuleTarget, |
|||
} |
|||
|
|||
|
|||
def Target(spec): |
|||
return TargetMap[spec.get('type')](spec) |
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,23 @@ |
|||
#!/usr/bin/env python |
|||
|
|||
# Copyright (c) 2013 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 xcode.py file. """ |
|||
|
|||
import gyp.generator.xcode as xcode |
|||
import unittest |
|||
import sys |
|||
|
|||
|
|||
class TestEscapeXcodeDefine(unittest.TestCase): |
|||
if sys.platform == 'darwin': |
|||
def test_InheritedRemainsUnescaped(self): |
|||
self.assertEqual(xcode.EscapeXcodeDefine('$(inherited)'), '$(inherited)') |
|||
|
|||
def test_Escaping(self): |
|||
self.assertEqual(xcode.EscapeXcodeDefine('a b"c\\'), 'a\\ b\\"c\\\\') |
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
@ -0,0 +1,90 @@ |
|||
#!/usr/bin/env python |
|||
|
|||
# Copyright 2013 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 input.py file.""" |
|||
|
|||
import gyp.input |
|||
import unittest |
|||
import sys |
|||
|
|||
|
|||
class TestFindCycles(unittest.TestCase): |
|||
def setUp(self): |
|||
self.nodes = {} |
|||
for x in ('a', 'b', 'c', 'd', 'e'): |
|||
self.nodes[x] = gyp.input.DependencyGraphNode(x) |
|||
|
|||
def _create_dependency(self, dependent, dependency): |
|||
dependent.dependencies.append(dependency) |
|||
dependency.dependents.append(dependent) |
|||
|
|||
def test_no_cycle_empty_graph(self): |
|||
for label, node in self.nodes.iteritems(): |
|||
self.assertEquals([], node.FindCycles()) |
|||
|
|||
def test_no_cycle_line(self): |
|||
self._create_dependency(self.nodes['a'], self.nodes['b']) |
|||
self._create_dependency(self.nodes['b'], self.nodes['c']) |
|||
self._create_dependency(self.nodes['c'], self.nodes['d']) |
|||
|
|||
for label, node in self.nodes.iteritems(): |
|||
self.assertEquals([], node.FindCycles()) |
|||
|
|||
def test_no_cycle_dag(self): |
|||
self._create_dependency(self.nodes['a'], self.nodes['b']) |
|||
self._create_dependency(self.nodes['a'], self.nodes['c']) |
|||
self._create_dependency(self.nodes['b'], self.nodes['c']) |
|||
|
|||
for label, node in self.nodes.iteritems(): |
|||
self.assertEquals([], node.FindCycles()) |
|||
|
|||
def test_cycle_self_reference(self): |
|||
self._create_dependency(self.nodes['a'], self.nodes['a']) |
|||
|
|||
self.assertEquals([(self.nodes['a'], self.nodes['a'])], |
|||
self.nodes['a'].FindCycles()) |
|||
|
|||
def test_cycle_two_nodes(self): |
|||
self._create_dependency(self.nodes['a'], self.nodes['b']) |
|||
self._create_dependency(self.nodes['b'], self.nodes['a']) |
|||
|
|||
self.assertEquals([(self.nodes['a'], self.nodes['b'], self.nodes['a'])], |
|||
self.nodes['a'].FindCycles()) |
|||
self.assertEquals([(self.nodes['b'], self.nodes['a'], self.nodes['b'])], |
|||
self.nodes['b'].FindCycles()) |
|||
|
|||
def test_two_cycles(self): |
|||
self._create_dependency(self.nodes['a'], self.nodes['b']) |
|||
self._create_dependency(self.nodes['b'], self.nodes['a']) |
|||
|
|||
self._create_dependency(self.nodes['b'], self.nodes['c']) |
|||
self._create_dependency(self.nodes['c'], self.nodes['b']) |
|||
|
|||
cycles = self.nodes['a'].FindCycles() |
|||
self.assertTrue( |
|||
(self.nodes['a'], self.nodes['b'], self.nodes['a']) in cycles) |
|||
self.assertTrue( |
|||
(self.nodes['b'], self.nodes['c'], self.nodes['b']) in cycles) |
|||
self.assertEquals(2, len(cycles)) |
|||
|
|||
def test_big_cycle(self): |
|||
self._create_dependency(self.nodes['a'], self.nodes['b']) |
|||
self._create_dependency(self.nodes['b'], self.nodes['c']) |
|||
self._create_dependency(self.nodes['c'], self.nodes['d']) |
|||
self._create_dependency(self.nodes['d'], self.nodes['e']) |
|||
self._create_dependency(self.nodes['e'], self.nodes['a']) |
|||
|
|||
self.assertEquals([(self.nodes['a'], |
|||
self.nodes['b'], |
|||
self.nodes['c'], |
|||
self.nodes['d'], |
|||
self.nodes['e'], |
|||
self.nodes['a'])], |
|||
self.nodes['a'].FindCycles()) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
Loading…
Reference in new issue