Remove scons support
10
.travis.yml
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
**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).
|
||||
|
||||

|
||||
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@@ -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
|
||||
5
Builds/QtCreator/.gitignore
vendored
@@ -1,5 +0,0 @@
|
||||
# QTCreator
|
||||
|
||||
Makefile
|
||||
*.user
|
||||
|
||||
@@ -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
|
||||
234
Builds/Test.py
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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!"
|
||||
@@ -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
|
||||
4
Builds/VisualStudio2015/.gitattributes
vendored
@@ -1,4 +0,0 @@
|
||||
RippleD.vcxproj -text
|
||||
RippleD.vcxproj.filters -text
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
Go to *C/C++, General, Additional Include Directories* and add the
|
||||
location of the boost installation:
|
||||
|
||||

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

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

|
||||
|
||||
### 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`
|
||||
|
||||

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