mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Remove scons support
This commit is contained in:
committed by
Nikolaos D. Bougalis
parent
b4e1b3c1b1
commit
f0b9506617
@@ -1,188 +0,0 @@
|
||||
# Beast.py
|
||||
# Copyright 2014 by:
|
||||
# Vinnie Falco <vinnie.falco@gmail.com>
|
||||
# Tom Ritchford <?>
|
||||
# Nik Bougalis <?>
|
||||
# This file is part of Beast: http://github.com/vinniefalco/Beast
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import SCons.Node
|
||||
import SCons.Util
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# Environment
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def _execute(args, include_errors=True, **kwds):
|
||||
"""Execute a shell command and return the value. If args is a string,
|
||||
it's split on spaces - if some of your arguments contain spaces, args should
|
||||
instead be a list of arguments."""
|
||||
def single_line(line, report_errors=True, joiner='+'):
|
||||
"""Force a string to be a single line with no carriage returns, and report
|
||||
a warning if there was more than one line."""
|
||||
lines = line.strip().splitlines()
|
||||
if report_errors and len(lines) > 1:
|
||||
print('multiline result:', lines)
|
||||
return joiner.join(lines)
|
||||
def is_string(s):
|
||||
"""Is s a string? - in either Python 2.x or 3.x."""
|
||||
return isinstance(s, (str, unicode))
|
||||
if is_string(args):
|
||||
args = args.split()
|
||||
stderr = subprocess.STDOUT if include_errors else None
|
||||
return single_line(subprocess.check_output(args, stderr=stderr, **kwds))
|
||||
|
||||
class __System(object):
|
||||
"""Provides information about the host platform"""
|
||||
def __init__(self):
|
||||
self.name = platform.system()
|
||||
self.linux = self.name == 'Linux'
|
||||
self.osx = self.name == 'Darwin'
|
||||
self.windows = self.name == 'Windows'
|
||||
self.distro = None
|
||||
self.version = None
|
||||
|
||||
# True if building under the Travis CI (http://travis-ci.org)
|
||||
self.travis = (
|
||||
os.environ.get('TRAVIS', '0') == 'true') and (
|
||||
os.environ.get('CI', '0') == 'true')
|
||||
|
||||
if self.linux:
|
||||
self.distro, self.version, _ = platform.linux_distribution()
|
||||
self.__display = '%s %s (%s)' % (self.distro, self.version, self.name)
|
||||
|
||||
elif self.osx:
|
||||
parts = platform.mac_ver()[0].split('.')
|
||||
while len(parts) < 3:
|
||||
parts.append('0')
|
||||
self.__display = '%s %s' % (self.name, '.'.join(parts))
|
||||
elif self.windows:
|
||||
release, version, csd, ptype = platform.win32_ver()
|
||||
self.__display = '%s %s %s (%s)' % (self.name, release, version, ptype)
|
||||
|
||||
else:
|
||||
raise Exception('Unknown system platform "' + self.name + '"')
|
||||
|
||||
self.platform = self.distro or self.name
|
||||
|
||||
def __str__(self):
|
||||
return self.__display
|
||||
|
||||
class Git(object):
|
||||
"""Provides information about git and the repository we are called from"""
|
||||
def __init__(self, env):
|
||||
self.tags = self.branch = self.user = ''
|
||||
self.exists = env.Detect('git')
|
||||
if self.exists:
|
||||
try:
|
||||
self.tags = _execute('git describe --tags')
|
||||
self.branch = _execute('git rev-parse --abbrev-ref HEAD')
|
||||
remote = _execute('git config remote.origin.url')
|
||||
self.user = remote.split(':')[1].split('/')[0]
|
||||
except:
|
||||
self.exists = False
|
||||
|
||||
system = __System()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def printChildren(target):
|
||||
def doPrint(tgt, level, found):
|
||||
for item in tgt:
|
||||
if SCons.Util.is_List(item):
|
||||
doPrint(item, level, found)
|
||||
else:
|
||||
if item.abspath in found:
|
||||
continue
|
||||
found[item.abspath] = False
|
||||
print('\t'*level + item.path)
|
||||
#DoPrint(item.children(scan=1), level+1, found)
|
||||
item.scan()
|
||||
doPrint(item.all_children(), level+1, found)
|
||||
doPrint(target, 0, {})
|
||||
|
||||
def variantFile(path, variant_dirs):
|
||||
'''Returns the path to the corresponding dict entry in variant_dirs'''
|
||||
path = str(path)
|
||||
for dest, source in variant_dirs.items():
|
||||
common = os.path.commonprefix([path, source])
|
||||
if common == source:
|
||||
return os.path.join(dest, path[len(common)+1:])
|
||||
return path
|
||||
|
||||
def variantFiles(files, variant_dirs):
|
||||
'''Returns a list of files remapped to their variant directories'''
|
||||
result = []
|
||||
for path in files:
|
||||
result.append(variantFile(path, variant_dirs))
|
||||
return result
|
||||
|
||||
def printEnv(env, keys):
|
||||
if type(keys) != list:
|
||||
keys = list(keys)
|
||||
s = ''
|
||||
for key in keys:
|
||||
if key in env:
|
||||
value = env[key]
|
||||
else:
|
||||
value = ''
|
||||
s+=('%s=%s, ' % (key, value))
|
||||
print('[' + s + ']')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# Output
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# See https://stackoverflow.com/questions/7445658/how-to-detect-if-the-console-does-support-ansi-escape-codes-in-python
|
||||
CAN_CHANGE_COLOR = (
|
||||
hasattr(sys.stderr, "isatty")
|
||||
and sys.stderr.isatty()
|
||||
and not system.windows
|
||||
and not os.environ.get('INSIDE_EMACS')
|
||||
)
|
||||
|
||||
# See https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
BLUE = 94
|
||||
GREEN = 92
|
||||
RED = 91
|
||||
YELLOW = 93
|
||||
|
||||
def add_mode(text, *modes):
|
||||
if CAN_CHANGE_COLOR:
|
||||
modes = ';'.join(str(m) for m in modes)
|
||||
return '\033[%sm%s\033[0m' % (modes, text)
|
||||
else:
|
||||
return text
|
||||
|
||||
def blue(text):
|
||||
return add_mode(text, BLUE)
|
||||
|
||||
def green(text):
|
||||
return add_mode(text, GREEN)
|
||||
|
||||
def red(text):
|
||||
return add_mode(text, RED)
|
||||
|
||||
def yellow(text):
|
||||
return add_mode(text, YELLOW)
|
||||
|
||||
def warn(text, print=print):
|
||||
print('%s %s' % (red('WARNING:'), text))
|
||||
|
||||
# Prints command lines using environment substitutions
|
||||
def print_coms(coms, env):
|
||||
if type(coms) is str:
|
||||
coms=list(coms)
|
||||
for key in coms:
|
||||
cmdline = env.subst(env[key], 0,
|
||||
env.File('<target>'), env.File('<sources>'))
|
||||
print (green(cmdline))
|
||||
@@ -1,97 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2009 Scott Stafford
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
# Author : Scott Stafford
|
||||
# Date : 2009-12-09 20:36:14
|
||||
#
|
||||
# Changes : Vinnie Falco <vinnie.falco@gmail.com>
|
||||
# Date : 2014--4-25
|
||||
|
||||
"""
|
||||
Protoc.py: Protoc Builder for SCons
|
||||
|
||||
This Builder invokes protoc to generate C++ and Python from a .proto file.
|
||||
|
||||
NOTE: Java is not currently supported.
|
||||
"""
|
||||
|
||||
__author__ = "Scott Stafford"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Defaults
|
||||
import SCons.Node.FS
|
||||
import SCons.Util
|
||||
|
||||
from SCons.Script import File, Dir
|
||||
|
||||
import os.path
|
||||
|
||||
protocs = 'protoc'
|
||||
|
||||
ProtocAction = SCons.Action.Action('$PROTOCCOM', '$PROTOCCOMSTR')
|
||||
|
||||
def ProtocEmitter(target, source, env):
|
||||
PROTOCOUTDIR = env['PROTOCOUTDIR']
|
||||
PROTOCPYTHONOUTDIR = env['PROTOCPYTHONOUTDIR']
|
||||
for source_path in [str(x) for x in source]:
|
||||
base = os.path.splitext(os.path.basename(source_path))[0]
|
||||
if PROTOCOUTDIR:
|
||||
target.extend([os.path.join(PROTOCOUTDIR, base + '.pb.cc'),
|
||||
os.path.join(PROTOCOUTDIR, base + '.pb.h')])
|
||||
if PROTOCPYTHONOUTDIR:
|
||||
target.append(os.path.join(PROTOCPYTHONOUTDIR, base + '_pb2.py'))
|
||||
|
||||
try:
|
||||
target.append(env['PROTOCFDSOUT'])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
#print "PROTOC SOURCE:", [str(s) for s in source]
|
||||
#print "PROTOC TARGET:", [str(s) for s in target]
|
||||
|
||||
return target, source
|
||||
|
||||
ProtocBuilder = SCons.Builder.Builder(
|
||||
action = ProtocAction,
|
||||
emitter = ProtocEmitter,
|
||||
srcsuffix = '$PROTOCSRCSUFFIX')
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for protoc to an Environment."""
|
||||
try:
|
||||
bld = env['BUILDERS']['Protoc']
|
||||
except KeyError:
|
||||
bld = ProtocBuilder
|
||||
env['BUILDERS']['Protoc'] = bld
|
||||
|
||||
env['PROTOC'] = env.Detect(protocs) or 'protoc'
|
||||
env['PROTOCFLAGS'] = SCons.Util.CLVar('')
|
||||
env['PROTOCPROTOPATH'] = SCons.Util.CLVar('')
|
||||
env['PROTOCCOM'] = '$PROTOC ${["-I%s"%x for x in PROTOCPROTOPATH]} $PROTOCFLAGS --cpp_out=$PROTOCCPPOUTFLAGS$PROTOCOUTDIR ${PROTOCPYTHONOUTDIR and ("--python_out="+PROTOCPYTHONOUTDIR) or ""} ${PROTOCFDSOUT and ("-o"+PROTOCFDSOUT) or ""} ${SOURCES}'
|
||||
env['PROTOCOUTDIR'] = '${SOURCE.dir}'
|
||||
env['PROTOCPYTHONOUTDIR'] = "python"
|
||||
env['PROTOCSRCSUFFIX'] = '.proto'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(protocs)
|
||||
@@ -1,894 +0,0 @@
|
||||
# Copyright 2014 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
# Portions Copyright The SCons Foundation
|
||||
# Portions Copyright Google, Inc.
|
||||
# This file is part of beast
|
||||
|
||||
"""
|
||||
A SCons tool to provide a family of scons builders that
|
||||
generate Visual Studio project files
|
||||
"""
|
||||
|
||||
import collections
|
||||
import hashlib
|
||||
import io
|
||||
import itertools
|
||||
import ntpath
|
||||
import os
|
||||
import pprint
|
||||
import random
|
||||
import re
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Node.FS
|
||||
import SCons.Node
|
||||
import SCons.Script.Main
|
||||
import SCons.Util
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Adapted from msvs.py
|
||||
|
||||
UnicodeByteMarker = '\xEF\xBB\xBF'
|
||||
|
||||
V14DSPHeader = """\
|
||||
<?xml version="1.0" encoding="%(encoding)s"?>\r
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
|
||||
"""
|
||||
|
||||
V14DSPProjectConfiguration = """\
|
||||
<ProjectConfiguration Include="%(variant)s|%(platform)s">\r
|
||||
<Configuration>%(variant)s</Configuration>\r
|
||||
<Platform>%(platform)s</Platform>\r
|
||||
</ProjectConfiguration>\r
|
||||
"""
|
||||
|
||||
V14DSPGlobals = """\
|
||||
<PropertyGroup Label="Globals">\r
|
||||
<ProjectGuid>%(project_guid)s</ProjectGuid>\r
|
||||
<Keyword>Win32Proj</Keyword>\r
|
||||
<RootNamespace>%(name)s</RootNamespace>\r
|
||||
<IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>\r
|
||||
</PropertyGroup>\r
|
||||
"""
|
||||
|
||||
V14DSPPropertyGroup = """\
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'" Label="Configuration">\r
|
||||
<CharacterSet>MultiByte</CharacterSet>\r
|
||||
<ConfigurationType>Application</ConfigurationType>\r
|
||||
<PlatformToolset>v140</PlatformToolset>\r
|
||||
<LinkIncremental>False</LinkIncremental>\r
|
||||
<UseDebugLibraries>%(use_debug_libs)s</UseDebugLibraries>\r
|
||||
<UseOfMfc>False</UseOfMfc>\r
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>\r
|
||||
<IntDir>%(int_dir)s</IntDir>\r
|
||||
<OutDir>%(out_dir)s</OutDir>\r
|
||||
</PropertyGroup>\r
|
||||
"""
|
||||
|
||||
V14DSPImportGroup= """\
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'" Label="PropertySheets">\r
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
|
||||
</ImportGroup>\r
|
||||
"""
|
||||
|
||||
V14DSPItemDefinitionGroup= """\
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">\r
|
||||
"""
|
||||
|
||||
V14CustomBuildProtoc= """\
|
||||
<FileType>Document</FileType>\r
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='%(name)s'">protoc --cpp_out=%(cpp_out)s --proto_path=%%(RelativeDir) %%(Identity)</Command>\r
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='%(name)s'">%(base_out)s.pb.h;%(base_out)s.pb.cc</Outputs>\r
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='%(name)s'">protoc --cpp_out=%(cpp_out)s --proto_path=%%(RelativeDir) %%(Identity)</Message>\r
|
||||
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='%(name)s'">false</LinkObjects>\r
|
||||
"""
|
||||
|
||||
V14DSPFiltersHeader = (
|
||||
'''<?xml version="1.0" encoding="utf-8"?>\r
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
|
||||
''')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def is_subdir(child, parent):
|
||||
'''Determine if child is a subdirectory of parent'''
|
||||
return os.path.commonprefix([parent, child]) == parent
|
||||
|
||||
def _key(item):
|
||||
if isinstance(item, (str, unicode)):
|
||||
return ('s', item.upper(), item)
|
||||
elif isinstance(item, (int, long, float)):
|
||||
return ('n', item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
return ('l', map(_key, item))
|
||||
elif isinstance(item, dict):
|
||||
return ('d', xsorted(item.keys()), xsorted(item.values()))
|
||||
elif isinstance(item, Configuration):
|
||||
return ('c', _key(item.name), _key(item.target), _key(item.variant), _key(item.platform))
|
||||
elif isinstance(item, Item):
|
||||
return ('i', _key(winpath(item.path())), _key(item.is_compiled()), _key(item.builder()), _key(item.tag()), _key(item.is_excluded()))
|
||||
elif isinstance(item, SCons.Node.FS.File):
|
||||
return ('f', _key(item.name), _key(item.suffix))
|
||||
else:
|
||||
return ('x', item)
|
||||
|
||||
def xsorted(tosort, **kwargs):
|
||||
'''Performs sorted in a deterministic manner.'''
|
||||
if 'key' in kwargs:
|
||||
map(kwargs['key'], tosort)
|
||||
kwargs['key'] = _key
|
||||
return sorted(tosort, **kwargs)
|
||||
|
||||
def itemList(items, sep):
|
||||
if type(items) == str: # Won't work in Python 3.
|
||||
return items
|
||||
def gen():
|
||||
for item in xsorted(items):
|
||||
if isinstance(item, dict):
|
||||
for k, v in xsorted(item.items()):
|
||||
yield k + '=' + v
|
||||
elif isinstance(item, (tuple, list)):
|
||||
assert len(item) == 2, "Item shoud have exactly two elements: " + str(item)
|
||||
yield '%s=%s' % tuple(item)
|
||||
else:
|
||||
yield item
|
||||
yield sep
|
||||
return ''.join(gen())
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class SwitchConverter(object):
|
||||
'''Converts command line switches to MSBuild XML, using tables'''
|
||||
|
||||
def __init__(self, table, booltable, retable=None):
|
||||
self.table = {}
|
||||
for key in table:
|
||||
self.table[key] = table[key]
|
||||
for key in booltable:
|
||||
value = booltable[key]
|
||||
self.table[key] = [value[0], 'True']
|
||||
self.table[key + '-'] = [value[0], 'False']
|
||||
if retable != None:
|
||||
self.retable = retable
|
||||
else:
|
||||
self.retable = []
|
||||
|
||||
def getXml(self, switches, prefix = ''):
|
||||
switches = list(set(switches)) # Filter dupes because on windows platforms, /nologo is added automatically to the environment.
|
||||
xml = []
|
||||
for regex, tag in self.retable:
|
||||
matches = []
|
||||
for switch in switches[:]:
|
||||
match = regex.match(switch)
|
||||
if None != match:
|
||||
matches.append(match.group(1))
|
||||
switches.remove(switch)
|
||||
if len(matches) > 0:
|
||||
xml.append (
|
||||
'%s<%s>%s</%s>\r\n' % (
|
||||
prefix, tag, ';'.join(matches), tag))
|
||||
unknown = []
|
||||
for switch in switches:
|
||||
try:
|
||||
value = self.table[switch]
|
||||
xml.append (
|
||||
'%s<%s>%s</%s>\r\n' % (
|
||||
prefix, value[0], value[1], value[0]))
|
||||
except:
|
||||
unknown.append(switch)
|
||||
if unknown:
|
||||
s = itemList(unknown, ' ')
|
||||
tag = 'AdditionalOptions'
|
||||
xml.append('%(prefix)s<%(tag)s>%(s)s%%(%(tag)s)</%(tag)s>\r\n' % locals())
|
||||
if xml:
|
||||
return ''.join(xml)
|
||||
return ''
|
||||
|
||||
class ClSwitchConverter(SwitchConverter):
|
||||
def __init__(self):
|
||||
booltable = {
|
||||
'/C' : ['KeepComments'],
|
||||
'/doc' : ['GenerateXMLDocumentationFiles'],
|
||||
'/FAu' : ['UseUnicodeForAssemblerListing'],
|
||||
'/FC' : ['UseFullPaths'],
|
||||
'/FR' : ['BrowseInformation'],
|
||||
'/Fr' : ['BrowseInformation'],
|
||||
'/Fx' : ['ExpandAttributedSource'],
|
||||
'/GF' : ['StringPooling'],
|
||||
'/GL' : ['WholeProgramOptimization'],
|
||||
'/Gm' : ['MinimalRebuild'],
|
||||
'/GR' : ['RuntimeTypeInfo'],
|
||||
'/GS' : ['BufferSecurityCheck'],
|
||||
'/GT' : ['EnableFiberSafeOptimizations'],
|
||||
'/Gy' : ['FunctionLevelLinking'],
|
||||
'/MP' : ['MultiProcessorCompilation'],
|
||||
'/Oi' : ['IntrinsicFunctions'],
|
||||
'/Oy' : ['OmitFramePointers'],
|
||||
'/RTCc' : ['SmallerTypeCheck'],
|
||||
'/u' : ['UndefineAllPreprocessorDefinitions'],
|
||||
'/X' : ['IgnoreStandardIncludePath'],
|
||||
'/WX' : ['TreatWarningAsError'],
|
||||
'/Za' : ['DisableLanguageExtensions'],
|
||||
'/Zl' : ['OmitDefaultLibName'],
|
||||
'/fp:except' : ['FloatingPointExceptions'],
|
||||
'/hotpatch' : ['CreateHotpatchableImage'],
|
||||
'/nologo' : ['SuppressStartupBanner'],
|
||||
'/openmp' : ['OpenMPSupport'],
|
||||
'/showIncludes' : ['ShowIncludes'],
|
||||
'/Zc:forScope' : ['ForceConformanceInForLoopScope'],
|
||||
'/Zc:wchar_t' : ['TreatWChar_tAsBuiltInType'],
|
||||
}
|
||||
table = {
|
||||
'/EHsc' : ['ExceptionHandling', 'Sync'],
|
||||
'/EHa' : ['ExceptionHandling', 'Async'],
|
||||
'/EHs' : ['ExceptionHandling', 'SyncCThrow'],
|
||||
'/FA' : ['AssemblerOutput', 'AssemblyCode'],
|
||||
'/FAcs' : ['AssemblerOutput', 'All'],
|
||||
'/FAc' : ['AssemblerOutput', 'AssemblyAndMachineCode'],
|
||||
'/FAs' : ['AssemblerOutput', 'AssemblyAndSourceCode'],
|
||||
'/Gd' : ['CallingConvention', 'Cdecl'],
|
||||
'/Gr' : ['CallingConvention', 'FastCall'],
|
||||
'/Gz' : ['CallingConvention', 'StdCall'],
|
||||
'/MT' : ['RuntimeLibrary', 'MultiThreaded'],
|
||||
'/MTd' : ['RuntimeLibrary', 'MultiThreadedDebug'],
|
||||
'/MD' : ['RuntimeLibrary', 'MultiThreadedDLL'],
|
||||
'/MDd' : ['RuntimeLibrary', 'MultiThreadedDebugDLL'],
|
||||
'/Od' : ['Optimization', 'Disabled'],
|
||||
'/O1' : ['Optimization', 'MinSpace'],
|
||||
'/O2' : ['Optimization', 'MaxSpeed'],
|
||||
'/Ox' : ['Optimization', 'Full'],
|
||||
'/Ob1' : ['InlineFunctionExpansion', 'OnlyExplicitInline'],
|
||||
'/Ob2' : ['InlineFunctionExpansion', 'AnySuitable'],
|
||||
'/Ot' : ['FavorSizeOrSpeed', 'Speed'],
|
||||
'/Os' : ['FavorSizeOrSpeed', 'Size'],
|
||||
'/RTCs' : ['BasicRuntimeChecks', 'StackFrameRuntimeCheck'],
|
||||
'/RTCu' : ['BasicRuntimeChecks', 'UninitializedLocalUsageCheck'],
|
||||
'/RTC1' : ['BasicRuntimeChecks', 'EnableFastChecks'],
|
||||
'/TC' : ['CompileAs', 'CompileAsC'],
|
||||
'/TP' : ['CompileAs', 'CompileAsCpp'],
|
||||
'/W0' : [ 'WarningLevel', 'TurnOffAllWarnings'],
|
||||
'/W1' : [ 'WarningLevel', 'Level1'],
|
||||
'/W2' : [ 'WarningLevel', 'Level2'],
|
||||
'/W3' : [ 'WarningLevel', 'Level3'],
|
||||
'/W4' : [ 'WarningLevel', 'Level4'],
|
||||
'/Wall' : [ 'WarningLevel', 'EnableAllWarnings'],
|
||||
'/Yc' : ['PrecompiledHeader', 'Create'],
|
||||
'/Yu' : ['PrecompiledHeader', 'Use'],
|
||||
'/Z7' : ['DebugInformationFormat', 'OldStyle'],
|
||||
'/Zi' : ['DebugInformationFormat', 'ProgramDatabase'],
|
||||
'/ZI' : ['DebugInformationFormat', 'EditAndContinue'],
|
||||
'/Zp1' : ['StructMemberAlignment', '1Byte'],
|
||||
'/Zp2' : ['StructMemberAlignment', '2Bytes'],
|
||||
'/Zp4' : ['StructMemberAlignment', '4Bytes'],
|
||||
'/Zp8' : ['StructMemberAlignment', '8Bytes'],
|
||||
'/Zp16' : ['StructMemberAlignment', '16Bytes'],
|
||||
'/arch:IA32' : ['EnableEnhancedInstructionSet', 'NoExtensions'],
|
||||
'/arch:SSE' : ['EnableEnhancedInstructionSet', 'StreamingSIMDExtensions'],
|
||||
'/arch:SSE2' : ['EnableEnhancedInstructionSet', 'StreamingSIMDExtensions2'],
|
||||
'/arch:AVX' : ['EnableEnhancedInstructionSet', 'AdvancedVectorExtensions'],
|
||||
'/clr' : ['CompileAsManaged', 'True'],
|
||||
'/clr:pure' : ['CompileAsManaged', 'Pure'],
|
||||
'/clr:safe' : ['CompileAsManaged', 'Safe'],
|
||||
'/clr:oldSyntax' : ['CompileAsManaged', 'OldSyntax'],
|
||||
'/fp:fast' : ['FloatingPointModel', 'Fast'],
|
||||
'/fp:precise' : ['FloatingPointModel', 'Precise'],
|
||||
'/fp:strict' : ['FloatingPointModel', 'Strict'],
|
||||
'/errorReport:none' : ['ErrorReporting', 'None'],
|
||||
'/errorReport:prompt' : ['ErrorReporting', 'Prompt'],
|
||||
'/errorReport:queue' : ['ErrorReporting', 'Queue'],
|
||||
'/errorReport:send' : ['ErrorReporting', 'Send'],
|
||||
}
|
||||
retable = [
|
||||
(re.compile(r'/wd\"(\d+)\"'), 'DisableSpecificWarnings'),
|
||||
]
|
||||
# Ideas from Google's Generate Your Project
|
||||
'''
|
||||
_Same(_compile, 'AdditionalIncludeDirectories', _folder_list) # /I
|
||||
|
||||
_Same(_compile, 'PreprocessorDefinitions', _string_list) # /D
|
||||
_Same(_compile, 'ProgramDataBaseFileName', _file_name) # /Fd
|
||||
|
||||
_Same(_compile, 'AdditionalOptions', _string_list)
|
||||
_Same(_compile, 'AdditionalUsingDirectories', _folder_list) # /AI
|
||||
_Same(_compile, 'AssemblerListingLocation', _file_name) # /Fa
|
||||
_Same(_compile, 'BrowseInformationFile', _file_name)
|
||||
_Same(_compile, 'ForcedIncludeFiles', _file_list) # /FI
|
||||
_Same(_compile, 'ForcedUsingFiles', _file_list) # /FU
|
||||
_Same(_compile, 'UndefinePreprocessorDefinitions', _string_list) # /U
|
||||
_Same(_compile, 'XMLDocumentationFileName', _file_name)
|
||||
'' : ['EnablePREfast', _boolean) # /analyze Visible='false'
|
||||
_Renamed(_compile, 'ObjectFile', 'ObjectFileName', _file_name) # /Fo
|
||||
_Renamed(_compile, 'PrecompiledHeaderThrough', 'PrecompiledHeaderFile',
|
||||
_file_name) # Used with /Yc and /Yu
|
||||
_Renamed(_compile, 'PrecompiledHeaderFile', 'PrecompiledHeaderOutputFile',
|
||||
_file_name) # /Fp
|
||||
_ConvertedToAdditionalOption(_compile, 'DefaultCharIsUnsigned', '/J')
|
||||
_MSBuildOnly(_compile, 'ProcessorNumber', _integer) # the number of processors
|
||||
_MSBuildOnly(_compile, 'TrackerLogDirectory', _folder_name)
|
||||
_MSBuildOnly(_compile, 'TreatSpecificWarningsAsErrors', _string_list) # /we
|
||||
_MSBuildOnly(_compile, 'PreprocessOutputPath', _string) # /Fi
|
||||
'''
|
||||
SwitchConverter.__init__(self, table, booltable, retable)
|
||||
|
||||
class LinkSwitchConverter(SwitchConverter):
|
||||
def __init__(self):
|
||||
# Based on code in Generate Your Project
|
||||
booltable = {
|
||||
'/DEBUG' : ['GenerateDebugInformation'],
|
||||
'/DYNAMICBASE' : ['RandomizedBaseAddress'],
|
||||
'/NOLOGO' : ['SuppressStartupBanner'],
|
||||
'/nologo' : ['SuppressStartupBanner'],
|
||||
}
|
||||
table = {
|
||||
'/ERRORREPORT:NONE' : ['ErrorReporting', 'NoErrorReport'],
|
||||
'/ERRORREPORT:PROMPT' : ['ErrorReporting', 'PromptImmediately'],
|
||||
'/ERRORREPORT:QUEUE' : ['ErrorReporting', 'QueueForNextLogin'],
|
||||
'/ERRORREPORT:SEND' : ['ErrorReporting', 'SendErrorReport'],
|
||||
'/MACHINE:X86' : ['TargetMachine', 'MachineX86'],
|
||||
'/MACHINE:ARM' : ['TargetMachine', 'MachineARM'],
|
||||
'/MACHINE:EBC' : ['TargetMachine', 'MachineEBC'],
|
||||
'/MACHINE:IA64' : ['TargetMachine', 'MachineIA64'],
|
||||
'/MACHINE:MIPS' : ['TargetMachine', 'MachineMIPS'],
|
||||
'/MACHINE:MIPS16' : ['TargetMachine', 'MachineMIPS16'],
|
||||
'/MACHINE:MIPSFPU' : ['TargetMachine', 'MachineMIPSFPU'],
|
||||
'/MACHINE:MIPSFPU16' : ['TargetMachine', 'MachineMIPSFPU16'],
|
||||
'/MACHINE:SH4' : ['TargetMachine', 'MachineSH4'],
|
||||
'/MACHINE:THUMB' : ['TargetMachine', 'MachineTHUMB'],
|
||||
'/MACHINE:X64' : ['TargetMachine', 'MachineX64'],
|
||||
'/NXCOMPAT' : ['DataExecutionPrevention', 'true'],
|
||||
'/NXCOMPAT:NO' : ['DataExecutionPrevention', 'false'],
|
||||
'/SUBSYSTEM:CONSOLE' : ['SubSystem', 'Console'],
|
||||
'/SUBSYSTEM:WINDOWS' : ['SubSystem', 'Windows'],
|
||||
'/SUBSYSTEM:NATIVE' : ['SubSystem', 'Native'],
|
||||
'/SUBSYSTEM:EFI_APPLICATION' : ['SubSystem', 'EFI Application'],
|
||||
'/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER' : ['SubSystem', 'EFI Boot Service Driver'],
|
||||
'/SUBSYSTEM:EFI_ROM' : ['SubSystem', 'EFI ROM'],
|
||||
'/SUBSYSTEM:EFI_RUNTIME_DRIVER' : ['SubSystem', 'EFI Runtime'],
|
||||
'/SUBSYSTEM:WINDOWSCE' : ['SubSystem', 'WindowsCE'],
|
||||
'/SUBSYSTEM:POSIX' : ['SubSystem', 'POSIX'],
|
||||
}
|
||||
'''
|
||||
/TLBID:1 /MANIFEST /MANIFESTUAC:level='asInvoker' uiAccess='false'
|
||||
|
||||
_Same(_link, 'AllowIsolation', _boolean) # /ALLOWISOLATION
|
||||
_Same(_link, 'CLRUnmanagedCodeCheck', _boolean) # /CLRUNMANAGEDCODECHECK
|
||||
_Same(_link, 'DelaySign', _boolean) # /DELAYSIGN
|
||||
_Same(_link, 'EnableUAC', _boolean) # /MANIFESTUAC
|
||||
_Same(_link, 'GenerateMapFile', _boolean) # /MAP
|
||||
_Same(_link, 'IgnoreAllDefaultLibraries', _boolean) # /NODEFAULTLIB
|
||||
_Same(_link, 'IgnoreEmbeddedIDL', _boolean) # /IGNOREIDL
|
||||
_Same(_link, 'MapExports', _boolean) # /MAPINFO:EXPORTS
|
||||
_Same(_link, 'StripPrivateSymbols', _file_name) # /PDBSTRIPPED
|
||||
_Same(_link, 'PerUserRedirection', _boolean)
|
||||
_Same(_link, 'Profile', _boolean) # /PROFILE
|
||||
_Same(_link, 'RegisterOutput', _boolean)
|
||||
_Same(_link, 'SetChecksum', _boolean) # /RELEASE
|
||||
_Same(_link, 'SupportUnloadOfDelayLoadedDLL', _boolean) # /DELAY:UNLOAD
|
||||
|
||||
_Same(_link, 'SwapRunFromCD', _boolean) # /SWAPRUN:CD
|
||||
_Same(_link, 'TurnOffAssemblyGeneration', _boolean) # /NOASSEMBLY
|
||||
_Same(_link, 'UACUIAccess', _boolean) # /uiAccess='true'
|
||||
_Same(_link, 'EnableCOMDATFolding', _newly_boolean) # /OPT:ICF
|
||||
_Same(_link, 'FixedBaseAddress', _newly_boolean) # /FIXED
|
||||
_Same(_link, 'LargeAddressAware', _newly_boolean) # /LARGEADDRESSAWARE
|
||||
_Same(_link, 'OptimizeReferences', _newly_boolean) # /OPT:REF
|
||||
_Same(_link, 'TerminalServerAware', _newly_boolean) # /TSAWARE
|
||||
|
||||
_Same(_link, 'AdditionalDependencies', _file_list)
|
||||
_Same(_link, 'AdditionalLibraryDirectories', _folder_list) # /LIBPATH
|
||||
_Same(_link, 'AdditionalManifestDependencies', _file_list) # /MANIFESTDEPENDENCY:
|
||||
_Same(_link, 'AdditionalOptions', _string_list)
|
||||
_Same(_link, 'AddModuleNamesToAssembly', _file_list) # /ASSEMBLYMODULE
|
||||
_Same(_link, 'AssemblyLinkResource', _file_list) # /ASSEMBLYLINKRESOURCE
|
||||
_Same(_link, 'BaseAddress', _string) # /BASE
|
||||
_Same(_link, 'DelayLoadDLLs', _file_list) # /DELAYLOAD
|
||||
_Same(_link, 'EmbedManagedResourceFile', _file_list) # /ASSEMBLYRESOURCE
|
||||
_Same(_link, 'EntryPointSymbol', _string) # /ENTRY
|
||||
_Same(_link, 'ForceSymbolReferences', _file_list) # /INCLUDE
|
||||
_Same(_link, 'FunctionOrder', _file_name) # /ORDER
|
||||
_Same(_link, 'HeapCommitSize', _string)
|
||||
_Same(_link, 'HeapReserveSize', _string) # /HEAP
|
||||
_Same(_link, 'ImportLibrary', _file_name) # /IMPLIB
|
||||
_Same(_link, 'KeyContainer', _file_name) # /KEYCONTAINER
|
||||
_Same(_link, 'KeyFile', _file_name) # /KEYFILE
|
||||
_Same(_link, 'ManifestFile', _file_name) # /ManifestFile
|
||||
_Same(_link, 'MapFileName', _file_name)
|
||||
_Same(_link, 'MergedIDLBaseFileName', _file_name) # /IDLOUT
|
||||
_Same(_link, 'MergeSections', _string) # /MERGE
|
||||
_Same(_link, 'MidlCommandFile', _file_name) # /MIDL
|
||||
_Same(_link, 'ModuleDefinitionFile', _file_name) # /DEF
|
||||
_Same(_link, 'OutputFile', _file_name) # /OUT
|
||||
_Same(_link, 'ProfileGuidedDatabase', _file_name) # /PGD
|
||||
_Same(_link, 'ProgramDatabaseFile', _file_name) # /PDB
|
||||
_Same(_link, 'StackCommitSize', _string)
|
||||
_Same(_link, 'StackReserveSize', _string) # /STACK
|
||||
_Same(_link, 'TypeLibraryFile', _file_name) # /TLBOUT
|
||||
_Same(_link, 'TypeLibraryResourceID', _integer) # /TLBID
|
||||
_Same(_link, 'Version', _string) # /VERSION
|
||||
|
||||
|
||||
_Same(_link, 'AssemblyDebug',
|
||||
_Enumeration(['',
|
||||
'true', # /ASSEMBLYDEBUG
|
||||
'false'])) # /ASSEMBLYDEBUG:DISABLE
|
||||
_Same(_link, 'CLRImageType',
|
||||
_Enumeration(['Default',
|
||||
'ForceIJWImage', # /CLRIMAGETYPE:IJW
|
||||
'ForcePureILImage', # /Switch="CLRIMAGETYPE:PURE
|
||||
'ForceSafeILImage'])) # /Switch="CLRIMAGETYPE:SAFE
|
||||
_Same(_link, 'CLRThreadAttribute',
|
||||
_Enumeration(['DefaultThreadingAttribute', # /CLRTHREADATTRIBUTE:NONE
|
||||
'MTAThreadingAttribute', # /CLRTHREADATTRIBUTE:MTA
|
||||
'STAThreadingAttribute'])) # /CLRTHREADATTRIBUTE:STA
|
||||
_Same(_link, 'Driver',
|
||||
_Enumeration(['NotSet',
|
||||
'Driver', # /Driver
|
||||
'UpOnly', # /DRIVER:UPONLY
|
||||
'WDM'])) # /DRIVER:WDM
|
||||
_Same(_link, 'LinkTimeCodeGeneration',
|
||||
_Enumeration(['Default',
|
||||
'UseLinkTimeCodeGeneration', # /LTCG
|
||||
'PGInstrument', # /LTCG:PGInstrument
|
||||
'PGOptimization', # /LTCG:PGOptimize
|
||||
'PGUpdate'])) # /LTCG:PGUpdate
|
||||
_Same(_link, 'ShowProgress',
|
||||
_Enumeration(['NotSet',
|
||||
'LinkVerbose', # /VERBOSE
|
||||
'LinkVerboseLib'], # /VERBOSE:Lib
|
||||
new=['LinkVerboseICF', # /VERBOSE:ICF
|
||||
'LinkVerboseREF', # /VERBOSE:REF
|
||||
'LinkVerboseSAFESEH', # /VERBOSE:SAFESEH
|
||||
'LinkVerboseCLR'])) # /VERBOSE:CLR
|
||||
_Same(_link, 'UACExecutionLevel',
|
||||
_Enumeration(['AsInvoker', # /level='asInvoker'
|
||||
'HighestAvailable', # /level='highestAvailable'
|
||||
'RequireAdministrator'])) # /level='requireAdministrator'
|
||||
_Same(_link, 'MinimumRequiredVersion', _string)
|
||||
_Same(_link, 'TreatLinkerWarningAsErrors', _boolean) # /WX
|
||||
|
||||
|
||||
# Options found in MSVS that have been renamed in MSBuild.
|
||||
_Renamed(_link, 'IgnoreDefaultLibraryNames', 'IgnoreSpecificDefaultLibraries',
|
||||
_file_list) # /NODEFAULTLIB
|
||||
_Renamed(_link, 'ResourceOnlyDLL', 'NoEntryPoint', _boolean) # /NOENTRY
|
||||
_Renamed(_link, 'SwapRunFromNet', 'SwapRunFromNET', _boolean) # /SWAPRUN:NET
|
||||
|
||||
_Moved(_link, 'GenerateManifest', '', _boolean)
|
||||
_Moved(_link, 'IgnoreImportLibrary', '', _boolean)
|
||||
_Moved(_link, 'LinkIncremental', '', _newly_boolean)
|
||||
_Moved(_link, 'LinkLibraryDependencies', 'ProjectReference', _boolean)
|
||||
_Moved(_link, 'UseLibraryDependencyInputs', 'ProjectReference', _boolean)
|
||||
|
||||
# MSVS options not found in MSBuild.
|
||||
_MSVSOnly(_link, 'OptimizeForWindows98', _newly_boolean)
|
||||
_MSVSOnly(_link, 'UseUnicodeResponseFiles', _boolean)
|
||||
|
||||
# MSBuild options not found in MSVS.
|
||||
_MSBuildOnly(_link, 'BuildingInIDE', _boolean)
|
||||
_MSBuildOnly(_link, 'ImageHasSafeExceptionHandlers', _boolean) # /SAFESEH
|
||||
_MSBuildOnly(_link, 'LinkDLL', _boolean) # /DLL Visible='false'
|
||||
_MSBuildOnly(_link, 'LinkStatus', _boolean) # /LTCG:STATUS
|
||||
_MSBuildOnly(_link, 'PreventDllBinding', _boolean) # /ALLOWBIND
|
||||
_MSBuildOnly(_link, 'SupportNobindOfDelayLoadedDLL', _boolean) # /DELAY:NOBIND
|
||||
_MSBuildOnly(_link, 'TrackerLogDirectory', _folder_name)
|
||||
_MSBuildOnly(_link, 'MSDOSStubFileName', _file_name) # /STUB Visible='false'
|
||||
_MSBuildOnly(_link, 'SectionAlignment', _integer) # /ALIGN
|
||||
_MSBuildOnly(_link, 'SpecifySectionAttributes', _string) # /SECTION
|
||||
_MSBuildOnly(_link, 'ForceFileOutput',
|
||||
_Enumeration([], new=['Enabled', # /FORCE
|
||||
# /FORCE:MULTIPLE
|
||||
'MultiplyDefinedSymbolOnly',
|
||||
'UndefinedSymbolOnly'])) # /FORCE:UNRESOLVED
|
||||
_MSBuildOnly(_link, 'CreateHotPatchableImage',
|
||||
_Enumeration([], new=['Enabled', # /FUNCTIONPADMIN
|
||||
'X86Image', # /FUNCTIONPADMIN:5
|
||||
'X64Image', # /FUNCTIONPADMIN:6
|
||||
'ItaniumImage'])) # /FUNCTIONPADMIN:16
|
||||
_MSBuildOnly(_link, 'CLRSupportLastError',
|
||||
_Enumeration([], new=['Enabled', # /CLRSupportLastError
|
||||
'Disabled', # /CLRSupportLastError:NO
|
||||
# /CLRSupportLastError:SYSTEMDLL
|
||||
'SystemDlls']))
|
||||
|
||||
'''
|
||||
SwitchConverter.__init__(self, table, booltable)
|
||||
|
||||
CLSWITCHES = ClSwitchConverter()
|
||||
LINKSWITCHES = LinkSwitchConverter()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Return a Windows path from a native path
|
||||
def winpath(path):
|
||||
drive, rest = ntpath.splitdrive(path)
|
||||
result = []
|
||||
while rest and rest != ntpath.sep:
|
||||
rest, part = ntpath.split(rest)
|
||||
result.insert(0, part)
|
||||
if rest:
|
||||
result.insert(0, rest)
|
||||
return ntpath.join(drive.upper(), *result)
|
||||
|
||||
def makeList(x):
|
||||
if not x:
|
||||
return []
|
||||
if type(x) is not list:
|
||||
return [x]
|
||||
return x
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class Configuration(object):
|
||||
def __init__(self, variant, platform, target, env):
|
||||
self.name = '%s|%s' % (variant, platform)
|
||||
self.variant = variant
|
||||
self.platform = platform
|
||||
self.target = target
|
||||
self.env = env
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class Item(object):
|
||||
'''Represents a file item in the Solution Explorer'''
|
||||
def __init__(self, path, builder):
|
||||
self._path = path
|
||||
self._builder = builder
|
||||
self.node = dict()
|
||||
|
||||
if builder == 'Object':
|
||||
self._tag = 'ClCompile'
|
||||
self._excluded = False
|
||||
elif builder == 'Protoc':
|
||||
self._tag = 'CustomBuild'
|
||||
self._excluded = False
|
||||
else:
|
||||
ext = os.path.splitext(self._path)[1]
|
||||
if ext in ['.c', '.cc', '.cpp']:
|
||||
self._tag = 'ClCompile'
|
||||
self._excluded = True
|
||||
else:
|
||||
if ext in ['.h', '.hpp', '.hxx', '.inl', '.inc']:
|
||||
self._tag = 'ClInclude'
|
||||
else:
|
||||
self._tag = 'None'
|
||||
self._excluded = False;
|
||||
|
||||
def __repr__(self):
|
||||
return '<VSProject.Item "%s" %s>' % (
|
||||
self.path, self.tag, str(self.node))
|
||||
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
def tag(self):
|
||||
return self._tag
|
||||
|
||||
def builder(self):
|
||||
return self._builder
|
||||
|
||||
def is_compiled(self):
|
||||
return self._builder == 'Object'
|
||||
|
||||
def is_excluded(self):
|
||||
return self._excluded
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def _guid(seed, name = None):
|
||||
m = hashlib.md5()
|
||||
m.update(seed)
|
||||
if name:
|
||||
m.update(name)
|
||||
d = m.hexdigest().upper()
|
||||
guid = "{%s-%s-%s-%s-%s}" % (d[:8], d[8:12], d[12:16], d[16:20], d[20:32])
|
||||
return guid
|
||||
|
||||
class _ProjectGenerator(object):
|
||||
'''Generates a project file for Visual Studio 2013'''
|
||||
|
||||
def __init__(self, project_node, filters_node, env):
|
||||
try:
|
||||
self.configs = xsorted(env['VSPROJECT_CONFIGS'])
|
||||
except KeyError:
|
||||
raise ValueError ('Missing VSPROJECT_CONFIGS')
|
||||
self.root_dir = os.getcwd()
|
||||
self.root_dirs = [os.path.abspath(x) for x in makeList(env['VSPROJECT_ROOT_DIRS'])]
|
||||
self.project_dir = os.path.dirname(os.path.abspath(str(project_node)))
|
||||
self.project_node = project_node
|
||||
self.project_file = None
|
||||
self.filters_node = filters_node
|
||||
self.filters_file = None
|
||||
self.guid = _guid(os.path.basename(str(self.project_node)))
|
||||
self.buildItemList(env)
|
||||
|
||||
def buildItemList(self, env):
|
||||
'''Build the Item set associated with the configurations'''
|
||||
items = {}
|
||||
def _walk(target, items, prefix=''):
|
||||
if os.path.isabs(str(target)):
|
||||
return
|
||||
if target.has_builder():
|
||||
builder = target.get_builder().get_name(env)
|
||||
bsources = target.get_binfo().bsources
|
||||
if builder == 'Program':
|
||||
for child in bsources:
|
||||
_walk(child, items, prefix+' ')
|
||||
else:
|
||||
for child in bsources:
|
||||
item = items.setdefault(str(child), Item(str(child), builder=builder))
|
||||
item.node[config] = target
|
||||
_walk(child, items, prefix+' ')
|
||||
for child in target.children(scan=1):
|
||||
if not os.path.isabs(str(child)):
|
||||
item = items.setdefault(str(child), Item(str(child), builder=None))
|
||||
_walk(child, items, prefix+' ')
|
||||
for config in self.configs:
|
||||
targets = config.target
|
||||
for target in targets:
|
||||
_walk(target, items)
|
||||
self.items = xsorted(items.values())
|
||||
|
||||
def makeListTag(self, items, prefix, tag, attrs, inherit=True):
|
||||
'''Builds an XML tag string from a list of items. If items is
|
||||
empty, then the returned string is empty.'''
|
||||
if not items:
|
||||
return ''
|
||||
s = '%(prefix)s<%(tag)s%(attrs)s>' % locals()
|
||||
s += ';'.join(items)
|
||||
if inherit:
|
||||
s += ';%%(%(tag)s)' % locals()
|
||||
s += '</%(tag)s>\r\n' % locals()
|
||||
return s
|
||||
|
||||
def relPaths(self, paths):
|
||||
items = []
|
||||
for path in paths:
|
||||
if not os.path.isabs(path):
|
||||
items.append(winpath(os.path.relpath(path, self.project_dir)))
|
||||
return items
|
||||
|
||||
def extraRelPaths(self, paths, base):
|
||||
extras = []
|
||||
for path in paths:
|
||||
if not path in base:
|
||||
extras.append(path)
|
||||
return self.relPaths(extras)
|
||||
|
||||
def writeHeader(self):
|
||||
global clSwitches
|
||||
|
||||
encoding = 'utf-8'
|
||||
project_guid = self.guid
|
||||
name = os.path.splitext(os.path.basename(str(self.project_node)))[0]
|
||||
|
||||
f = self.project_file
|
||||
f.write(UnicodeByteMarker)
|
||||
f.write(V14DSPHeader % locals())
|
||||
f.write(V14DSPGlobals % locals())
|
||||
f.write(' <ItemGroup Label="ProjectConfigurations">\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
f.write(V14DSPProjectConfiguration % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
|
||||
f.write(' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
use_debug_libs = variant == 'Debug'
|
||||
variant_dir = os.path.relpath(os.path.dirname(
|
||||
config.target[0].get_abspath()), self.project_dir)
|
||||
out_dir = winpath(variant_dir) + ntpath.sep
|
||||
int_dir = winpath(ntpath.join(variant_dir, 'src')) + ntpath.sep
|
||||
f.write(V14DSPPropertyGroup % locals())
|
||||
|
||||
f.write(' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r\n')
|
||||
f.write(' <ImportGroup Label="ExtensionSettings" />\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
f.write(V14DSPImportGroup % locals())
|
||||
|
||||
f.write(' <PropertyGroup Label="UserMacros" />\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
f.write(V14DSPItemDefinitionGroup % locals())
|
||||
# Cl options
|
||||
f.write(' <ClCompile>\r\n')
|
||||
f.write(
|
||||
' <PreprocessorDefinitions>%s%%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n' % (
|
||||
itemList(config.env['CPPDEFINES'], ';')))
|
||||
props = ''
|
||||
props += self.makeListTag(self.relPaths(xsorted(config.env['CPPPATH'])),
|
||||
' ', 'AdditionalIncludeDirectories', '', True)
|
||||
f.write(props)
|
||||
f.write(CLSWITCHES.getXml(xsorted(config.env['CCFLAGS']), ' '))
|
||||
f.write(' </ClCompile>\r\n')
|
||||
|
||||
f.write(' <Link>\r\n')
|
||||
props = ''
|
||||
props += self.makeListTag(xsorted(config.env['LIBS']),
|
||||
' ', 'AdditionalDependencies', '', True)
|
||||
try:
|
||||
props += self.makeListTag(self.relPaths(xsorted(config.env['LIBPATH'])),
|
||||
' ', 'AdditionalLibraryDirectories', '', True)
|
||||
except:
|
||||
pass
|
||||
f.write(props)
|
||||
f.write(LINKSWITCHES.getXml(xsorted(config.env['LINKFLAGS']), ' '))
|
||||
f.write(' </Link>\r\n')
|
||||
|
||||
f.write(' </ItemDefinitionGroup>\r\n')
|
||||
|
||||
def writeProject(self):
|
||||
self.writeHeader()
|
||||
|
||||
f = self.project_file
|
||||
self.project_file.write(' <ItemGroup>\r\n')
|
||||
for item in self.items:
|
||||
path = winpath(os.path.relpath(item.path(), self.project_dir))
|
||||
tag = item.tag()
|
||||
props = ''
|
||||
if item.builder() == 'Object':
|
||||
props = ''
|
||||
for config in self.configs:
|
||||
name = config.name
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
if not config in item.node:
|
||||
props += \
|
||||
''' <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">True</ExcludedFromBuild>\r\n''' % locals()
|
||||
for config, output in xsorted(item.node.items()):
|
||||
name = config.name
|
||||
env = output.get_build_env()
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
props += self.makeListTag(self.extraRelPaths(xsorted(env['CPPPATH']), config.env['CPPPATH']),
|
||||
' ', 'AdditionalIncludeDirectories',
|
||||
''' Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'"''' % locals(),
|
||||
True)
|
||||
elif item.is_excluded():
|
||||
props = ' <ExcludedFromBuild>True</ExcludedFromBuild>\r\n'
|
||||
elif item.builder() == 'Protoc':
|
||||
for config, output in xsorted(item.node.items()):
|
||||
name = config.name
|
||||
out_dir = os.path.relpath(os.path.dirname(str(output)), self.project_dir)
|
||||
cpp_out = winpath(out_dir)
|
||||
out_parts = out_dir.split(os.sep)
|
||||
out_parts.append(os.path.splitext(os.path.basename(item.path()))[0])
|
||||
base_out = ntpath.join(*out_parts)
|
||||
props += V14CustomBuildProtoc % locals()
|
||||
|
||||
f.write(' <%(tag)s Include="%(path)s">\r\n' % locals())
|
||||
f.write(props)
|
||||
f.write(' </%(tag)s>\r\n' % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
|
||||
f.write(
|
||||
' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r\n'
|
||||
' <ImportGroup Label="ExtensionTargets">\r\n'
|
||||
' </ImportGroup>\r\n'
|
||||
'</Project>\r\n')
|
||||
|
||||
def writeFilters(self):
|
||||
def getGroup(abspath):
|
||||
abspath = os.path.dirname(abspath)
|
||||
for d in self.root_dirs:
|
||||
common = os.path.commonprefix([abspath, d])
|
||||
if common == d:
|
||||
return winpath(os.path.relpath(abspath, common))
|
||||
return winpath(os.path.split(abspath)[1])
|
||||
|
||||
f = self.filters_file
|
||||
f.write(UnicodeByteMarker)
|
||||
f.write(V14DSPFiltersHeader)
|
||||
|
||||
f.write(' <ItemGroup>\r\n')
|
||||
groups = set()
|
||||
for item in self.items:
|
||||
group = getGroup(os.path.abspath(item.path()))
|
||||
while group != '':
|
||||
groups.add(group)
|
||||
group = ntpath.split(group)[0]
|
||||
for group in xsorted(groups):
|
||||
guid = _guid(self.guid, group)
|
||||
f.write(
|
||||
' <Filter Include="%(group)s">\r\n'
|
||||
' <UniqueIdentifier>%(guid)s</UniqueIdentifier>\r\n'
|
||||
' </Filter>\r\n' % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
|
||||
f.write(' <ItemGroup>\r\n')
|
||||
for item in self.items:
|
||||
path = os.path.abspath(item.path())
|
||||
group = getGroup(path)
|
||||
path = winpath(os.path.relpath(path, self.project_dir))
|
||||
tag = item.tag()
|
||||
f.write (
|
||||
' <%(tag)s Include="%(path)s">\r\n'
|
||||
' <Filter>%(group)s</Filter>\r\n'
|
||||
' </%(tag)s>\r\n' % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
f.write('</Project>\r\n')
|
||||
|
||||
def build(self):
|
||||
try:
|
||||
self.project_file = open(str(self.project_node), 'wb')
|
||||
except (IOError, detail):
|
||||
raise SCons.Errors.InternalError('Unable to open "' +
|
||||
str(self.project_node) + '" for writing:' + str(detail))
|
||||
try:
|
||||
self.filters_file = open(str(self.filters_node), 'wb')
|
||||
except (IOError, detail):
|
||||
raise SCons.Errors.InternalError('Unable to open "' +
|
||||
str(self.filters_node) + '" for writing:' + str(detail))
|
||||
self.writeProject()
|
||||
self.writeFilters()
|
||||
self.project_file.close()
|
||||
self.filters_file.close()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class _SolutionGenerator(object):
|
||||
def __init__(self, slnfile, projfile, env):
|
||||
pass
|
||||
|
||||
def build(self):
|
||||
pass
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Generate the VS2013 project
|
||||
def buildProject(target, source, env):
|
||||
if env.get('auto_build_solution', 1):
|
||||
if len(target) != 3:
|
||||
raise ValueError ("Unexpected len(target) != 3")
|
||||
if not env.get('auto_build_solution', 1):
|
||||
if len(target) != 2:
|
||||
raise ValueError ("Unexpected len(target) != 2")
|
||||
|
||||
g = _ProjectGenerator (target[0], target[1], env)
|
||||
g.build()
|
||||
|
||||
if env.get('auto_build_solution', 1):
|
||||
g = _SolutionGenerator (target[2], target[0], env)
|
||||
g.build()
|
||||
|
||||
def projectEmitter(target, source, env):
|
||||
if len(target) != 1:
|
||||
raise ValueError ("Exactly one target must be specified")
|
||||
|
||||
# If source is unspecified this condition will be true
|
||||
if not source or source[0] == target[0]:
|
||||
source = []
|
||||
|
||||
outputs = []
|
||||
for node in list(target):
|
||||
path = env.GetBuildPath(node)
|
||||
outputs.extend([
|
||||
path + '.vcxproj',
|
||||
path + '.vcxproj.filters'])
|
||||
if env.get('auto_build_solution', 1):
|
||||
outputs.append(path + '.sln')
|
||||
return outputs, source
|
||||
|
||||
projectBuilder = SCons.Builder.Builder(
|
||||
action = SCons.Action.Action(buildProject, "Building ${TARGET}"),
|
||||
emitter = projectEmitter)
|
||||
|
||||
def createConfig(self, variant, platform, target, env):
|
||||
return Configuration(variant, platform, target, env)
|
||||
|
||||
def generate(env):
|
||||
'''Add Builders and construction variables for Microsoft Visual
|
||||
Studio project files to an Environment.'''
|
||||
try:
|
||||
env['BUILDERS']['VSProject']
|
||||
except KeyError:
|
||||
env['BUILDERS']['VSProject'] = projectBuilder
|
||||
env.AddMethod(createConfig, 'VSProjectConfig')
|
||||
|
||||
def exists(env):
|
||||
return True
|
||||
@@ -138,11 +138,6 @@ std::unique_ptr <Checkpointer> makeCheckpointer (soci::session&, JobQueue&, Logs
|
||||
|
||||
} // ripple
|
||||
|
||||
// Do not remove this dead code. It forces `scons vcxproj` to include version.h.
|
||||
#if 0
|
||||
#include "version.h"
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
# Copyright (c) 2014 The Native Client 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 atexit
|
||||
import os
|
||||
import sys
|
||||
import SCons.Action
|
||||
# This implements a Ninja backend for SCons. This allows SCons to be used
|
||||
# as a Ninja file generator, similar to how Gyp will generate Ninja files.
|
||||
#
|
||||
# This is a way to bypass SCons's slow startup time. After running SCons
|
||||
# to generate a Ninja file (which is fairly slow), you can rebuild targets
|
||||
# quickly using Ninja, as long as the .scons files haven't changed.
|
||||
#
|
||||
# The implementation is fairly hacky: It hooks PRINT_CMD_LINE_FUNC to
|
||||
# discover the build commands that SCons would normally run.
|
||||
#
|
||||
# A cleaner implementation would traverse the node graph instead.
|
||||
# Traversing the node graph is itself straightforward, but finding the
|
||||
# command associated with a node is not -- I couldn't figure out how to do
|
||||
# that.
|
||||
# This is necessary to handle SCons's "variant dir" feature. The filename
|
||||
# associated with a Scons node can be ambiguous: it might come from the
|
||||
# build dir or the source dir.
|
||||
def GetRealNode(node):
|
||||
src = node.srcnode()
|
||||
if src.stat() is not None:
|
||||
return src
|
||||
return node
|
||||
def GenerateNinjaFile(envs, dest_file):
|
||||
# Tell SCons not to run any commands, just report what would be run.
|
||||
for e in envs:
|
||||
e.SetOption('no_exec', True)
|
||||
# Tell SCons that everything needs rebuilding.
|
||||
e.Decider(lambda dependency, target, prev_ni: True)
|
||||
# Use a list to ensure that the output is ordered deterministically.
|
||||
node_list = []
|
||||
node_map = {}
|
||||
def CustomCommandPrinter(cmd, targets, source, env):
|
||||
for node in targets:
|
||||
# There can sometimes be multiple commands per target (e.g. ar+ranlib).
|
||||
# We must collect these together to output a single Ninja rule.
|
||||
if node not in node_map:
|
||||
node_list.append(node)
|
||||
node_map.setdefault(node, []).append(cmd)
|
||||
for e in envs:
|
||||
e.Append(PRINT_CMD_LINE_FUNC=CustomCommandPrinter)
|
||||
def WriteFile():
|
||||
dest_temp = '%s.tmp' % dest_file
|
||||
ninja_fh = open(dest_temp, 'w')
|
||||
ninja_fh.write("""\
|
||||
# Generated by scons_to_ninja.py
|
||||
# Generic rule for handling any command.
|
||||
rule cmd
|
||||
command = $cmd
|
||||
# NaCl overrides SCons's Install() step to create hard links, for speed.
|
||||
# To coexist with that, we must remove the file before copying, otherwise
|
||||
# cp complains the source and dest "are the same file". We also create
|
||||
# hard links here (with -l) for speed.
|
||||
rule install
|
||||
command = rm -f $out && cp -l $in $out
|
||||
""")
|
||||
for node in node_list:
|
||||
dest_path = node.get_path()
|
||||
cmds = node_map[node]
|
||||
deps = [GetRealNode(dep).get_path() for dep in node.all_children()]
|
||||
action = node.builder.action
|
||||
if type(action) == SCons.Action.FunctionAction:
|
||||
funcname = action.function_name()
|
||||
if funcname == 'installFunc':
|
||||
assert len(deps) == 1, len(deps)
|
||||
ninja_fh.write('\nbuild %s: install %s\n'
|
||||
% (dest_path, ' '.join(deps)))
|
||||
continue
|
||||
else:
|
||||
sys.stderr.write('Unknown FunctionAction, %r: skipping target %r\n'
|
||||
% (funcname, dest_path))
|
||||
continue
|
||||
ninja_fh.write('\nbuild %s: cmd %s\n'
|
||||
% (dest_path, ' '.join(deps)))
|
||||
ninja_fh.write(' cmd = %s\n' % ' && '.join(cmds))
|
||||
# Make the result file visible atomically.
|
||||
os.rename(dest_temp, dest_file)
|
||||
atexit.register(WriteFile)
|
||||
Reference in New Issue
Block a user