Remove scons support

This commit is contained in:
Brad Chase
2018-03-02 14:18:03 -05:00
committed by Nikolaos D. Bougalis
parent b4e1b3c1b1
commit f0b9506617
42 changed files with 312 additions and 15913 deletions

View File

@@ -34,27 +34,27 @@ matrix:
include:
- compiler: gcc
env: GCC_VER=5 BUILD=cmake TARGET=debug
env: GCC_VER=5 TARGET=debug
# - APP_ARGS="--unittest-jobs=2"
# - compiler: gcc
# env: GCC_VER=5 TARGET=debug.nounity
# - compiler: gcc
# env: GCC_VER=5 BUILD=cmake TARGET=coverage PATH=$PWD/cmake/bin:$PATH
# env: GCC_VER=5 TARGET=coverage PATH=$PWD/cmake/bin:$PATH
- compiler: clang
env: GCC_VER=5 BUILD=cmake TARGET=debug
env: GCC_VER=5 TARGET=debug
# - compiler: clang
# env: GCC_VER=5 TARGET=debug.nounity
# The clang cmake builds do not link.
# - compiler: clang
# env: GCC_VER=5 BUILD=cmake TARGET=debug
# env: GCC_VER=5 TARGET=debug CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PWD/cmake/bin:$PATH
# - compiler: clang
# env: GCC_VER=5 BUILD=cmake TARGET=debug.nounity
# env: GCC_VER=5 TARGET=debug.nounity CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PWD/cmake/bin:$PATH
cache:
directories:

View File

@@ -1,38 +0,0 @@
# Maintainer: Roberto Catini <roberto.catini@gmail.com>
pkgname=rippled
pkgrel=1
pkgver=0
pkgdesc="Ripple peer-to-peer network daemon"
arch=('i686' 'x86_64')
url="https://github.com/ripple/rippled"
license=('custom:ISC')
depends=('protobuf' 'openssl' 'boost-libs')
makedepends=('git' 'scons' 'boost')
backup=("etc/$pkgname/rippled.cfg")
source=("git://github.com/ripple/rippled.git#branch=master")
sha512sums=('SKIP')
pkgver() {
cd "$srcdir/$pkgname"
git describe --long --tags | sed -r 's/([^-]*-g)/r\1/;s/-/./g'
}
build() {
cd "$srcdir/$pkgname"
scons
}
check() {
cd "$srcdir/$pkgname"
build/rippled --unittest
}
package() {
cd "$srcdir/$pkgname"
install -D -m644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -D build/rippled "$pkgdir/usr/bin/rippled"
install -D -m644 cfg/rippled-example.cfg "$pkgdir/etc/$pkgname/rippled.cfg"
mkdir -p "$pkgdir/var/lib/$pkgname/db"
mkdir -p "$pkgdir/var/log/$pkgname"
}

View File

@@ -1,30 +0,0 @@
# rippled
# use the ubuntu base image
FROM ubuntu
MAINTAINER Roberto Catini roberto.catini@gmail.com
# make sure the package repository is up to date
RUN apt-get update
RUN apt-get -y upgrade
# install the dependencies
RUN apt-get -y install git scons pkg-config protobuf-compiler libprotobuf-dev libssl-dev libboost1.55-all-dev
# download source code from official repository
RUN git clone https://github.com/ripple/rippled.git src; cd src/; git checkout master
# compile
RUN cd src/; scons build/rippled
# move to root directory and strip
RUN cp src/build/rippled rippled; strip rippled
# copy default config
RUN cp src/cfg/rippled-example.cfg rippled.cfg
# clean source
RUN rm -r src
# launch rippled when launching the container
ENTRYPOINT ./rippled

View File

@@ -1,23 +0,0 @@
FROM ubuntu
MAINTAINER Torrie Fischer <torrie@ripple.com>
RUN apt-get update -qq &&\
apt-get install -qq software-properties-common &&\
apt-add-repository -y ppa:ubuntu-toolchain-r/test &&\
apt-add-repository -y ppa:afrank/boost &&\
apt-get update -qq
RUN apt-get purge -qq libboost1.48-dev &&\
apt-get install -qq libprotobuf8 libboost1.57-all-dev
RUN mkdir -p /srv/rippled/data
VOLUME /srv/rippled/data/
ENTRYPOINT ["/srv/rippled/bin/rippled"]
CMD ["--conf", "/srv/rippled/data/rippled.cfg"]
EXPOSE 51235/udp
EXPOSE 5005/tcp
ADD ./rippled.cfg /srv/rippled/data/rippled.cfg
ADD ./rippled /srv/rippled/bin/

View File

@@ -1,13 +0,0 @@
set -e
mkdir -p build/docker/
cp cfg/rippled-example.cfg build/clang.debug/rippled build/docker/
cp Builds/Docker/Dockerfile-testnet build/docker/Dockerfile
mv build/docker/rippled-example.cfg build/docker/rippled.cfg
strip build/docker/rippled
docker build -t ripple/rippled:$CIRCLE_SHA1 build/docker/
docker tag ripple/rippled:$CIRCLE_SHA1 ripple/rippled:latest
if [ -z "$CIRCLE_PR_NUMBER" ]; then
docker tag ripple/rippled:$CIRCLE_SHA1 ripple/rippled:$CIRCLE_BRANCH
fi

View File

@@ -1,16 +0,0 @@
set -e
if [ -z "$DOCKER_EMAIL" -o -z "$DOCKER_USERNAME" -o -z "$DOCKER_PASSWORD" ];then
echo "Docker credentials are not set. Can't login to docker, no containers will be pushed."
exit 0
fi
if [ -n "$CIRCLE_PR_NUMBER" ]; then
echo "Not pushing results of a pull request build."
exit 0
fi
docker login -e $DOCKER_EMAIL -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
docker push ripple/rippled:$CIRCLE_SHA1
docker push ripple/rippled:$CIRCLE_BRANCH
docker push ripple/rippled:latest

View File

@@ -1,31 +0,0 @@
**Requirements**
1. Java Runtime Environment (JRE)
2. Eclipse with CDT (tested on Luna):
http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/lunasr2
3. Eclipse SCons plugin: http://sconsolidator.com/
**WARNING**: by default the SCons plugin uses 16 threads. Go to
*Window->Preferences->SCons->Build Settings* in Eclipse and make it
use only 4-8 jobs(threads) or whatever you feel confortable with. It will
positively freeze your system if you run with 16 threads/jobs.
![scons](scons.png)
**Getting Started**
After setting up Eclipse just do a File->New->Other...
Select: C/C++ / New SCons project from existing source
Point the importer to the folder where the SConstruct resides (the root
folder of your git workspace normally)
**Build**
Just hit Project->Build All in Eclipse to get started. And remember to not
let it run 16 threads!
**Debug**
Start a new Eclipse debug configuration and set binary to run to build/rippled
(assuming you have built it).
![debug](debug.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,22 +0,0 @@
#!/usr/bin/env bash
#
# This scripts installs the dependencies needed by rippled. It should be run
# with sudo.
#
if [ ! -f /etc/fedora-release ]; then
echo "This script is meant to be run on fedora"
exit 1
fi
fedora_release=$(grep -o '[0-9]*' /etc/fedora-release)
if (( $(bc <<< "${fedora_release} < 22") )); then
echo "This script is meant to run on fedora 22 or greater"
exit 1
fi
yum -y update
yum -y group install "Development Tools"
yum -y install gcc-c++ scons openssl-devel openssl-static protobuf-devel protobuf-static boost-devel boost-static libstdc++-static

View File

@@ -1,5 +0,0 @@
# QTCreator
Makefile
*.user

View File

@@ -1,112 +0,0 @@
# Ripple protocol buffers
PROTOS = ../../src/ripple_data/protocol/ripple.proto
PROTOS_DIR = ../../build/proto
# Google Protocol Buffers support
protobuf_h.name = protobuf header
protobuf_h.input = PROTOS
protobuf_h.output = $${PROTOS_DIR}/${QMAKE_FILE_BASE}.pb.h
protobuf_h.depends = ${QMAKE_FILE_NAME}
protobuf_h.commands = protoc --cpp_out=$${PROTOS_DIR} --proto_path=${QMAKE_FILE_PATH} ${QMAKE_FILE_NAME}
protobuf_h.variable_out = HEADERS
QMAKE_EXTRA_COMPILERS += protobuf_h
protobuf_cc.name = protobuf implementation
protobuf_cc.input = PROTOS
protobuf_cc.output = $${PROTOS_DIR}/${QMAKE_FILE_BASE}.pb.cc
protobuf_cc.depends = $${PROTOS_DIR}/${QMAKE_FILE_BASE}.pb.h
protobuf_cc.commands = $$escape_expand(\\n)
#protobuf_cc.variable_out = SOURCES
QMAKE_EXTRA_COMPILERS += protobuf_cc
# Ripple compilation
DESTDIR = ../../build/QtCreator
OBJECTS_DIR = ../../build/QtCreator/obj
TEMPLATE = app
CONFIG += console thread warn_off
CONFIG -= qt gui
DEFINES += _DEBUG
linux-g++:QMAKE_CXXFLAGS += \
-Wall \
-Wno-sign-compare \
-Wno-char-subscripts \
-Wno-invalid-offsetof \
-Wno-unused-parameter \
-Wformat \
-O0 \
-std=c++11 \
-pthread
INCLUDEPATH += \
"../../src/leveldb/" \
"../../src/leveldb/port" \
"../../src/leveldb/include" \
$${PROTOS_DIR}
OTHER_FILES += \
# $$files(../../src/*, true) \
# $$files(../../src/beast/*) \
# $$files(../../src/beast/modules/beast_basics/diagnostic/*)
# $$files(../../src/beast/modules/beast_core/, true)
UI_HEADERS_DIR += ../../src/ripple_basics
# ---------
# New style
#
SOURCES += \
../../src/ripple/beast/ripple_beast.unity.cpp \
../../src/ripple/beast/ripple_beastc.c \
../../src/ripple/common/ripple_common.unity.cpp \
../../src/ripple/http/ripple_http.unity.cpp \
../../src/ripple/json/ripple_json.unity.cpp \
../../src/ripple/peerfinder/ripple_peerfinder.unity.cpp \
../../src/ripple/radmap/ripple_radmap.unity.cpp \
../../src/ripple/resource/ripple_resource.unity.cpp \
../../src/ripple/sitefiles/ripple_sitefiles.unity.cpp \
../../src/ripple/sslutil/ripple_sslutil.unity.cpp \
../../src/ripple/testoverlay/ripple_testoverlay.unity.cpp \
../../src/ripple/types/ripple_types.unity.cpp \
../../src/ripple/validators/ripple_validators.unity.cpp
# ---------
# Old style
#
SOURCES += \
../../src/ripple_app/ripple_app.unity.cpp \
../../src/ripple_app/ripple_app_pt1.unity.cpp \
../../src/ripple_app/ripple_app_pt2.unity.cpp \
../../src/ripple_app/ripple_app_pt3.unity.cpp \
../../src/ripple_app/ripple_app_pt4.unity.cpp \
../../src/ripple_app/ripple_app_pt5.unity.cpp \
../../src/ripple_app/ripple_app_pt6.unity.cpp \
../../src/ripple_app/ripple_app_pt7.unity.cpp \
../../src/ripple_app/ripple_app_pt8.unity.cpp \
../../src/ripple_basics/ripple_basics.unity.cpp \
../../src/ripple_core/ripple_core.unity.cpp \
../../src/ripple_data/ripple_data.unity.cpp \
../../src/ripple_hyperleveldb/ripple_hyperleveldb.unity.cpp \
../../src/ripple_leveldb/ripple_leveldb.unity.cpp \
../../src/ripple_net/ripple_net.unity.cpp \
../../src/ripple_overlay/ripple_overlay.unity.cpp \
../../src/ripple_rpc/ripple_rpc.unity.cpp \
../../src/ripple_websocket/ripple_websocket.unity.cpp
LIBS += \
-lboost_date_time-mt\
-lboost_filesystem-mt \
-lboost_program_options-mt \
-lboost_regex-mt \
-lboost_system-mt \
-lboost_thread-mt \
-lboost_random-mt \
-lprotobuf \
-lssl \
-lrt

View File

@@ -22,15 +22,10 @@ Invocation:
The build must succeed without shell aliases for this to work.
To pass flags to scons, put them at the very end of the command line, after
To pass flags to cmake, put them at the very end of the command line, after
the -- flag - like this:
./Builds/Test.py -- -j4 # Pass -j4 to scons.
To build with CMake, use the --cmake flag, or any of the specific configuration
flags
./Builds/Test.py --cmake -- -j4 # Pass -j4 to cmake --build
./Builds/Test.py -- -j4 # Pass -j4 to cmake --build
Common problems:
@@ -39,11 +34,7 @@ Common problems:
2) OpenSSL not found. Solution: export OPENSSL_ROOT=[path to OpenSSL folder]
3) scons is an alias. Solution: Create a script named "scons" somewhere in
your $PATH (eg. ~/bin/scons will often work).
#!/bin/sh
python /C/Python27/Scripts/scons.py "${@}"
3) cmake is not found. Solution: Be sure cmake directory is on your $PATH
"""
from __future__ import absolute_import, division, print_function, unicode_literals
@@ -97,28 +88,6 @@ else:
[tuple(x) for x in powerset(['-GNinja', '-Dstatic=true', '-Dassert=true', '-Dsan=address'])] +
[tuple(x) for x in powerset(['-GNinja', '-Dstatic=true', '-Dassert=true', '-Dsan=thread'])]))
# Scons
if IS_WINDOWS or IS_OS_X:
ALL_TARGETS = [('debug',), ('release',)]
else:
ALL_TARGETS = [(cc + "." + target,)
for cc in ['gcc', 'clang']
for target in ['debug', 'release', 'coverage', 'profile',
'debug.nounity', 'release.nounity', 'coverage.nounity', 'profile.nounity']]
# list of tuples of all possible options
if IS_WINDOWS or IS_OS_X:
ALL_OPTIONS = [tuple(x) for x in powerset(['--ninja', '--assert'])]
else:
ALL_OPTIONS = list(set(
[tuple(x) for x in powerset(['--ninja', '--static', '--assert', '--sanitize=address'])] +
[tuple(x) for x in powerset(['--ninja', '--static', '--assert', '--sanitize=thread'])]))
# list of tuples of all possible options + all possible targets
ALL_BUILDS = [options + target
for target in ALL_TARGETS
for options in ALL_OPTIONS]
parser = argparse.ArgumentParser(
description='Test.py - run ripple tests'
)
@@ -173,26 +142,11 @@ parser.add_argument(
help='Reduce output where possible (unit tests)',
)
# Scons and CMake parameters are too different to run
# both side-by-side
pgroup = parser.add_mutually_exclusive_group()
pgroup.add_argument(
'--cmake',
action='store_true',
help='Build using CMake.',
)
pgroup.add_argument(
'--scons',
action='store_true',
help='Build using Scons. Default behavior.')
parser.add_argument(
'--dir', '-d',
default=(),
nargs='*',
help='Specify one or more CMake dir names. Implies --cmake. '
help='Specify one or more CMake dir names. '
'Will also be used as -Dtarget=<dir> running cmake.'
)
@@ -200,7 +154,7 @@ parser.add_argument(
'--target',
default=(),
nargs='*',
help='Specify one or more CMake build targets. Implies --cmake. '
help='Specify one or more CMake build targets. '
'Will be used as --target <target> running cmake --build.'
)
@@ -208,7 +162,7 @@ parser.add_argument(
'--config',
default=(),
nargs='*',
help='Specify one or more CMake build configs. Implies --cmake. '
help='Specify one or more CMake build configs. '
'Will be used as --config <config> running cmake --build.'
)
@@ -216,14 +170,14 @@ parser.add_argument(
'--generator_option',
action='append',
help='Specify a CMake generator option. Repeat for multiple options. '
'Implies --cmake. Will be passed to the cmake generator. '
'Will be passed to the cmake generator. '
'Due to limits of the argument parser, arguments starting with \'-\' '
'must be attached to this option. e.g. --generator_option=-GNinja.')
parser.add_argument(
'--build_option',
action='append',
help='Specify a build option. Repeat for multiple options. Implies --cmake. '
help='Specify a build option. Repeat for multiple options. '
'Will be passed to the build tool via cmake --build. '
'Due to limits of the argument parser, arguments starting with \'-\' '
'must be attached to this option. e.g. --build_option=-j8.')
@@ -253,7 +207,7 @@ def shell(cmd, args=(), silent=False):
command = (cmd,) + args
# shell is needed in Windows to find scons in the path
# shell is needed in Windows to find executable in the path
process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
@@ -284,58 +238,6 @@ def shell(cmd, args=(), silent=False):
process.wait()
return process.returncode, lines
def run_tests(args):
failed = []
if IS_WINDOWS:
binary_re = re.compile(r'build\\([^\\]+)\\rippled.exe')
else:
binary_re = re.compile(r'build/([^/]+)/rippled')
_, lines = shell('scons', ('-n', '--tree=derived',) + args, silent=True)
for line in lines:
match = binary_re.search(line)
if match:
executable, target = match.group(0, 1)
print('Unit tests for', target)
testflag = '--unittest'
quiet = ''
if ARGS.test:
testflag += ('=' + ARGS.test)
if ARGS.quiet:
quiet = '-q'
if ARGS.testjobs:
testjobs = ('--unittest-jobs=' + str(ARGS.testjobs))
resultcode, lines = shell(executable, (testflag, quiet, testjobs,))
if resultcode:
if not ARGS.verbose:
print('ERROR:', *lines, sep='')
failed.append([target, 'unittest'])
if not ARGS.keep_going:
break
return failed
def run_build(args=None):
print('Building:', *args or ('(default)',))
resultcode, lines = shell('scons', args)
if resultcode:
print('Build FAILED:')
if not ARGS.verbose:
print(*lines, sep='')
sys.exit(1)
if '--ninja' in args:
resultcode, lines = shell('ninja')
if resultcode:
print('Ninja build FAILED:')
if not ARGS.verbose:
print(*lines, sep='')
sys.exit(1)
def get_cmake_dir(cmake_dir):
return os.path.join('build' , 'cmake' , cmake_dir)
@@ -407,92 +309,54 @@ def run_cmake_tests(directory, target, config):
def main():
all_failed = []
if ARGS.dir or ARGS.target or ARGS.config or ARGS.build_option or ARGS.generator_option:
ARGS.cmake=True
if not ARGS.cmake:
if ARGS.all:
to_build = ALL_BUILDS
else:
to_build = [tuple(ARGS.extra_args)]
for build in to_build:
args = ()
# additional arguments come first
for arg in list(ARGS.extra_args):
if arg not in build:
args += (arg,)
args += build
run_build(args)
failed = run_tests(args)
if failed:
print('FAILED:', *(':'.join(f) for f in failed))
if not ARGS.keep_going:
sys.exit(1)
else:
all_failed.extend([','.join(build), ':'.join(f)]
for f in failed)
else:
print('Success')
if ARGS.clean:
shutil.rmtree('build')
if '--ninja' in args:
os.remove('build.ninja')
os.remove('.ninja_deps')
os.remove('.ninja_log')
if ARGS.all:
build_dir_targets = CMAKE_DIR_TARGETS
generator_options = CMAKE_ALL_GENERATE_OPTIONS
else:
if ARGS.all:
build_dir_targets = CMAKE_DIR_TARGETS
generator_options = CMAKE_ALL_GENERATE_OPTIONS
build_dir_targets = { tuple(ARGS.dir) : [ARGS.target, ARGS.config] }
if ARGS.generator_option:
generator_options = [tuple(ARGS.generator_option)]
else:
build_dir_targets = { tuple(ARGS.dir) : [ARGS.target, ARGS.config] }
if ARGS.generator_option:
generator_options = [tuple(ARGS.generator_option)]
else:
generator_options = [tuple()]
generator_options = [tuple()]
if not build_dir_targets:
# Let CMake choose the build tool.
build_dir_targets = { () : [] }
if not build_dir_targets:
# Let CMake choose the build tool.
build_dir_targets = { () : [] }
if ARGS.build_option:
ARGS.build_option = ARGS.build_option + list(ARGS.extra_args)
else:
ARGS.build_option = list(ARGS.extra_args)
if ARGS.build_option:
ARGS.build_option = ARGS.build_option + list(ARGS.extra_args)
else:
ARGS.build_option = list(ARGS.extra_args)
for args in generator_options:
for build_dirs, (build_targets, build_configs) in build_dir_targets.items():
if not build_dirs:
build_dirs = ('default',)
if not build_targets:
build_targets = ('rippled',)
if not build_configs:
build_configs = ('',)
for cmake_dir in build_dirs:
cmake_full_dir = get_cmake_dir(cmake_dir)
run_cmake(cmake_full_dir, cmake_dir, args)
for args in generator_options:
for build_dirs, (build_targets, build_configs) in build_dir_targets.items():
if not build_dirs:
build_dirs = ('default',)
if not build_targets:
build_targets = ('rippled',)
if not build_configs:
build_configs = ('',)
for cmake_dir in build_dirs:
cmake_full_dir = get_cmake_dir(cmake_dir)
run_cmake(cmake_full_dir, cmake_dir, args)
for target in build_targets:
for config in build_configs:
run_cmake_build(cmake_full_dir, target, config, ARGS.build_option)
failed = run_cmake_tests(cmake_full_dir, target, config)
for target in build_targets:
for config in build_configs:
run_cmake_build(cmake_full_dir, target, config, ARGS.build_option)
failed = run_cmake_tests(cmake_full_dir, target, config)
if failed:
print('FAILED:', *(':'.join(f) for f in failed))
if not ARGS.keep_going:
sys.exit(1)
else:
all_failed.extend([decodeString(cmake_dir +
"." + target + "." + config), ':'.join(f)]
for f in failed)
if failed:
print('FAILED:', *(':'.join(f) for f in failed))
if not ARGS.keep_going:
sys.exit(1)
else:
print('Success')
if ARGS.clean:
shutil.rmtree(cmake_full_dir)
all_failed.extend([decodeString(cmake_dir +
"." + target + "." + config), ':'.join(f)]
for f in failed)
else:
print('Success')
if ARGS.clean:
shutil.rmtree(cmake_full_dir)
if all_failed:
if len(all_failed) > 1:

View File

@@ -1,82 +0,0 @@
#!/usr/bin/env bash
#
# This scripts installs boost and protobuf built with clang. This is needed on
# ubuntu 15.10 when building with clang
# It will build these in a 'clang' subdirectory that it creates below the directory
# this script is run from. If a clang directory already exists the script will refuse
# to run.
if hash lsb_release 2>/dev/null; then
if [ $(lsb_release -si) == "Ubuntu" ]; then
ubuntu_release=$(lsb_release -sr)
fi
fi
if [ -z "${ubuntu_release}" ]; then
echo "System not supported"
exit 1
fi
if ! hash clang 2>/dev/null; then
clang_version=3.7
if [ ${ubuntu_release} == "16.04" ]; then
clang_version=3.8
fi
sudo apt-get -y install clang-${clang_version}
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clang_version} 99 clang++
hash -r
if ! hash clang 2>/dev/null; then
echo "Please install clang"
exit 1
fi
fi
if [ ${ubuntu_release} != "16.04" ] && [ ${ubuntu_release} != "15.10" ]; then
echo "clang specific boost and protobuf not needed"
exit 0
fi
if [ -d clang ]; then
echo "clang directory already exists. Cowardly refusing to run"
exit 1
fi
if ! hash wget 2>/dev/null; then
sudo apt-get -y install wget
hash -r
if ! hash wget 2>/dev/null; then
echo "Please install wget"
exit 1
fi
fi
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # pysical cores
mkdir clang
pushd clang > /dev/null
# Install protobuf
pb=protobuf-2.6.1
pb_tar=${pb}.tar.gz
wget -O ${pb_tar} https://github.com/google/protobuf/releases/download/v2.6.1/${pb_tar}
tar xf ${pb_tar}
rm ${pb_tar}
pushd ${pb} > /dev/null
./configure CC=clang CXX=clang++ CXXFLAGS='-std=c++14 -O3 -g'
make -j${num_procs}
popd > /dev/null
# Install boost
boost_ver=1.60.0
bd=boost_${boost_ver//./_}
bd_tar=${bd}.tar.gz
wget -O ${bd_tar} http://sourceforge.net/projects/boost/files/boost/${boost_ver}/${bd_tar}
tar xf ${bd_tar}
rm ${bd_tar}
pushd ${bd} > /dev/null
./bootstrap.sh
./b2 toolset=clang -j${num_procs}
popd > /dev/null
popd > /dev/null

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env bash
#
# This script builds boost with the correct ABI flags for ubuntu
#
version=63
patch=0
if hash lsb_release 2>/dev/null; then
if [ $(lsb_release -si) == "Ubuntu" ]; then
ubuntu_release=$(lsb_release -sr)
fi
fi
if [ -z "${ubuntu_release}" ]; then
echo "System not supported"
exit 1
fi
extra_defines=""
if (( $(bc <<< "${ubuntu_release} < 15.1") )); then
extra_defines="define=_GLIBCXX_USE_CXX11_ABI=0"
fi
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # pysical cores
printf "\nBuild command will be: ./b2 -j${num_procs} ${extra_defines}\n\n"
boost_dir="boost_1_${version}_${patch}"
boost_tag="boost-1.${version}.${patch}"
git clone -b "${boost_tag}" --recursive https://github.com/boostorg/boost.git "${boost_dir}"
cd ${boost_dir}
git checkout --force ${boost_tag}
git submodule foreach git checkout --force ${boost_tag}
./bootstrap.sh
./b2 headers
./b2 -j${num_procs} ${extra_defines}
echo "Build command was: ./b2 -j${num_procs} ${extra_defines}"
echo "Don't forget to set BOOST_ROOT!"

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env bash
#
# This scripts installs the dependencies needed by rippled. It should be run
# with sudo. For ubuntu < 15.10, it installs gcc 5 as the default compiler. gcc
# 5 is ABI incompatable with gcc 4. If needed, the following will switch back to
# gcc-4: `sudo update-alternatives --config gcc` and choosing the gcc-4
# option.
#
if hash lsb_release 2>/dev/null; then
if [ $(lsb_release -si) == "Ubuntu" ]; then
ubuntu_release=$(lsb_release -sr)
fi
fi
if [ -z "${ubuntu_release}" ]; then
echo "System not supported"
exit 1
fi
if [ ${ubuntu_release} == "14.04" ] || [ ${ubuntu_release} == "15.04" ]; then
apt-get install python-software-properties
echo "deb [arch=amd64] https://mirrors.ripple.com/ubuntu/ trusty stable contrib" | sudo tee /etc/apt/sources.list.d/ripple.list
wget -O- -q https://mirrors.ripple.com/mirrors.ripple.com.gpg.key | sudo apt-key add -
add-apt-repository ppa:ubuntu-toolchain-r/test
apt-get update
apt-get -y upgrade
apt-get -y install curl git cmake ctags pkg-config protobuf-compiler libprotobuf-dev libssl-dev python-software-properties boost-all-dev g++-5 g++-4.9
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 99 --slave /usr/bin/g++ g++ /usr/bin/g++-5
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 99 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9
exit 0
fi
# Test if 0th parameter has a version number greater than or equal to the 1st param
function version_check() { test "$(printf '%s\n' "$@" | sort -V | tail -n 1)" == "$1"; }
# this should work for versions greater than 15.10
if version_check ${ubuntu_release} 15.10; then
apt-get update
apt-get -y upgrade
apt-get -y install python-software-properties curl git cmake ctags pkg-config protobuf-compiler libprotobuf-dev libssl-dev python-software-properties libboost-all-dev
exit 0
fi
echo "System not supported"
exit 1

View File

@@ -1,4 +0,0 @@
RippleD.vcxproj -text
RippleD.vcxproj.filters -text

View File

@@ -1,255 +0,0 @@
# Visual Studio 2015 Build Instructions
## Important
We do not recommend Windows for rippled production use at this time. Currently, the Ubuntu
platform has received the highest level of quality assurance, testing, and support.
Additionally, 32-bit Windows versions are not supported.
## Prerequisites
To clone the source code repository, create branches for inspection or modification,
build rippled under Visual Studio, and run the unit tests you will need these
software components:
* [Visual Studio 2015](README.md#install-visual-studio-2015)
* [Git for Windows](README.md#install-git-for-windows)
* [Google Protocol Buffers Compiler](README.md#install-google-protocol-buffers-compiler)
* (Optional) [Python and Scons](README.md#optional-install-python-and-scons)
* [OpenSSL Library](README.md#install-openssl)
* [Boost library](README.md#build-boost)
## Install Software
### Install Visual Studio 2015
If not already installed on your system, download your choice of installer from the
[Visual Studio 2015 Download](https://www.visualstudio.com/downloads/download-visual-studio-vs)
page, run the installer, and follow the directions. You may need to choose a "Custom"
installation and ensure that "Visual C++" is selected under "Programming Languages".
Any version of Visual Studio 2015 may be used to build rippled.
The **Visual Studio 2015 Community** edition is available free of charge (see
[the product page](https://www.visualstudio.com/products/visual-studio-community-vs)
for licensing details), while paid editions may be used for an free initial trial period.
### Install Git for Windows
Git is a distributed revision control system. The Windows version also provides the
bash shell and many Windows versions of Unix commands. While there are other
varieties of Git (such as TortoiseGit, which has a native Windows interface and
integrates with the Explorer shell), we recommend installing
[Git for Windows](https://git-scm.com/) since
it provides a Unix-like command line environment useful for running shell scripts.
Use of the bash shell under Windows is mandatory for running the unit tests.
* NOTE: To gain full featured access to the
[git-subtree](https://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/)
functionality used in the rippled repository we suggest Git version 2.6.2 or later.
### Install Google Protocol Buffers Compiler
Building rippled requires **protoc.exe** version 2.5.1 or later. At your option you
may build it yourself from the sources in the
[Google Protocol Buffers](https://github.com/google/protobuf) repository,
or you may download a
[protoc.exe](https://ripple.github.io/Downloads/protoc/2.5.1/protoc.exe)
([alternate link](https://github.com/ripple/Downloads/raw/gh-pages/protoc/2.5.1/protoc.exe))
precompiled Windows executable from the
[Ripple Organization](https://github.com/ripple).
Either way, once you have the required version of **protoc.exe**, copy it into
a folder in your command line `%PATH%`.
* **NOTE:** If you use an older version of the compiler, the build will
fail with errors related to a mismatch of the version of protocol
buffer headers versus the compiler.
### (Optional) Install Python and Scons
[Python](https://www.python.org/downloads/) and
[Scons](http://scons.org/download.php) are not required to build
rippled with Visual Studio, but can be used to build from the
command line and in scripts, and are required to properly update
the `RippleD.vcxproj` file.
If you wish to build with scons, a version after 2.3.5 is required
for Visual Studio 2015 support.
## Configure Dependencies
### Install OpenSSL
[Download OpenSSL.](http://slproweb.com/products/Win32OpenSSL.html)
There will be four variants available:
1. 64-bit. Use this if you are running 64-bit windows. As of this writing, the link is called: "Win64 OpenSSL v1.0.2j".
2. 64-bit light - Don't use this. It is missing files needed to build rippled. As of this writing, the link is called: "Win64 OpenSSL v1.0.2j Light"
Run the installer, and choose an appropriate location for your OpenSSL
installation. In this guide we use **C:\lib\OpenSSL-Win64** as the
destination location.
You may be informed on running the installer that "Visual C++ 2008
Redistributables" must first be installed first. If so, download it
from the [same page](http://slproweb.com/products/Win32OpenSSL.html),
again making sure to get the correct 32-/64-bit variant.
* NOTE: Since rippled links statically to OpenSSL, it does not matter
where the OpenSSL .DLL files are placed, or what version they are.
rippled does not use or require any external .DLL files to run
other than the standard operating system ones.
### Build Boost
After [downloading boost](http://www.boost.org/users/download/) and
unpacking it, open a **Developer Command Prompt** for
Visual Studio, change to the directory containing boost, then
bootstrap the build tools:
(As of this writing, the most recent version of boost is 1.62.0, which
will unpack into a directory named `boost_1_62_0`. For higher versions
of boost, adjust the directories provided in these examples as
appropriate.)
```powershell
cd C:\lib\boost_1_62_0
bootstrap
```
The rippled application is linked statically to the standard runtimes and external
dependencies on Windows, to ensure that the behavior of the executable is not
affected by changes in outside files. Therefore, it is necessary to build the
required boost static libraries using this command:
```powershell
bjam --toolset=msvc-14.0 address-model=64 architecture=x86 link=static threading=multi runtime-link=shared,static stage --stagedir=stage64
```
Building the boost libraries may take considerable time. When the build process
is completed, take note of both the reported compiler include paths and linker
library paths as they will be required later.
* NOTE: If older versions of Visual Studio are also installed, the build may fail.
If this happens, make sure that only Visual Studio 2015 is installed. Due to
defects in the uninstallation procedures of these Microsoft products, it may
be necessary to start with a fresh install of the operating system with only
the necessary development environment components installed to have a successful build.
### Clone the rippled repository
If you are familiar with cloning github repositories, just follow your normal process
and clone `git@github.com:ripple/rippled.git`. Otherwise follow this section for instructions.
1. If you don't have a github account, sign up for one at
[github.com](https://github.com/).
2. Make sure you have Github ssh keys. For help see
[generating-ssh-keys](https://help.github.com/articles/generating-ssh-keys).
Open the "Git Bash" shell that was installed with "Git for Windows" in the
step above. Navigate to the directory where you want to clone rippled (git
bash uses `/c` for windows's `C:` and forward slash where windows uses
backslash, so `C:\Users\joe\projs` would be `/c/Users/joe/projs` in git bash).
Now clone the repository and optionally switch to the *master* branch.
Type the following at the bash prompt:
```powershell
git clone git@github.com:ripple/rippled.git
cd rippled
git checkout master
```
* If you receive an error about not having the "correct access rights"
make sure you have Github ssh keys, as described above.
### Configure Library Paths
Open the solution file located at **Builds/Visual Studio 2015/ripple.sln**
and select the "View->Property Manager" to bring up the Property Manager.
Expand the *debug | x64* section and
double click the *Microsoft.Cpp.x64.user* property sheet to bring up the
*Property Pages* dialog. These are global properties applied to all
64-bit build targets:
![Visual Studio 2015 Global Properties](images/VS2015x64Properties.png)
Go to *C/C++, General, Additional Include Directories* and add the
location of the boost installation:
![Visual Studio 2015 Include Directories](images/VS2015x64IncludeDirs.png)
Then, go to *Linker, General, Additional Library Directories* and add
the location of the compiled boost libraries reported at the completion
of building the boost libraries:
![Visual Studio 2015 Library Directories](images/VS2015x64LibraryDirs.png)
Follow the same procedure for adding the `Additional Include Directories`
and `Additional Library Directories` required for OpenSSL. In our example
these directories are **C:\lib\OpenSSL-Win64\include** and
**C:\lib\OpenSSL-Win64\lib** respectively.
# Setup Environment
## Create a working directory for rippled.cfg
The rippled server uses the [Rippled.cfg](https://wiki.ripple.com/Rippled.cfg)
file to read its configuration parameters. This section describes setting up
a directory to hold the config file. The next sections describe how to tell
the rippled server where that file is.
1. Create a directory to hold the configuration file. In this example, the
ripple config directory was created in `C:\Users\joe\ripple\config`.
2. Copy the example config file located in `cfg\rippled-example.cfg` to the
new directory and rename it "rippled.cfg".
3. Read the rippled.cfg file and edit as appropriate.
## Change the Visual Studio Projects Debugging Properties
1. If not already open, open the solution file located at **Builds/Visual Studio 2015/Ripple.sln**
2. Select the correct solution platform in the solution platform dropdown (either *x64*
or *Win32* depending on machine type).
3. Select the "Project->Properties" menu item to bring up RippleD's Properties Pages
4. In "Configuration Properties" select "Debugging".
5. In the upper-left Configurations drop down, select "All Configurations".
6. In "Debugger to Launch" select "Local Windows Debugger".
### Tell rippled where to find the configuration file.
The `--conf` command-line switch to tell rippled where to find this file.
In the "Command Arguments" field in the properties dialog (that you opened
in the above section), add: `--conf="C:/Users/joe/ripple/config/rippled.cfg"`
(of course replacing that path with the path you set up above).
![Visual Studio 2013 Command Args Prop Page](images/VSCommandArgsPropPage.png)
### Set the _NO_DEBUG_HEAP Environment Variable
Rippled can run very slowly in the debugger when using the Windows Debug Heap.
Set the `_NO_DEBUG_HEAP` environment variable to one to disable the debug heap.
In the "Environment" field (that you opened in the above section), add:
`_NO_DEBUG_HEAP=1`
![Visual Studio 2013 No Debug Heap Prop Page](images/NoDebugHeapPropPage.png)
# Build
After these steps are complete, rippled should be ready to build. Simply
set rippled as the startup project by right clicking on it in the
Visual Studio Solution Explorer, choose **Set as Startup Project**,
and then choose the **Build->Build Solution** menu item.
# Unit Tests (Recommended)
The rippled unit tests are written in C++ and are part
of the rippled executable.
From a Windows console, run the unit tests:
```
./build/msvc.debug/rippled.exe --unittest
```
Substitute the correct path to the executable to test different builds.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,36 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug.classic|x64 = debug.classic|x64
debug.classic|x86 = debug.classic|x86
debug|x64 = debug|x64
debug|x86 = debug|x86
release.classic|x64 = release.classic|x64
release.classic|x86 = release.classic|x86
release|x64 = release|x64
release|x86 = release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.ActiveCfg = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.Build.0 = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x86.ActiveCfg = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x86.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.ActiveCfg = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.Build.0 = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x86.ActiveCfg = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.Build.0 = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x86.ActiveCfg = release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -5,4 +5,3 @@ num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # number of ph
path=$(cd $(dirname $0) && pwd)
cd $(dirname $path)
${path}/Test.py -a -c --testjobs=${num_procs} -- -j${num_procs}
${path}/Test.py -a -c -k --cmake --testjobs=${num_procs} -- -j${num_procs}

147
Builds/linux/README.md Normal file
View File

@@ -0,0 +1,147 @@
# Linux Build Instructions
This document focuses on building rippled for development purposes under recent
Ubuntu linux distributions. To build rippled for Redhat, Fedora or Centos
builds, including docker based builds for those distributions, please consult
the [rippled-package-builder](https://github.com/ripple/rippled-package-builder)
repository.
Development is regularly done on Ubuntu 16.04 or later. For non Ubuntu
distributions, the steps below should work be installing the appropriate
dependencies using that distribution's package management tools.
## Dependencies
Use `apt-get` to install the dependencies provided by the distribution
```
$ apt-get update
$ apt-get install -y gcc g++ wget git cmake protobuf-compiler libprotobuf-dev libssl-dev
```
Advanced users can choose to install newer versions of gcc, or the clang compiler.
At this time, rippled only supports protobuf version 2. Using version 3 of
protobuf will give errors.
### Build Boost
We recommend downloading and compiling a more recent version of boost than
provided by the `boost-all-dev` package. After changing to the directory where
you wish to download and compile boost, run
```
$ wget https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.gz
$ tar -xzf boost_1_65_1.tar.gz
$ cd boost_1_65_1
$ ./bootstrap.sh
$ ./b2 headers
$ ./b2 -j<Num Parallel>
```
### (Optional) Dependencies for Building Source Documentation
Source code documentation is not required for running/debugging rippled. That
said, the documentation contains some helpful information about specific
components of the application. For more information on how to install and run
the necessary components, see [this document](../../docs/README.md)
## Build
### Clone the rippled repository
From a shell:
```
git clone git@github.com:ripple/rippled.git
cd rippled
```
For a stable release, choose the `master` branch or one of the tagged releases
listed on [GitHub](https://github.com/ripple/rippled/releases).
```
git checkout master
```
or to test the latest release candidate, choose the `release` branch.
```
git checkout release
```
If you are doing development work and want the latest set of untested
features, you can consider using the `develop` branch instead.
```
git checkout develop
```
### Configure Library Paths
If you didn't persistently set the `BOOST_ROOT` environment variable to the
directory in which you compiled boost, then you should set it temporarily.
For example, you built Boost in your home directory `~/boost_1_65_1`, you
would do for any shell in which you want to build:
```
export BOOST_ROOT=~/boost_1_65_1
```
Alternatively, you can add `DBOOST_ROOT=~/boost_1_65_1` to the command line when
invoking `cmake`.
### Generate and Build
All builds should be done in a separate directory from the source tree root
(a subdirectory is fine). For example, from the root of the ripple source tree:
```
mkdir my_build
cd my_build
```
followed by:
```
cmake -Dtarget=gcc.debug.unity ..
```
The target variable can be adjusted as needed for `gcc` vs `clang`, `debug` vs.
`release` and `unity` vs. `nounity` builds. `unity` builds are typically faster
to compile but run the risk of ODR violations given that multiple compilation
units are merged together at compile time. `nounity` builds will take longer to
compile but align more closely with language standards.
Once you have generated the build system, you can run the build via cmake:
```
cmake --build . -- -j <parallel jobs>
```
the `-j` parameter in this example tells the build tool to compile several
files in parallel. This value should be chosen roughly based on the number of
cores you have available and/or want to use for building.
When the build completes succesfully, you will have a `rippled` executable in
the current directory, which can be used to connect to the network (when
properly configured) or to run unit tests.
#### Options During Configuration:
There are a number of config variables that our CMake files support. These
can be added to the cmake generation command as needed:
* `-Dassert=ON` to enable asserts
* `-Djemalloc=ON` to enable jemalloc support for heap checking
* `-Dsan=thread` to enable the thread sanitizer with clang
* `-Dsan=address` to enable the address sanitizer with clang
* `-Dstatic=ON` to enable static linking library dependencies
## Unit Tests (Recommended)
`rippled` builds a set of unit tests into the server executable. To run these unit
tests after building, pass the `--unittest` option to the compiled `rippled`
executable. The executable will exit with summary info after running the unit tests.

View File

@@ -1,13 +0,0 @@
--- /usr/include/boost/config/compiler/clang.hpp 2013-07-20 13:17:10.000000000 -0400
+++ /usr/include/boost/config/compiler/clang.rippled.hpp 2014-03-11 16:40:51.000000000 -0400
@@ -39,6 +39,10 @@
// Clang supports "long long" in all compilation modes.
#define BOOST_HAS_LONG_LONG
+#if defined(__SIZEOF_INT128__)
+# define BOOST_HAS_INT128
+#endif
+
//
// Dynamic shared object (DSO) and dynamic-link library (DLL) support
//

View File

@@ -1,10 +0,0 @@
--- /usr/include/boost/bimap/detail/debug/static_error.hpp 2008-03-22 17:45:55.000000000 -0400
+++ /usr/include/boost/bimap/detail/debug/static_error.rippled.hpp 2014-03-12 19:40:05.000000000 -0400
@@ -25,7 +25,6 @@
// a static error.
/*===========================================================================*/
#define BOOST_BIMAP_STATIC_ERROR(MESSAGE,VARIABLES) \
- struct BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE) {}; \
BOOST_MPL_ASSERT_MSG(false, \
BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE), \
VARIABLES)

View File

@@ -1,63 +1,58 @@
# !!! The official build system is SConstruct !!!
# This is an experimental cmake build file for rippled
# cmake support for building rippled. The rippled specific settings
# below can be set at the command line as `-D<setting>=<value>`.
#
# cmake support in rippled. Currently supports:
# * `target` is a period separated tuple from the sets
# {gcc,clang,msvc} x {debug, release} x {unity, nounity} x {coverage} x {profile}
#
# * unity/nounity debug/release
# * running protobuf
# * sanitizer builds
# * optional release build with assert turned on
# * `target` variable to easily set compiler/debug/unity
# (i.e. -Dtarget=gcc.debug.nounity)
# * gcc/clang/visual studio/xcode
# * linux/mac/win
# * gcc 4 ABI, when needed
# * ninja builds
# * check openssl version on linux
# * static builds (swd TBD: needs to be tested by building & deploying on different systems)
# * jemalloc enabled builds (linux and macos only)
# * perf builds (linux only) - which just sets recommended compiler flags
# for running perf on the executable
# Example, build gcc debug nonunity build
# -Dtarget=gcc.debug.nounity
# Example, clang release unity build
# -Dtarget=clang.release.unity
# Example, visual studio debug unity build
# -Dtarget=msvc.release.unity
# Example, build gcc release unity build suited for profiling with perf
# -Dtarget=gcc.release.unity.profile
# Example, build gcc debug unity build suited for measuring code coverage
# with gcov
# -Dtarget=gcc.release.unity.coverage
#
# Notes:
# * Use the -G"Visual Studio 14 2015 Win64" generator, or the "VS2015 x86 x64
# Cross Tools" Command Prompt on Windows. Without this a 32-bit project will be
# created. There is no way to set the generator or force a 64-bit build in
# CMakeLists.txt (setting CMAKE_GENERATOR_PLATFORM won't work). The best solution
# may be to wrap cmake with a script.
#
# * Ninja command line builds seem to work under Windows, but only from within
# the "VS2015 x86 x64 Cross Tools" Command Prompt.
# The default is a unity debug build using gcc (linux), clang (osx), and
# msvc (windows).
#
# * It is not possible to generate a visual studio project on linux or
# mac. The visual studio generator is only available on windows.
# Note the generated Visual Studio solution will always have two projects,
# one unity and one non-unity. If the `target` is unity, the default project
# will be named `rippled` and second non-default (non-unity) project
# will be called `rippled_classic`. Likewise, if the `target` is non-unity,
# the project will have a default project called `rippled` (now non-unity)
# and second non-default (unity) project `rippled_unity`. In either
# case, only the `rippled` build will be enabled by default.
#
# * The Visual Studio solution will be generated with two projects, one
# unity, one non-unity. Which is default depends on the nounity flag in
# -Dtarget. Unity targets will create `rippled` and `rippled_classic`.
# Non-unity targets will create `rippled` and `rippled_unity`. In either
# case, only the `rippled` build will be enabled by default. It does
# not appear possible to include both unity and non-unity configs in one
# project and disable compilation based on configuration.
# * `assert` whether to enable asserts in release build
#
# * Language is _much_ worse than python, poor documentation and "quirky"
# language support (for example, generator expressions can only be used
# in limited contexts and seem to work differently based on
# context (set_property can set multiple values, add_compile_options
# can not/or is buggy)
# Example, enable asserts even in release builds
# -Dassert=True
#
# * Could not call out to `sed` because cmake messed with the regular
# expression before calling the external command. I did not see a way
# around this.
# Default is not to enable asserts in release builds.
#
# * `san` enable clang sanitizers
#
# Example, enable thread sanitizer
# -Dsan=thread
# Example, enable address sanitizer
# -Dsan=address
#
# * `static`, on linux, link protobuf, openssl, libc++, and boost
# statically.
#
# Example, enable static linking
# -Dstatic=True
#
# * `jemalloc`, on linux, enables jemalloc for heap profiling.
#
# Example, enable jemalloc
# -Djemallc=True
#
# * Makefile generators want to be single target. It wants a separate
# directory for each target type. I saw some mentions on the web for
# ways around this bug haven't look into it. The visual studio project
# does support debug/release configurations in the same project (but
# not unity/non-unity).
############################################################
#########################################################
# CMAKE_C_COMPILER and CMAKE_CXX_COMPILER must be defined
# before the project statement; However, the project

View File

@@ -68,7 +68,7 @@ ISC license. See the LICENSE file for more details.
|---------|----------|
| ./bin | Scripts and data files for Ripple integrators. |
| ./build | Intermediate and final build outputs. |
| ./Builds| Platform or IDE-specific project files. |
| ./Builds| Platform-specific guides for building rippled. |
| ./docs | Source documentation files and doxygen config. |
| ./cfg | Example configuration files. |
| ./src | Source code. |

1314
SConstruct

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
# Set environment variables.
environment:
PYTHON: C:/Python27-x64
# We bundle up protoc.exe and only the parts of boost and openssl we need so
# that it's a small download. We also use appveyor's free cache, avoiding fees
@@ -9,15 +8,7 @@ environment:
RIPPLED_DEPS_PATH: rippled_deps17.01
RIPPLED_DEPS_URL: https://ripple.github.io/Downloads/appveyor/%RIPPLED_DEPS_PATH%.zip
# Other dependencies we just download each time.
PIP_PATH: get-pip.py
PIP_URL: https://bootstrap.pypa.io/%PIP_PATH%
# The % in this URL messes up variable substition, so any updates will
# need to update both PYWIN32_PATH and PYWIN32_URL
PYWIN32_PATH: pywin32-220.win-amd64-py2.7.exe
PYWIN32_URL: https://downloads.sourceforge.net/project/pywin32/pywin32/Build%20220/pywin32-220.win-amd64-py2.7.exe
# Scons honours these environment variables, setting the include/lib paths.
# CMake honors these environment variables, setting the include/lib paths.
BOOST_ROOT: C:/%RIPPLED_DEPS_PATH%/boost
OPENSSL_ROOT: C:/%RIPPLED_DEPS_PATH%/openssl
@@ -27,10 +18,6 @@ environment:
appveyor_build_worker_cloud: gce
matrix:
# This build works, but our current Appveyor config runs matrix builds
# sequentially, and the one build is already slow enough.
# - build: scons
# target: msvc.debug
- build: cmake
target: msvc.debug
buildconfig: Debug
@@ -42,30 +29,14 @@ os: Visual Studio 2017
# Resulting archive should not exceed 100 MB.
cache:
- 'C:\%RIPPLED_DEPS_PATH%'
- '%PIP_PATH%'
- '%PYWIN32_PATH%'
# This means we'll download a zip of the branch we want, rather than the full
# history.
shallow_clone: true
install:
# We want easy_install, python and protoc.exe on PATH.
- SET PATH=%PYTHON%;%PYTHON%/Scripts;C:/%RIPPLED_DEPS_PATH%;%PATH%
# `ps` prefix means the command is executed by powershell.
- ps: |
if ($env:build -eq "scons") {
if(-not(Test-Path $env:PIP_PATH)) {
echo "Download from $env:PIP_URL"
Start-FileDownload $env:PIP_URL
}
if(-not(Test-Path $env:PYWIN32_PATH)) {
echo "Download from $env:PYWIN32_URL"
Start-FileDownload $env:PYWIN32_URL
}
}
- bin/ci/windows/install-dependencies.bat
# We want protoc.exe on PATH.
- SET PATH=C:/%RIPPLED_DEPS_PATH%;%PATH%
# Download dependencies if appveyor didn't restore them from the cache.
# Use 7zip to unzip.
@@ -95,13 +66,6 @@ build_script:
# Show which version of the compiler we are using.
- cl
- ps: |
if ($env:build -eq "scons") {
# Build with scons
scons $env:target -j%NUMBER_OF_PROCESSORS%
if ($LastExitCode -ne 0) { throw "scons build failed" }
}
else
{
# Build with cmake
cmake --version
$cmake_target="$($env:target).ci"
@@ -113,19 +77,10 @@ build_script:
cmake --build . --config $env:buildconfig -- -m
if ($LastExitCode -ne 0) { throw "CMake build failed" }
Pop-Location
}
after_build:
- ps: |
if ($env:build -eq "scons") {
cp build/$($env:target)/rippled.exe build
ls build
$exe="build/rippled"
}
else
{
$exe="build/$cmake_target/$env:buildconfig/rippled"
}
$exe="build/$cmake_target/$env:buildconfig/rippled"
"Exe is at $exe"
test_script:

View File

@@ -31,78 +31,67 @@ else
time=
fi
if [[ ${BUILD:-cmake} == "cmake" ]]; then
echo "cmake building ${APP}"
: ${CMAKE_EXTRA_ARGS:=""}
if [[ ${NINJA_BUILD:-} == true ]]; then
CMAKE_EXTRA_ARGS+=" -G Ninja"
fi
CMAKE_TARGET=${COMPNAME}.${TARGET}
if [[ ${CI:-} == true ]]; then
CMAKE_TARGET=$CMAKE_TARGET.ci
fi
#
# allow explicit setting of the name of the build
# dir, otherwise default to the CMAKE_TARGET value
#
: "${BUILD_DIR:=$CMAKE_TARGET}"
BUILDARGS=" -j${JOBS}"
if [[ ${VERBOSE_BUILD:-} == true ]]; then
CMAKE_EXTRA_ARGS+=" -DCMAKE_VERBOSE_MAKEFILE=ON"
# TODO: if we use a different generator, this
# option to build verbose would need to change:
if [[ ${NINJA_BUILD:-} == true ]]; then
BUILDARGS+=" -v"
else
BUILDARGS+=" verbose=1"
fi
fi
if [[ ${USE_CCACHE:-} == true ]]; then
echo "using ccache with basedir [${CCACHE_BASEDIR:-}]"
CMAKE_EXTRA_ARGS+=" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
fi
if [ -d "build/${BUILD_DIR}" ]; then
rm -rf "build/${BUILD_DIR}"
fi
mkdir -p "build/${BUILD_DIR}"
pushd "build/${BUILD_DIR}"
$time cmake ../.. -Dtarget=$CMAKE_TARGET ${CMAKE_EXTRA_ARGS}
if [[ ${TARGET} == "docs" ]]; then
$time cmake --build . --target docs -- $BUILDARGS
## mimic the standard test output for docs build
## to make controlling processes like jenkins happy
if [ -f html_doc/index.html ]; then
echo "1 case, 1 test total, 0 failures"
else
echo "1 case, 1 test total, 1 failures"
fi
exit
else
$time cmake --build . -- $BUILDARGS
if [[ ${BUILD_BOTH:-} == true ]]; then
if [[ ${TARGET} == *.unity ]]; then
cmake --build . --target rippled_classic -- $BUILDARGS
else
cmake --build . --target rippled_unity -- $BUILDARGS
fi
fi
fi
popd
export APP_PATH="$PWD/build/${BUILD_DIR}/${APP}"
echo "using APP_PATH: $APP_PATH"
else
export APP_PATH="$PWD/build/${COMPNAME}.${TARGET}/${APP}"
echo "using APP_PATH: $APP_PATH"
# Make sure vcxproj is up to date
$time scons vcxproj
git diff --exit-code
# $CC will be either `clang` or `gcc`
# http://docs.travis-ci.com/user/migrating-from-legacy/?utm_source=legacy-notice&utm_medium=banner&utm_campaign=legacy-upgrade
# indicates that 2 cores are available to containers.
$time scons -j${JOBS} ${COMPNAME}.$TARGET
echo "cmake building ${APP}"
: ${CMAKE_EXTRA_ARGS:=""}
if [[ ${NINJA_BUILD:-} == true ]]; then
CMAKE_EXTRA_ARGS+=" -G Ninja"
fi
CMAKE_TARGET=${COMPNAME}.${TARGET}
if [[ ${CI:-} == true ]]; then
CMAKE_TARGET=$CMAKE_TARGET.ci
fi
#
# allow explicit setting of the name of the build
# dir, otherwise default to the CMAKE_TARGET value
#
: "${BUILD_DIR:=$CMAKE_TARGET}"
BUILDARGS=" -j${JOBS}"
if [[ ${VERBOSE_BUILD:-} == true ]]; then
CMAKE_EXTRA_ARGS+=" -DCMAKE_VERBOSE_MAKEFILE=ON"
# TODO: if we use a different generator, this
# option to build verbose would need to change:
if [[ ${NINJA_BUILD:-} == true ]]; then
BUILDARGS+=" -v"
else
BUILDARGS+=" verbose=1"
fi
fi
if [[ ${USE_CCACHE:-} == true ]]; then
echo "using ccache with basedir [${CCACHE_BASEDIR:-}]"
CMAKE_EXTRA_ARGS+=" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
fi
if [ -d "build/${BUILD_DIR}" ]; then
rm -rf "build/${BUILD_DIR}"
fi
mkdir -p "build/${BUILD_DIR}"
pushd "build/${BUILD_DIR}"
$time cmake ../.. -Dtarget=$CMAKE_TARGET ${CMAKE_EXTRA_ARGS}
if [[ ${TARGET} == "docs" ]]; then
$time cmake --build . --target docs -- $BUILDARGS
## mimic the standard test output for docs build
## to make controlling processes like jenkins happy
if [ -f html_doc/index.html ]; then
echo "1 case, 1 test total, 0 failures"
else
echo "1 case, 1 test total, 1 failures"
fi
exit
else
$time cmake --build . -- $BUILDARGS
if [[ ${BUILD_BOTH:-} == true ]]; then
if [[ ${TARGET} == *.unity ]]; then
cmake --build . --target rippled_classic -- $BUILDARGS
else
cmake --build . --target rippled_unity -- $BUILDARGS
fi
fi
fi
popd
export APP_PATH="$PWD/build/${BUILD_DIR}/${APP}"
echo "using APP_PATH: $APP_PATH"
# See what we've actually built
ldd $APP_PATH

View File

@@ -1,13 +0,0 @@
if "%build%" == "scons" (
rem Installing pip will install setuptools/easy_install.
python "%PIP_PATH%"
rem Pip has some problems installing scons on windows so we use easy install.
rem - easy_install scons
rem Workaround
easy_install https://pypi.python.org/packages/source/S/SCons/scons-2.5.0.tar.gz#md5=bda5530a70a41a7831d83c8b191c021e
rem Scons has problems with parallel builds on windows without pywin32.
easy_install "%PYWIN32_PATH%"
rem (easy_install can do headless installs of .exe wizards)
)

View File

@@ -1,29 +0,0 @@
machine:
services:
- docker
dependencies:
pre:
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- echo "deb [arch=amd64 trusted=yes] https://test-mirrors.ripple.com/ubuntu/ trusty testing" | sudo tee /etc/apt/sources.list.d/ripple.list
- sudo apt-get update -qq
- sudo apt-get purge -qq libboost1.48-dev
- sudo apt-get install -qq libboost1.60-all-dev
- sudo apt-get install -qq clang-3.6 gcc-5 g++-5 libobjc-5-dev libgcc-5-dev libstdc++-5-dev libclang1-3.6 libgcc1 libgomp1 libstdc++6 scons protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags texinfo
- lsb_release -a
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 99
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 99
- sudo update-alternatives --force --install /usr/bin/clang clang /usr/bin/clang-3.6 99 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-3.6
- gcc --version
- clang --version
- clang++ --version
- if [[ ! -e gdb-8.0 ]]; then wget https://ftp.gnu.org/gnu/gdb/gdb-8.0.tar.xz && tar xf gdb-8.0.tar.xz && cd gdb-8.0 && ./configure && make && cd ..; fi
- pushd gdb-8.0 && sudo make install && popd
- gdb --version
cache_directories:
- gdb-8.0
test:
pre:
- scons clang.debug
override:
# Execute unit tests under gdb
- gdb -return-child-result -quiet -batch -ex "set env MALLOC_CHECK_=3" -ex "set print thread-events off" -ex run -ex "thread apply all backtrace full" -ex "quit" --args build/clang.debug/rippled --unittest --quiet --unittest-log

View File

@@ -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))

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)