diff --git a/.travis.yml b/.travis.yml index 28cfac27a9..6340f73551 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,49 +13,55 @@ env: - BOOST_ROOT=$HOME/boost_1_60_0 - BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.gz?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.60.0%2Fboost_1_60_0.tar.gz&ts=1460417589&use_mirror=netix' -packages: &gcc5_pkgs - - gcc-5 - - g++-5 - - python-software-properties - - protobuf-compiler - - libprotobuf-dev - - libssl-dev - - libstdc++6 - - binutils-gold - # Provides a backtrace if the unittests crash - - gdb +addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: + - gcc-5 + - g++-5 + - python-software-properties + - protobuf-compiler + - libprotobuf-dev + - libssl-dev + - libstdc++6 + - binutils-gold + # Provides a backtrace if the unittests crash + - gdb matrix: include: + # Default BUILD is "scons". + - compiler: gcc - env: GCC_VER=5 TARGET=debug.nounity - addons: &ao_gcc5 - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: *gcc5_pkgs + env: GCC_VER=5 BUILD=cmake TARGET=debug.nounity PATH=$PWD/cmake/bin:$PATH - compiler: gcc env: GCC_VER=5 TARGET=coverage - addons: *ao_gcc5 - compiler: clang env: GCC_VER=5 TARGET=debug CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH - addons: *ao_gcc5 - compiler: clang env: GCC_VER=5 TARGET=debug.nounity CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH - addons: *ao_gcc5 + + # The clang cmake builds do not link. + # - compiler: clang + # env: GCC_VER=5 BUILD=cmake 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 CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PWD/cmake/bin:$PATH cache: directories: - $BOOST_ROOT - llvm-$LLVM_VERSION + - cmake before_install: - bin/ci/ubuntu/install-dependencies.sh script: - - bin/ci/ubuntu/build-and-test.sh + - travis_retry bin/ci/ubuntu/build-and-test.sh notifications: email: diff --git a/Builds/CMake/CMakeFuncs.cmake b/Builds/CMake/CMakeFuncs.cmake new file mode 100644 index 0000000000..630fac488f --- /dev/null +++ b/Builds/CMake/CMakeFuncs.cmake @@ -0,0 +1,635 @@ +# This is a set of common functions and settings for rippled +# and derived products. + +############################################################ + +cmake_minimum_required(VERSION 3.1.0) + +if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + message(WARNING "Builds are strongly discouraged in " + "${CMAKE_SOURCE_DIR}.") +endif() + +macro(parse_target) + + if (NOT target AND NOT CMAKE_BUILD_TYPE) + if (APPLE) + set(target clang.debug) + elseif(WIN32) + set(target msvc) + else() + set(target gcc.debug) + endif() + endif() + + if (target) + # Parse the target + set(remaining ${target}) + while (remaining) + # get the component up to the next dot or end + string(REGEX REPLACE "^\\.?([^\\.]+).*$" "\\1" cur_component ${remaining}) + string(REGEX REPLACE "^\\.?[^\\.]+(.*$)" "\\1" remaining ${remaining}) + + if (${cur_component} STREQUAL gcc) + if (DEFINED ENV{GNU_CC}) + set(CMAKE_C_COMPILER $ENV{GNU_CC}) + elseif ($ENV{CXX} MATCHES .*gcc.*) + set(CMAKE_CXX_COMPILER $ENV{CC}) + else() + find_program(CMAKE_C_COMPILER gcc) + endif() + + if (DEFINED ENV{GNU_CXX}) + set(CMAKE_C_COMPILER $ENV{GNU_CXX}) + elseif ($ENV{CXX} MATCHES .*g\\+\\+.*) + set(CMAKE_C_COMPILER $ENV{CC}) + else() + find_program(CMAKE_CXX_COMPILER g++) + endif() + endif() + + if (${cur_component} STREQUAL clang) + if (DEFINED ENV{CLANG_CC}) + set(CMAKE_C_COMPILER $ENV{CLANG_CC}) + elseif ($ENV{CXX} MATCHES .*clang.*) + set(CMAKE_CXX_COMPILER $ENV{CC}) + else() + find_program(CMAKE_C_COMPILER clang) + endif() + + if (DEFINED ENV{CLANG_CXX}) + set(CMAKE_C_COMPILER $ENV{CLANG_CXX}) + elseif ($ENV{CXX} MATCHES .*clang.*) + set(CMAKE_C_COMPILER $ENV{CC}) + else() + find_program(CMAKE_CXX_COMPILER clang++) + endif() + endif() + + if (${cur_component} STREQUAL msvc) + # TBD + endif() + + if (${cur_component} STREQUAL unity) + set(unity true) + set(nonunity false) + endif() + + if (${cur_component} STREQUAL nounity) + set(unity false) + set(nonunity true) + endif() + + if (${cur_component} STREQUAL debug) + set(release false) + endif() + + if (${cur_component} STREQUAL release) + set(release true) + endif() + + if (${cur_component} STREQUAL coverage) + set(coverage true) + set(debug true) + endif() + + if (${cur_component} STREQUAL profile) + set(profile true) + endif() + + if (${cur_component} STREQUAL ci) + # Workarounds that make various CI builds work, but that + # we don't want in the general case. + set(ci true) + set(openssl_min 1.0.1) + endif() + + endwhile() + + if (release) + set(CMAKE_BUILD_TYPE Release) + else() + set(CMAKE_BUILD_TYPE Debug) + endif() + + if (NOT unity) + set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}Classic) + endif() + endif() + +endmacro() + +############################################################ + +macro(setup_build_cache) + set(san "" CACHE STRING "On gcc & clang, add sanitizer + instrumentation") + set_property(CACHE san PROPERTY STRINGS ";address;thread") + set(assert false CACHE BOOL "Enables asserts, even in release builds") + set(static false CACHE BOOL + "On linux, link protobuf, openssl, libc++, and boost statically") + + if (static AND (WIN32 OR APPLE)) + message(FATAL_ERROR "Static linking is only supported on linux.") + endif() + + if (${CMAKE_GENERATOR} STREQUAL "Unix Makefiles" AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) + endif() + + # Can't exclude files from configurations, so can't support both + # unity and nonunity configurations at the same time + if (NOT DEFINED unity OR unity) + set(CMAKE_CONFIGURATION_TYPES + Debug + Release) + else() + set(CMAKE_CONFIGURATION_TYPES + DebugClassic + ReleaseClassic) + endif() + + set(CMAKE_CONFIGURATION_TYPES + ${CMAKE_CONFIGURATION_TYPES} CACHE STRING "" FORCE) +endmacro() + +############################################################ + +function(prepend var prefix) + set(listVar "") + foreach(f ${ARGN}) + list(APPEND listVar "${prefix}${f}") + endforeach(f) + set(${var} "${listVar}" PARENT_SCOPE) +endfunction() + +macro(append_flags name) + foreach (arg ${ARGN}) + set(${name} "${${name}} ${arg}") + endforeach() +endmacro() + +macro(group_sources curdir) + file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} + ${PROJECT_SOURCE_DIR}/${curdir}/*) + foreach (child ${children}) + if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + group_sources(${curdir}/${child}) + else() + string(REPLACE "/" "\\" groupname ${curdir}) + source_group(${groupname} FILES + ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + endif() + endforeach() +endmacro() + +macro(add_with_props src_var files) + list(APPEND ${src_var} ${files}) + foreach (arg ${ARGN}) + set(props "${props} ${arg}") + endforeach() + set_source_files_properties( + ${files} + PROPERTIES COMPILE_FLAGS + ${props}) +endmacro() + +############################################################ + +macro(determine_build_type) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES ".*Clang") # both Clang and AppleClang + set(is_clang true) + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(is_gcc true) + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(is_msvc true) + endif() + + if (${CMAKE_GENERATOR} STREQUAL "Xcode") + set(is_xcode true) + else() + set(is_xcode false) + endif() + + if (NOT is_gcc AND NOT is_clang AND NOT is_msvc) + message("Current compiler is ${CMAKE_CXX_COMPILER_ID}") + message(FATAL_ERROR "Missing compiler. Must be GNU, Clang, or MSVC") + endif() +endmacro() + +############################################################ + +macro(check_gcc4_abi) + # Check if should use gcc4's ABI + set(gcc4_abi false) + + if ($ENV{RIPPLED_OLD_GCC_ABI}) + set(gcc4_abi true) + endif() + + if (is_gcc AND NOT gcc4_abi) + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5) + execute_process(COMMAND lsb_release -si OUTPUT_VARIABLE lsb) + string(STRIP ${lsb} lsb) + if (${lsb} STREQUAL "Ubuntu") + execute_process(COMMAND lsb_release -sr OUTPUT_VARIABLE lsb) + string(STRIP ${lsb} lsb) + if (${lsb} VERSION_LESS 15.1) + set(gcc4_abi true) + endif() + endif() + endif() + endif() + + if (gcc4_abi) + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + endif() +endmacro() + +############################################################ + +macro(special_build_flags) + if (coverage) + add_compile_options(-fprofile-arcs -ftest-coverage) + append_flags(CMAKE_EXE_LINKER_FLAGS -fprofile-arcs -ftest-coverage) + endif() + + if (profile) + add_compile_options(-p -pg) + append_flags(CMAKE_EXE_LINKER_FLAGS -p -pg) + endif() +endmacro() + +############################################################ + +# Params: Boost components to search for. +macro(find_boost) + if (NOT WIN32) + if (is_clang AND DEFINED ENV{CLANG_BOOST_ROOT}) + set(BOOST_ROOT $ENV{CLANG_BOOST_ROOT}) + endif() + + set(Boost_USE_STATIC_LIBS on) + set(Boost_USE_MULTITHREADED on) + set(Boost_USE_STATIC_RUNTIME off) + find_package(Boost COMPONENTS + ${ARGN}) + + if (Boost_FOUND) + include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) + else() + message(FATAL_ERROR "Boost not found") + endif() + else(DEFINED ENV{BOOST_ROOT}) + include_directories(SYSTEM $ENV{BOOST_ROOT}) + link_directories($ENV{BOOST_ROOT}/stage/lib) + endif() +endmacro() + +macro(find_pthread) + if (NOT WIN32) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads) + endif() +endmacro() + +macro(find_openssl openssl_min) + if (APPLE) + # swd TBD fixme + file(GLOB OPENSSL_ROOT_DIR /usr/local/Cellar/openssl/*) + # set(OPENSSL_ROOT_DIR /usr/local/Cellar/openssl) + endif() + + if (WIN32) + if (DEFINED ENV{OPENSSL_ROOT}) + include_directories($ENV{OPENSSL_ROOT}/include) + link_directories($ENV{OPENSSL_ROOT}/lib) + endif() + else() + if (static) + set(tmp CMAKE_FIND_LIBRARY_SUFFIXES) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() + + find_package(OpenSSL) + + if (static) + set(CMAKE_FIND_LIBRARY_SUFFIXES tmp) + endif() + + if (OPENSSL_FOUND) + include_directories(${OPENSSL_INCLUDE_DIR}) + else() + message(FATAL_ERROR "OpenSSL not found") + endif() + if (UNIX AND NOT APPLE AND ${OPENSSL_VERSION} VERSION_LESS ${openssl_min}) + message(FATAL_ERROR + "Your openssl is Version: ${OPENSSL_VERSION}, ${openssl_min} or better is required.") + endif() + endif() +endmacro() + +macro(find_protobuf) + if (WIN32) + if (DEFINED ENV{PROTOBUF_ROOT}) + include_directories($ENV{PROTOBUF_ROOT}/src) + link_directories($ENV{PROTOBUF_ROOT}/src/.libs) + endif() + + # Modified from FindProtobuf.cmake + FUNCTION(PROTOBUF_GENERATE_CPP SRCS HDRS PROTOFILES) + # argument parsing + IF(NOT PROTOFILES) + MESSAGE(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files") + RETURN() + ENDIF() + + SET(OUTPATH ${CMAKE_CURRENT_BINARY_DIR}) + SET(PROTOROOT ${CMAKE_CURRENT_SOURCE_DIR}) + # the real logic + SET(${SRCS}) + SET(${HDRS}) + FOREACH(PROTOFILE ${PROTOFILES}) + # ensure that the file ends with .proto + STRING(REGEX MATCH "\\.proto$$" PROTOEND ${PROTOFILE}) + IF(NOT PROTOEND) + MESSAGE(SEND_ERROR "Proto file '${PROTOFILE}' does not end with .proto") + ENDIF() + + GET_FILENAME_COMPONENT(PROTO_PATH ${PROTOFILE} PATH) + GET_FILENAME_COMPONENT(ABS_FILE ${PROTOFILE} ABSOLUTE) + GET_FILENAME_COMPONENT(FILE_WE ${PROTOFILE} NAME_WE) + + STRING(REGEX MATCH "^${PROTOROOT}" IN_ROOT_PATH ${PROTOFILE}) + STRING(REGEX MATCH "^${PROTOROOT}" IN_ROOT_ABS_FILE ${ABS_FILE}) + + IF(IN_ROOT_PATH) + SET(MATCH_PATH ${PROTOFILE}) + ELSEIF(IN_ROOT_ABS_FILE) + SET(MATCH_PATH ${ABS_FILE}) + ELSE() + MESSAGE(SEND_ERROR "Proto file '${PROTOFILE}' is not in protoroot '${PROTOROOT}'") + ENDIF() + + # build the result file name + STRING(REGEX REPLACE "^${PROTOROOT}(/?)" "" ROOT_CLEANED_FILE ${MATCH_PATH}) + STRING(REGEX REPLACE "\\.proto$$" "" EXT_CLEANED_FILE ${ROOT_CLEANED_FILE}) + + SET(CPP_FILE "${OUTPATH}/${EXT_CLEANED_FILE}.pb.cc") + SET(H_FILE "${OUTPATH}/${EXT_CLEANED_FILE}.pb.h") + + LIST(APPEND ${SRCS} "${CPP_FILE}") + LIST(APPEND ${HDRS} "${H_FILE}") + + ADD_CUSTOM_COMMAND( + OUTPUT "${CPP_FILE}" "${H_FILE}" + COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPATH} + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + ARGS "--cpp_out=${OUTPATH}" --proto_path "${PROTOROOT}" "${MATCH_PATH}" + DEPENDS ${ABS_FILE} + COMMENT "Running C++ protocol buffer compiler on ${MATCH_PATH} with root ${PROTOROOT}, generating: ${CPP_FILE}" + VERBATIM) + + ENDFOREACH() + + SET_SOURCE_FILES_PROPERTIES(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) + SET(${SRCS} ${${SRCS}} PARENT_SCOPE) + SET(${HDRS} ${${HDRS}} PARENT_SCOPE) + + ENDFUNCTION() + + set(PROTOBUF_PROTOC_EXECUTABLE Protoc) # must be on path + else() + if (static) + set(tmp CMAKE_FIND_LIBRARY_SUFFIXES) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() + + find_package(Protobuf REQUIRED) + + if (static) + set(CMAKE_FIND_LIBRARY_SUFFIXES tmp) + endif() + + if (is_clang AND DEFINED ENV{CLANG_PROTOBUF_ROOT}) + link_directories($ENV{CLANG_PROTOBUF_ROOT}/src/.libs) + include_directories($ENV{CLANG_PROTOBUF_ROOT}/src) + else() + include_directories(${PROTOBUF_INCLUDE_DIRS}) + endif() + endif() + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + file(GLOB ripple_proto src/ripple/proto/*.proto) + PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${ripple_proto}) + + if (WIN32) + include_directories(src/protobuf/src + src/protobuf/vsprojects + ${CMAKE_CURRENT_BINARY_DIR}/src/ripple/proto) + endif() + +endmacro() + +############################################################ + +macro(setup_build_boilerplate) + if (NOT WIN32 AND san) + add_compile_options(-fsanitize=${san} -fno-omit-frame-pointer) + + append_flags(CMAKE_EXE_LINKER_FLAGS + -fsanitize=${san}) + + string(TOLOWER ${san} ci_san) + if (${ci_san} STREQUAL address) + set(SANITIZER_LIBRARIES asan) + add_definitions(-DSANITIZER=ASAN) + endif() + if (${ci_san} STREQUAL thread) + set(SANITIZER_LIBRARIES tsan) + add_definitions(-DSANITIZER=TSAN) + endif() + endif() + + ############################################################ + + add_definitions( + -DOPENSSL_NO_SSL2 + -DDEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER + -DHAVE_USLEEP=1 + -DSOCI_CXX_C11=1 + -D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS + -DBOOST_NO_AUTO_PTR + ) + + if (is_gcc) + add_compile_options(-Wno-unused-but-set-variable -Wno-deprecated) + endif() + + # Generator expressions are not supported in add_definitions, use set_property instead + set_property( + DIRECTORY + APPEND + PROPERTY COMPILE_DEFINITIONS + $<$,$>:DEBUG _DEBUG>) + + if (NOT assert) + set_property( + DIRECTORY + APPEND + PROPERTY COMPILE_DEFINITIONS + $<$,$,$>:NDEBUG>) + endif() + + if (NOT WIN32) + add_definitions(-D_FILE_OFFSET_BITS=64) + append_flags(CMAKE_CXX_FLAGS -frtti -std=c++14 -Wno-invalid-offsetof + -DBOOST_COROUTINE_NO_DEPRECATION_WARNING -DBOOST_COROUTINES_NO_DEPRECATION_WARNING) + add_compile_options(-Wall -Wno-sign-compare -Wno-char-subscripts -Wno-format + -Wno-unused-local-typedefs -g) + # There seems to be an issue using generator experssions with multiple values, + # split the expression + add_compile_options($<$,$>:-O3>) + add_compile_options($<$,$>:-fno-strict-aliasing>) + append_flags(CMAKE_EXE_LINKER_FLAGS -rdynamic -g) + + if (is_clang) + add_compile_options( + -Wno-redeclared-class-member -Wno-mismatched-tags -Wno-deprecated-register) + add_definitions(-DBOOST_ASIO_HAS_STD_ARRAY) + endif() + + if (APPLE) + add_definitions(-DBEAST_COMPILE_OBJECTIVE_CPP=1 + -DNO_LOG_UNHANDLED_EXCEPTIONS) + add_compile_options( + -Wno-deprecated -Wno-deprecated-declarations -Wno-unused-variable -Wno-unused-function) + endif() + + if (is_gcc) + add_compile_options(-Wno-unused-but-set-variable -Wno-unused-local-typedefs) + add_compile_options($<$,$>:-O0>) + endif (is_gcc) + else(NOT WIN32) + add_compile_options( + /bigobj # Increase object file max size + /EHa # ExceptionHandling all + /fp:precise # Floating point behavior + /Gd # __cdecl calling convention + /Gm- # Minimal rebuild: disabled + /GR # Enable RTTI + /Gy- # Function level linking: disabled + /FS + /MP # Multiprocessor compilation + /openmp- # pragma omp: disabled + /Zc:forScope # Language extension: for scope + /Zi # Generate complete debug info + /errorReport:none # No error reporting to Internet + /nologo # Suppress login banner + /W3 # Warning level 3 + /WX- # Disable warnings as errors + /wd"4018" + /wd"4244" + /wd"4267" + /wd"4800" # Disable C4800(int to bool performance) + /wd"4503" # Decorated name length exceeded, name was truncated + ) + add_definitions( + -D_WIN32_WINNT=0x6000 + -D_SCL_SECURE_NO_WARNINGS + -D_CRT_SECURE_NO_WARNINGS + -DWIN32_CONSOLE + -DNOMINMAX + -DBOOST_COROUTINE_NO_DEPRECATION_WARNING + -DBOOST_COROUTINES_NO_DEPRECATION_WARNING) + append_flags(CMAKE_EXE_LINKER_FLAGS + /DEBUG + /DYNAMICBASE + /ERRORREPORT:NONE + /MACHINE:X64 + /MANIFEST + /nologo + /NXCOMPAT + /SUBSYSTEM:CONSOLE + /TLBID:1) + + + # There seems to be an issue using generator experssions with multiple values, + # split the expression + # /GS Buffers security check: enable + add_compile_options($<$,$>:/GS>) + # /MTd Language: Multi-threaded Debug CRT + add_compile_options($<$,$>:/MTd>) + # /Od Optimization: Disabled + add_compile_options($<$,$>:/Od>) + # /RTC1 Run-time error checks: + add_compile_options($<$,$>:/RTC1>) + + # Generator expressions are not supported in add_definitions, use set_property instead + set_property( + DIRECTORY + APPEND + PROPERTY COMPILE_DEFINITIONS + $<$,$>:_CRTDBG_MAP_ALLOC>) + + # /MT Language: Multi-threaded CRT + add_compile_options($<$,$>:/MT>) + add_compile_options($<$,$>:/Ox>) + # /Ox Optimization: Full + + endif (NOT WIN32) + + if (static) + append_flags(CMAKE_EXE_LINKER_FLAGS -static-libstdc++) + # set_target_properties(ripple-libpp PROPERTIES LINK_SEARCH_START_STATIC 1) + # set_target_properties(ripple-libpp PROPERTIES LINK_SEARCH_END_STATIC 1) + endif() +endmacro() + +############################################################ + +macro(create_build_folder cur_project) + if (NOT WIN32) + ADD_CUSTOM_TARGET(build_folder ALL + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Creating build output folder") + add_dependencies(${cur_project} build_folder) + endif() +endmacro() + +macro(set_startup_project cur_project) + if (WIN32 AND NOT ci) + if (CMAKE_VERSION VERSION_LESS 3.6) + message(WARNING + "Setting the VS startup project requires cmake 3.6 or later. Please upgrade.") + endif() + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY + VS_STARTUP_PROJECT ${cur_project}) + endif() +endmacro() + +macro(link_common_libraries cur_project) + if (NOT WIN32) + target_link_libraries(${cur_project} ${Boost_LIBRARIES}) + target_link_libraries(${cur_project} dl) + target_link_libraries(${cur_project} Threads::Threads) + if (APPLE) + find_library(app_kit AppKit) + find_library(foundation Foundation) + target_link_libraries(${cur_project} + crypto ssl ${app_kit} ${foundation}) + else() + target_link_libraries(${cur_project} rt) + endif() + else(NOT WIN32) + target_link_libraries(${cur_project} + $<$,$>:VC/static/ssleay32MTd> + $<$,$>:VC/static/libeay32MTd>) + target_link_libraries(${cur_project} + $<$,$>:VC/static/ssleay32MT> + $<$,$>:VC/static/libeay32MT>) + target_link_libraries(${cur_project} + legacy_stdio_definitions.lib Shlwapi kernel32 user32 gdi32 winspool comdlg32 + advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32) + endif (NOT WIN32) +endmacro() diff --git a/CMakeLists.txt b/CMakeLists.txt index 3935ca3c97..5d7264484f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,550 +54,95 @@ cmake_minimum_required(VERSION 3.1.0) -if (NOT target AND NOT CMAKE_BUILD_TYPE) - if (APPLE) - set(target clang.debug) +if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + set(dir "build") + set(cmd "cmake") + if (target) + set(dir "${dir}/${target}") + set(cmd "${cmd} -Dtarget=${target}") + elseif(CMAKE_BUILD_TYPE) + set(dir "${dir}/${CMAKE_BUILD_TYPE}") + set(cmd "${cmd} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") else() - set(target gcc.debug) + set(dir "${dir}/default") endif() + set(cmd "${cmd} ${CMAKE_SOURCE_DIR}") + + message(FATAL_ERROR "Builds are not allowed in ${CMAKE_SOURCE_DIR}.\n" + "Instead:\n" + "1) Remove the CMakeCache.txt file and CMakeFiles directory " + "from ${CMAKE_SOURCE_DIR}.\n" + "2) Create a directory to hold your build files, for example: ${dir}.\n" + "3) Change to that directory.\n" + "4) Run cmake targetting ${CMAKE_SOURCE_DIR}, for example: ${cmd}") +endif() +if("${CMAKE_GENERATOR}" MATCHES "Visual Studio" AND + NOT ("${CMAKE_GENERATOR}" MATCHES .*Win64.*)) + message(FATAL_ERROR "Visual Studio 32-bit build is unsupported. Use + -G\"${CMAKE_GENERATOR} Win64\"") endif() -if (target) - # Parse the target - set(remaining ${target}) - while (remaining) - # get the component up to the next dot or end - string(REGEX REPLACE "^\\.?([^\\.]+).*$" "\\1" cur_component ${remaining}) - string(REGEX REPLACE "^\\.?[^\\.]+(.*$)" "\\1" remaining ${remaining}) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Builds/CMake") +include(CMakeFuncs) - if (${cur_component} STREQUAL gcc) - if (DEFINED ENV{GNU_CC}) - set(CMAKE_C_COMPILER $ENV{GNU_CC}) - elseif ($ENV{CXX} MATCHES .*gcc.*) - set(CMAKE_CXX_COMPILER $ENV{CC}) - else() - find_program(CMAKE_C_COMPILER gcc) - endif() +set(openssl_min 1.0.2) - if (DEFINED ENV{GNU_CXX}) - set(CMAKE_C_COMPILER $ENV{GNU_CXX}) - elseif ($ENV{CXX} MATCHES .*g\\+\\+.*) - set(CMAKE_C_COMPILER $ENV{CC}) - else() - find_program(CMAKE_CXX_COMPILER g++) - endif() - endif() - - if (${cur_component} STREQUAL clang) - if (DEFINED ENV{CLANG_CC}) - set(CMAKE_C_COMPILER $ENV{CLANG_CC}) - elseif ($ENV{CXX} MATCHES .*clang.*) - set(CMAKE_CXX_COMPILER $ENV{CC}) - else() - find_program(CMAKE_C_COMPILER clang) - endif() - - if (DEFINED ENV{CLANG_CXX}) - set(CMAKE_C_COMPILER $ENV{CLANG_CXX}) - elseif ($ENV{CXX} MATCHES .*clang.*) - set(CMAKE_C_COMPILER $ENV{CC}) - else() - find_program(CMAKE_CXX_COMPILER clang++) - endif() - endif() - - if (${cur_component} STREQUAL msvc) - # TBD - endif() - - if (${cur_component} STREQUAL unity) - set(unity true) - set(nonunity false) - endif() - - if (${cur_component} STREQUAL nounity) - set(unity false) - set(nonunity true) - endif() - - if (${cur_component} STREQUAL debug) - set(release false) - endif() - - if (${cur_component} STREQUAL release) - set(release true) - endif() - - if (${cur_component} STREQUAL coverage) - set(coverage true) - set(debug true) - endif() - - if (${cur_component} STREQUAL profile) - set(profile true) - endif() - - endwhile() - - if (release) - set(CMAKE_BUILD_TYPE Release) - else() - set(CMAKE_BUILD_TYPE Debug) - endif() - - if (NOT unity) - set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}Classic) - endif() - -endif() +parse_target() if (NOT DEFINED unity) set(unity true) set(nonunity false) endif() -set(san "" CACHE STRING "On gcc & clang, add sanitizer instrumentation") -set_property(CACHE san PROPERTY STRINGS ";address;thread") -set(assert false CACHE BOOL "Enables asserts, even in release builds") -set(static false CACHE BOOL - "On linux, link protobuf, openssl, libc++, and boost statically") - -if (static AND (WIN32 OR APPLE)) - message(FATAL_ERROR "Static linking is only supported on linux.") -endif() - -if (${CMAKE_GENERATOR} STREQUAL "Unix Makefiles" AND NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Debug) -endif() - -# Can't exclude files from configurations, so can't support both -# unity and nonunity configurations at the same time -if (unity) - set(CMAKE_CONFIGURATION_TYPES - Debug - Release) -else() - set(CMAKE_CONFIGURATION_TYPES - DebugClassic - ReleaseClassic) -endif() - -set(CMAKE_CONFIGURATION_TYPES - ${CMAKE_CONFIGURATION_TYPES} CACHE STRING "" FORCE) +setup_build_cache() project(rippled) -############################################################ +if(nonunity) + set(CMAKE_CXX_FLAGS_DEBUGCLASSIC ${CMAKE_CXX_FLAGS_DEBUG}) + set(CMAKE_CXX_FLAGS_RELEASECLASSIC ${CMAKE_CXX_FLAGS_RELEASE}) + set(CMAKE_EXE_LINKER_FLAGS_DEBUGCLASSIC + ${CMAKE_EXE_LINKER_FLAGS_DEBUG}) + set(CMAKE_EXE_LINKER_FLAGS_RELEASECLASSIC + ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) +endif() -function(prepend var prefix) - set(listVar "") - foreach(f ${ARGN}) - list(APPEND listVar "${prefix}${f}") - endforeach(f) - set(${var} "${listVar}" PARENT_SCOPE) -endfunction() +determine_build_type() -macro(append_flags name) - foreach (arg ${ARGN}) - set(${name} "${${name}} ${arg}") - endforeach() -endmacro() - -macro(group_sources curdir) - file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} - ${PROJECT_SOURCE_DIR}/${curdir}/*) - foreach (child ${children}) - if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - group_sources(${curdir}/${child}) - else() - string(REPLACE "/" "\\" groupname ${curdir}) - source_group(${groupname} FILES - ${PROJECT_SOURCE_DIR}/${curdir}/${child}) - endif() - endforeach() -endmacro() - -macro(add_with_props files) - list(APPEND src ${files}) - foreach (arg ${ARGN}) - set(props "${props} ${arg}") - endforeach() - set_source_files_properties( - ${files} - PROPERTIES COMPILE_FLAGS - ${props}) -endmacro() +check_gcc4_abi() ############################################################ -if ("${CMAKE_CXX_COMPILER_ID}" MATCHES ".*Clang") # both Clang and AppleClang - set(is_clang true) -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(is_gcc true) -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(is_msvc true) -endif() +include_directories( + src + src/beast + src/beast/include + src/beast/extras + src/nudb/include + src/soci/src + src/soci/include) -if (${CMAKE_GENERATOR} STREQUAL "Xcode") - set(is_xcode true) -else() - set(is_xcode false) -endif() - -if (NOT is_gcc AND NOT is_clang AND NOT is_msvc) - message("Current compiler is ${CMAKE_CXX_COMPILER_ID}") - message(FATAL_ERROR "Missing compiler. Must be GNU, Clang, or MSVC") -endif() - -############################################################ -# Check if should use gcc4's ABI -set(gcc4_abi false) - -if ($ENV{RIPPLED_OLD_GCC_ABI}) - set(gcc4_abi true) -endif() - -if (is_gcc AND NOT gcc4_abi) - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5) - execute_process(COMMAND lsb_release -si OUTPUT_VARIABLE lsb) - string(STRIP ${lsb} lsb) - if (${lsb} STREQUAL "Ubuntu") - execute_process(COMMAND lsb_release -sr OUTPUT_VARIABLE lsb) - string(STRIP ${lsb} lsb) - if (${lsb} VERSION_LESS 15.1) - set(gcc4_abi true) - endif() - endif() - endif() -endif() - -if (gcc4_abi) - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -endif() +special_build_flags() ############################################################ -include_directories(src src/beast src/beast/include src/beast/extras - src/nudb/include src/soci/src src/soci/include) +find_boost( + coroutine + context + date_time + filesystem + program_options + regex + system + thread) -if (coverage) - add_compile_options(-fprofile-arcs -ftest-coverage) - append_flags(CMAKE_EXE_LINKER_FLAGS -fprofile-arcs -ftest-coverage) -endif() +find_pthread() -if (profile) - add_compile_options(-p -pg) - append_flags(CMAKE_EXE_LINKER_FLAGS -p -pg) -endif() +find_openssl(${openssl_min}) -############################################################ +find_protobuf() -if (NOT WIN32) - if (is_clang AND DEFINED ENV{CLANG_BOOST_ROOT}) - set(BOOST_ROOT $ENV{CLANG_BOOST_ROOT}) - endif() - - - set(Boost_USE_STATIC_LIBS on) - set(Boost_USE_MULTITHREADED on) - set(Boost_USE_STATIC_RUNTIME off) - find_package(Boost COMPONENTS - coroutine - context - date_time - filesystem - program_options - regex - system - thread) - - if (Boost_FOUND) - include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) - else() - message(FATAL_ERROR "Boost not found") - endif() -endif() - -if (APPLE) - # swd TBD fixme - file(GLOB OPENSSL_ROOT_DIR /usr/local/Cellar/openssl/*) - # set(OPENSSL_ROOT_DIR /usr/local/Cellar/openssl) -endif() - -if (WIN32) - if (DEFINED ENV{OPENSSL_ROOT}) - include_directories($ENV{OPENSSL_ROOT}/include) - link_directories($ENV{OPENSSL_ROOT}/lib) - endif() -else() - if (static) - set(tmp CMAKE_FIND_LIBRARY_SUFFIXES) - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() - - find_package(OpenSSL) - - if (static) - set(CMAKE_FIND_LIBRARY_SUFFIXES tmp) - endif() - - if (OPENSSL_FOUND) - include_directories(${OPENSSL_INCLUDE_DIR}) - else() - message(FATAL_ERROR "OpenSSL not found") - endif() - if (UNIX AND NOT APPLE AND ${OPENSSL_VERSION} VERSION_LESS 1.0.2) - message(FATAL_ERROR - "Your openssl is Version: ${OPENSSL_VERSION}, rippled requires 1.0.2 or better.") - endif() -endif() - -if (WIN32) - if (DEFINED ENV{PROTOBUF_ROOT}) - include_directories($ENV{PROTOBUF_ROOT}/src) - link_directories($ENV{PROTOBUF_ROOT}/src/.libs) - endif() - - # Modified from FindProtobuf.cmake - FUNCTION(PROTOBUF_GENERATE_CPP SRCS HDRS PROTOFILES) - # argument parsing - IF(NOT PROTOFILES) - MESSAGE(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files") - RETURN() - ENDIF() - - SET(OUTPATH ${CMAKE_CURRENT_BINARY_DIR}) - SET(PROTOROOT ${CMAKE_CURRENT_SOURCE_DIR}) - # the real logic - SET(${SRCS}) - SET(${HDRS}) - FOREACH(PROTOFILE ${PROTOFILES}) - # ensure that the file ends with .proto - STRING(REGEX MATCH "\\.proto$$" PROTOEND ${PROTOFILE}) - IF(NOT PROTOEND) - MESSAGE(SEND_ERROR "Proto file '${PROTOFILE}' does not end with .proto") - ENDIF() - - GET_FILENAME_COMPONENT(PROTO_PATH ${PROTOFILE} PATH) - GET_FILENAME_COMPONENT(ABS_FILE ${PROTOFILE} ABSOLUTE) - GET_FILENAME_COMPONENT(FILE_WE ${PROTOFILE} NAME_WE) - - STRING(REGEX MATCH "^${PROTOROOT}" IN_ROOT_PATH ${PROTOFILE}) - STRING(REGEX MATCH "^${PROTOROOT}" IN_ROOT_ABS_FILE ${ABS_FILE}) - - IF(IN_ROOT_PATH) - SET(MATCH_PATH ${PROTOFILE}) - ELSEIF(IN_ROOT_ABS_FILE) - SET(MATCH_PATH ${ABS_FILE}) - ELSE() - MESSAGE(SEND_ERROR "Proto file '${PROTOFILE}' is not in protoroot '${PROTOROOT}'") - ENDIF() - - # build the result file name - STRING(REGEX REPLACE "^${PROTOROOT}(/?)" "" ROOT_CLEANED_FILE ${MATCH_PATH}) - STRING(REGEX REPLACE "\\.proto$$" "" EXT_CLEANED_FILE ${ROOT_CLEANED_FILE}) - - SET(CPP_FILE "${OUTPATH}/${EXT_CLEANED_FILE}.pb.cc") - SET(H_FILE "${OUTPATH}/${EXT_CLEANED_FILE}.pb.h") - - LIST(APPEND ${SRCS} "${CPP_FILE}") - LIST(APPEND ${HDRS} "${H_FILE}") - - ADD_CUSTOM_COMMAND( - OUTPUT "${CPP_FILE}" "${H_FILE}" - COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPATH} - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} - ARGS "--cpp_out=${OUTPATH}" --proto_path "${PROTOROOT}" "${MATCH_PATH}" - DEPENDS ${ABS_FILE} - COMMENT "Running C++ protocol buffer compiler on ${MATCH_PATH} with root ${PROTOROOT}, generating: ${CPP_FILE}" - VERBATIM) - - ENDFOREACH() - - SET_SOURCE_FILES_PROPERTIES(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) - SET(${SRCS} ${${SRCS}} PARENT_SCOPE) - SET(${HDRS} ${${HDRS}} PARENT_SCOPE) - - ENDFUNCTION() - - set(PROTOBUF_PROTOC_EXECUTABLE Protoc) # must be on path -else() - if (static) - set(tmp CMAKE_FIND_LIBRARY_SUFFIXES) - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() - - find_package(Protobuf REQUIRED) - - if (static) - set(CMAKE_FIND_LIBRARY_SUFFIXES tmp) - endif() - - if (is_clang AND DEFINED ENV{CLANG_PROTOBUF_ROOT}) - link_directories($ENV{CLANG_PROTOBUF_ROOT}/src/.libs) - include_directories($ENV{CLANG_PROTOBUF_ROOT}/src) - else() - include_directories(${PROTOBUF_INCLUDE_DIRS}) - endif() -endif() -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - - -############################################################ - -if (NOT WIN32 AND san) - add_compile_options(-fsanitize=${san} -fno-omit-frame-pointer) - - append_flags(CMAKE_EXE_LINKER_FLAGS - -fsanitize=${san}) - - string(TOLOWER ${san} ci_san) - if (${ci_san} STREQUAL address) - set(SANITIZER_LIBRARIES asan) - add_definitions(-DSANITIZER=ASAN) - endif() - if (${ci_san} STREQUAL thread) - set(SANITIZER_LIBRARIES tsan) - add_definitions(-DSANITIZER=TSAN) - endif() -endif() - -############################################################ - -file(GLOB ripple_proto src/ripple/proto/*.proto) -PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${ripple_proto}) - -if (WIN32) - include_directories(src/protobuf/src - src/protobuf/vsprojects - ${CMAKE_CURRENT_BINARY_DIR}/src/ripple/proto) -endif() - -add_definitions( - -DOPENSSL_NO_SSL2 - -DDEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER - -DHAVE_USLEEP=1 - -DSOCI_CXX_C11=1 - -D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS - -DBOOST_NO_AUTO_PTR - ) - -if (is_gcc) - add_compile_options(-Wno-unused-but-set-variable -Wno-deprecated) -endif() - -# Generator expressions are not supported in add_definitions, use set_property instead -set_property( - DIRECTORY - APPEND - PROPERTY COMPILE_DEFINITIONS - $<$,$>:DEBUG _DEBUG>) - -if (NOT assert) - set_property( - DIRECTORY - APPEND - PROPERTY COMPILE_DEFINITIONS - $<$,$,$>:NDEBUG>) -endif() - -if (NOT WIN32) - add_definitions(-D_FILE_OFFSET_BITS=64) - append_flags(CMAKE_CXX_FLAGS -frtti -std=c++14 -Wno-invalid-offsetof - -DBOOST_COROUTINE_NO_DEPRECATION_WARNING -DBOOST_COROUTINES_NO_DEPRECATION_WARNING) - add_compile_options(-Wall -Wno-sign-compare -Wno-char-subscripts -Wno-format - -Wno-unused-local-typedefs -g) - # There seems to be an issue using generator experssions with multiple values, - # split the expression - add_compile_options($<$,$>:-O3>) - add_compile_options($<$,$>:-fno-strict-aliasing>) - append_flags(CMAKE_EXE_LINKER_FLAGS -rdynamic -g) - - if (is_clang) - add_compile_options( - -Wno-redeclared-class-member -Wno-mismatched-tags -Wno-deprecated-register) - add_definitions(-DBOOST_ASIO_HAS_STD_ARRAY) - endif() - - if (APPLE) - add_definitions(-DBEAST_COMPILE_OBJECTIVE_CPP=1 - -DNO_LOG_UNHANDLED_EXCEPTIONS) - add_compile_options( - -Wno-deprecated -Wno-deprecated-declarations -Wno-unused-variable -Wno-unused-function) - endif() - - if (is_gcc) - add_compile_options(-Wno-unused-but-set-variable -Wno-unused-local-typedefs) - add_compile_options($<$,$>:-O0>) - endif (is_gcc) -else(NOT WIN32) - add_compile_options( - /bigobj # Increase object file max size - /EHa # ExceptionHandling all - /fp:precise # Floating point behavior - /Gd # __cdecl calling convention - /Gm- # Minimal rebuild: disabled - /GR # Enable RTTI - /Gy- # Function level linking: disabled - /FS - /MP # Multiprocessor compilation - /openmp- # pragma omp: disabled - /Zc:forScope # Language extension: for scope - /Zi # Generate complete debug info - /errorReport:none # No error reporting to Internet - /nologo # Suppress login banner - /W3 # Warning level 3 - /WX- # Disable warnings as errors - /wd"4018" - /wd"4244" - /wd"4267" - /wd"4800" # Disable C4800(int to bool performance) - /wd"4503" # Decorated name length exceeded, name was truncated - ) - add_definitions( - -D_WIN32_WINNT=0x6000 - -D_SCL_SECURE_NO_WARNINGS - -D_CRT_SECURE_NO_WARNINGS - -DWIN32_CONSOLE - -DNOMINMAX - -DBOOST_COROUTINE_NO_DEPRECATION_WARNING - -DBOOST_COROUTINES_NO_DEPRECATION_WARNING) - append_flags(CMAKE_EXE_LINKER_FLAGS - /DEBUG - /DYNAMICBASE - /ERRORREPORT:NONE - /MACHINE:X64 - /MANIFEST - /nologo - /NXCOMPAT - /SUBSYSTEM:CONSOLE - /TLBID:1) - - - # There seems to be an issue using generator experssions with multiple values, - # split the expression - # /GS Buffers security check: enable - add_compile_options($<$,$>:/GS>) - # /MTd Language: Multi-threaded Debug CRT - add_compile_options($<$,$>:/MTd>) - # /Od Optimization: Disabled - add_compile_options($<$,$>:/Od>) - # /RTC1 Run-time error checks: - add_compile_options($<$,$>:/RTC1>) - -# Generator expressions are not supported in add_definitions, use set_property instead -set_property( - DIRECTORY - APPEND - PROPERTY COMPILE_DEFINITIONS - $<$,$>:_CRTDBG_MAP_ALLOC>) - - # /MT Language: Multi-threaded CRT - add_compile_options($<$,$>:/MT>) - add_compile_options($<$,$>:/Ox>) - # /Ox Optimization: Full - -endif (NOT WIN32) +setup_build_boilerplate() ############################################################ @@ -657,31 +202,31 @@ if (WIN32 OR is_xcode OR unity) shamap_test_unity.cpp test_unity.cpp) - list(APPEND src ${beast_unity_srcs} ${ripple_unity_srcs} ${test_unity_srcs}) + list(APPEND rippled_src ${beast_unity_srcs} ${ripple_unity_srcs} ${test_unity_srcs}) - add_with_props(src/unity/nodestore_test_unity.cpp + add_with_props(rippled_src src/unity/nodestore_test_unity.cpp -I"${CMAKE_SOURCE_DIR}/"src/rocksdb2/include -I"${CMAKE_SOURCE_DIR}/"src/snappy/snappy -I"${CMAKE_SOURCE_DIR}/"src/snappy/config ${rocks_db_system_header}) - add_with_props(src/ripple/unity/nodestore.cpp + add_with_props(rippled_src src/ripple/unity/nodestore.cpp -I"${CMAKE_SOURCE_DIR}/"src/rocksdb2/include -I"${CMAKE_SOURCE_DIR}/"src/snappy/snappy -I"${CMAKE_SOURCE_DIR}/"src/snappy/config ${rocks_db_system_header}) - add_with_props(src/ripple/unity/soci_ripple.cpp ${soci_extra_includes}) + add_with_props(rippled_src src/ripple/unity/soci_ripple.cpp ${soci_extra_includes}) - set(unity_srcs ${beast_unity_srcs} ${ripple_unity_srcs} ${test_unity_srcs} + list(APPEND ripple_unity_srcs ${beast_unity_srcs} ${test_unity_srcs} src/ripple/unity/nodestore.cpp src/ripple/unity/soci_ripple.cpp src/unity/nodestore_test_unity.cpp) set_property( - SOURCE ${unity_srcs} + SOURCE ${ripple_unity_srcs} APPEND PROPERTY HEADER_FILE_ONLY ${nonunity}) @@ -691,25 +236,43 @@ if (WIN32 OR is_xcode OR unity) endif () if (WIN32 OR is_xcode OR NOT unity) + # Rippled file(GLOB_RECURSE core_srcs src/ripple/core/*.cpp) - add_with_props("${core_srcs}" + add_with_props(rippled_src "${core_srcs}" -I"${CMAKE_SOURCE_DIR}/"src/soci/src/core -I"${CMAKE_SOURCE_DIR}/"src/sqlite) set(non_unity_srcs ${core_srcs}) foreach(curdir - beast/clock beast/container beast/insight beast/net beast/utility - app basics crypto json ledger legacy net overlay peerfinder protocol rpc - shamap server test) + beast/clock + beast/container + beast/insight + beast/net + beast/utility + app + basics + crypto + json + ledger + legacy + net + overlay + peerfinder + protocol + rpc + server + shamap + test) file(GLOB_RECURSE cursrcs src/ripple/${curdir}/*.cpp) - list(APPEND src "${cursrcs}") + list(APPEND rippled_src "${cursrcs}") list(APPEND non_unity_srcs "${cursrcs}") endforeach() - file(GLOB_RECURSE nodestore_srcs src/ripple/nodestore/*.cpp) + file(GLOB_RECURSE nodestore_srcs src/ripple/nodestore/*.cpp + src/test/nodestore/*.cpp) - add_with_props("${nodestore_srcs}" + add_with_props(rippled_src "${nodestore_srcs}" -I"${CMAKE_SOURCE_DIR}/"src/rocksdb2/include -I"${CMAKE_SOURCE_DIR}/"src/snappy/snappy -I"${CMAKE_SOURCE_DIR}/"src/snappy/config @@ -726,19 +289,42 @@ if (WIN32 OR is_xcode OR NOT unity) ${rocks_db_system_header}) list(APPEND non_unity_srcs "${test_srcs}") + list(APPEND rippled_src "${test_srcs}") + file(GLOB_RECURSE rippled_headers src/*.h src/*.hpp) + foreach(curdir + beast/asio + beast/core + beast/crypto + beast/cxx17 + beast/hash + proto + resource + validators + websocket) + file(GLOB_RECURSE cursrcs src/ripple/${curdir}/*.cpp) + list(APPEND rippled_headers "${cursrcs}") + endforeach() + list(APPEND rippled_src "${rippled_headers}") + + # Properties set_property( SOURCE ${non_unity_srcs} APPEND PROPERTY HEADER_FILE_ONLY ${unity}) + set_property( + SOURCE ${rippled_headers} + APPEND + PROPERTY HEADER_FILE_ONLY + true) # Doesn't work # $,$>) endif() ############################################################ -add_with_props(src/ripple/unity/soci.cpp +add_with_props(rippled_src src/ripple/unity/soci.cpp ${soci_extra_includes}) if (NOT is_msvc) @@ -747,7 +333,7 @@ else() unset(no_unused_w) endif() -add_with_props(src/ripple/unity/secp256k1.cpp +add_with_props(rippled_src src/ripple/unity/secp256k1.cpp -I"${CMAKE_SOURCE_DIR}/"src/secp256k1 ${no_unused_w} ) @@ -761,7 +347,7 @@ foreach(cursrc src/ripple/unity/resource.cpp src/ripple/unity/websocket02.cpp) - add_with_props(${cursrc} + add_with_props(rippled_src ${cursrc} ${rocks_db_system_header} ) @@ -773,7 +359,7 @@ else() unset(extra_props) endif() -add_with_props(src/sqlite/sqlite_unity.c +add_with_props(rippled_src src/sqlite/sqlite_unity.c ${extra_props}) if (NOT is_msvc) @@ -782,7 +368,7 @@ if (NOT is_msvc) -Wno-array-bounds) endif() -add_with_props(src/ripple/unity/ed25519.c +add_with_props(rippled_src src/ripple/unity/ed25519.c -I"${CMAKE_SOURCE_DIR}/"src/ed25519-donna) if (is_gcc) @@ -791,7 +377,7 @@ else() unset(no_init_w) endif() -add_with_props(src/ripple/unity/rocksdb.cpp +add_with_props(rippled_src src/ripple/unity/rocksdb.cpp -I"${CMAKE_SOURCE_DIR}/"src/rocksdb2 -I"${CMAKE_SOURCE_DIR}/"src/rocksdb2/include -I"${CMAKE_SOURCE_DIR}/"src/snappy/snappy @@ -802,13 +388,13 @@ if (NOT is_msvc) set(no_unused_w -Wno-unused-function) endif() -add_with_props(src/ripple/unity/snappy.cpp +add_with_props(rippled_src src/ripple/unity/snappy.cpp -I"${CMAKE_SOURCE_DIR}/"src/snappy/snappy -I"${CMAKE_SOURCE_DIR}/"src/snappy/config ${no_unused_w}) if (APPLE AND is_clang) - list(APPEND src src/ripple/unity/beastobjc.mm) + list(APPEND rippled_src src/ripple/unity/beastobjc.mm) endif() ############################################################ @@ -817,44 +403,13 @@ if (WIN32 OR is_xcode) group_sources(src) endif() -add_executable(rippled ${src} ${PROTO_HDRS}) +add_executable(rippled ${rippled_src} ${PROTO_HDRS}) -if (static) - append_flags(CMAKE_EXE_LINKER_FLAGS -static-libstdc++) - # set_target_properties(rippled PROPERTIES LINK_SEARCH_START_STATIC 1) - # set_target_properties(rippled PROPERTIES LINK_SEARCH_END_STATIC 1) -endif() +create_build_folder(rippled) -if (WIN32) - if (CMAKE_VERSION VERSION_LESS 3.6) - message(WARNING - "Setting the VS startup project requires cmake 3.6 or later. Please upgrade.") - endif() - set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT rippled) -endif() +set_startup_project(rippled) target_link_libraries(rippled - ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${PROTOBUF_LIBRARIES} ${SANITIZER_LIBRARIES}) + ${OPENSSL_LIBRARIES} ${PROTOBUF_LIBRARIES} ${SANITIZER_LIBRARIES}) - -if (NOT WIN32) - target_link_libraries(rippled dl) - if (APPLE) - find_library(app_kit AppKit) - find_library(foundation Foundation) - target_link_libraries(rippled - crypto ssl ${app_kit} ${foundation}) - else() - target_link_libraries(rippled rt) - endif() -else(NOT WIN32) - target_link_libraries(rippled - $<$,$>:VC/static/ssleay32MTd> - $<$,$>:VC/static/libeay32MTd>) - target_link_libraries(rippled - $<$,$>:VC/static/ssleay32MT> - $<$,$>:VC/static/libeay32MT>) - target_link_libraries(rippled - legacy_stdio_definitions.lib Shlwapi kernel32 user32 gdi32 winspool comdlg32 - advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32) -endif (NOT WIN32) +link_common_libraries(rippled) diff --git a/appveyor.yml b/appveyor.yml index 268422f53a..6565137491 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,6 +16,14 @@ environment: BOOST_ROOT: C:/rippled_deps15.01/boost OPENSSL_ROOT: C:/rippled_deps15.01/openssl + 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 + os: Visual Studio 2015 # At the end of each successful build we cache this directory. It must be less @@ -32,20 +40,13 @@ install: - SET PATH=%PYTHON%;%PYTHON%/Scripts;C:/rippled_deps15.01;%PATH% # `ps` prefix means the command is executed by powershell. - - ps: Start-FileDownload $env:PIP_URL - - ps: Start-FileDownload $env:PYWIN32_URL + - ps: | + if ($env:build -eq "scons") { + Start-FileDownload $env:PIP_URL + Start-FileDownload $env:PYWIN32_URL - # Installing pip will install setuptools/easy_install. - - python get-pip.py - - # Pip has some problems installing scons on windows so we use easy install. - # - easy_install scons - # Workaround - - easy_install https://pypi.python.org/packages/source/S/SCons/scons-2.5.0.tar.gz#md5=bda5530a70a41a7831d83c8b191c021e - - # Scons has problems with parallel builds on windows without pywin32. - - easy_install pywin32-220.win-amd64-py2.7.exe - # (easy_install can do headless installs of .exe wizards) + } + - bin/ci/windows/install-dependencies.bat # Download dependencies if appveyor didn't restore them from the cache. # Use 7zip to unzip. @@ -73,17 +74,45 @@ build_script: - '"%VS140COMNTOOLS%../../VC/vcvarsall.bat" x86_amd64' # Show which version of the compiler we are using. - cl - - scons msvc.debug -j%NUMBER_OF_PROCESSORS% + - ps: | + if ($env:build -eq "scons") { + # Build with scons + scons $env:target -j%NUMBER_OF_PROCESSORS% + } + else + { + # Build with cmake + cmake --version + $cmake_target="$($env:target).ci" + "$cmake_target" + New-Item -ItemType Directory -Force -Path "build/$cmake_target" + Push-Location "build/$cmake_target" + cmake -G"Visual Studio 14 2015 Win64" -Dtarget="$cmake_target" ../.. + msbuild /m "rippled.vcxproj" + Pop-Location + } after_build: - # Put our executable in a place where npm test can find it. - - ps: cp build/msvc.debug/rippled.exe build - - ps: ls build + - ps: | + if ($env:build -eq "scons") { + # Put our executable in a place where npm test can find it. + cp build/$($env:target)/rippled.exe build + ls build + $exe="build/rippled" + } + else + { + $exe="build/$cmake_target/Debug/rippled" + } + "Exe is at $exe" test_script: - # Run the unit tests - - build\\rippled --unittest + - ps: | + # Run the rippled unit tests + & $exe --unittest + + # Run the rippled integration tests + & npm install --progress=false + & npm test --rippled="$exe" + - # Run the integration tests - - npm install --progress=false - - npm test diff --git a/bin/ci/ubuntu/build-and-test.sh b/bin/ci/ubuntu/build-and-test.sh index 2626b3b7fd..5f8b457f4f 100755 --- a/bin/ci/ubuntu/build-and-test.sh +++ b/bin/ci/ubuntu/build-and-test.sh @@ -1,25 +1,59 @@ #!/bin/bash -u # We use set -e and bash with -u to bail on first non zero exit code of any -# processes launched or upon any unbound variable -set -e +# processes launched or upon any unbound variable. +# We use set -x to print commands before running them to help with +# debugging. +set -ex __dirname=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) echo "using CC: $CC" echo "using TARGET: $TARGET" -export RIPPLED_PATH="$PWD/build/$CC.$TARGET/rippled" -echo "using RIPPLED_PATH: $RIPPLED_PATH" -# Make sure vcxproj is up to date -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. -scons -j${NUM_PROCESSORS:-2} $CC.$TARGET + +# Ensure APP defaults to rippled if it's not set. +: ${APP:=rippled} +if [[ ${BUILD:-scons} == "cmake" ]]; then + echo "cmake building ${APP}" + CMAKE_TARGET=$CC.$TARGET + if [[ ${CI:-} == true ]]; then + CMAKE_TARGET=$CMAKE_TARGET.ci + fi + mkdir -p "build/${CMAKE_TARGET}" + pushd "build/${CMAKE_TARGET}" + cmake ../.. -Dtarget=$CMAKE_TARGET + make -j${NUM_PROCESSORS:-2} ${APP} + popd + export APP_PATH="$PWD/build/${CMAKE_TARGET}/${APP}" + echo "using APP_PATH: $APP_PATH" + +else + export APP_PATH="$PWD/build/$CC.$TARGET/${APP}" + echo "using APP_PATH: $APP_PATH" + # Make sure vcxproj is up to date + 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. + scons -j${NUM_PROCESSORS:-2} $CC.$TARGET +fi # We can be sure we're using the build/$CC.$TARGET variant # (-f so never err) -rm -f build/rippled +rm -f build/${APP} # See what we've actually built -ldd $RIPPLED_PATH +ldd $APP_PATH + +if [[ ${APP} == "rippled" ]]; then + export APP_ARGS="--unittest" + # Only report on src/ripple files + export LCOV_FILES="*/src/ripple/*" + # Exclude */src/ripple/test directory + export LCOV_EXCLUDE_FILES="*/src/ripple/test/*" +else + : ${APP_ARGS:=} + : ${LCOV_FILES:="*/src/*"} + # Don't exclude anything + : ${LCOV_EXCLUDE_FILES:="LCOV_NO_EXCLUDE"} +fi if [[ $TARGET == "coverage" ]]; then export PATH=$PATH:$LCOV_ROOT/usr/bin @@ -36,7 +70,7 @@ gdb -return-child-result -quiet -batch \ -ex run \ -ex "thread apply all backtrace full" \ -ex "quit" \ - --args $RIPPLED_PATH --unittest + --args $APP_PATH --unittest if [[ $TARGET == "coverage" ]]; then # Create test coverage data file @@ -45,16 +79,18 @@ if [[ $TARGET == "coverage" ]]; then # Combine baseline and test coverage data lcov -a baseline.info -a tests.info -o lcov-all.info - # Only report on src/ripple files - lcov -e "lcov-all.info" "*/src/ripple/*" -o lcov.pre.info + # Included files + lcov -e "lcov-all.info" "${LCOV_FILES}" -o lcov.pre.info - # Exclude */src/test directory - lcov --remove lcov.pre.info "*/src/ripple/test/*" -o lcov.info + # Excluded files + lcov --remove lcov.pre.info "${LCOV_EXCLUDE_FILES}" -o lcov.info # Push the results (lcov.info) to codecov codecov -X gcov # don't even try and look for .gcov files ;) fi -# Run NPM tests -npm install --progress=false -npm test --rippled=$RIPPLED_PATH +if [[ ${APP} == "rippled" ]]; then + # Run NPM tests + npm install --progress=false + npm test --rippled=$APP_PATH +fi diff --git a/bin/ci/ubuntu/install-dependencies.sh b/bin/ci/ubuntu/install-dependencies.sh index 4f18f2cdaf..e793f36a81 100755 --- a/bin/ci/ubuntu/install-dependencies.sh +++ b/bin/ci/ubuntu/install-dependencies.sh @@ -1,6 +1,11 @@ #!/bin/bash -u -# Exit if anything fails. -set -e +# Exit if anything fails. Echo commands to aid debugging. +set -ex + +# Target working dir - defaults to current dir. +# Can be set from caller, or in the first parameter +TWD=$( cd ${TWD:-${1:-${PWD:-$( pwd )}}}; pwd ) +echo "Target path is: $TWD" # Override gcc version to $GCC_VER. # Put an appropriate symlink at the front of the path. mkdir -v $HOME/bin @@ -13,16 +18,34 @@ done if [[ -n ${CLANG_VER:-} ]]; then # There are cases where the directory exists, but the exe is not available. # Use this workaround for now. - if [[ ! -x llvm-${LLVM_VERSION}/bin/llvm-config ]] && [[ -d llvm-${LLVM_VERSION} ]]; then - rm -fr llvm-${LLVM_VERSION} + if [[ ! -x ${TWD}/llvm-${LLVM_VERSION}/bin/llvm-config && -d ${TWD}/llvm-${LLVM_VERSION} ]]; then + rm -fr ${TWD}/llvm-${LLVM_VERSION} fi - if [[ ! -d llvm-${LLVM_VERSION} ]]; then - mkdir llvm-${LLVM_VERSION} + if [[ ! -d ${TWD}/llvm-${LLVM_VERSION} ]]; then + mkdir ${TWD}/llvm-${LLVM_VERSION} LLVM_URL="http://llvm.org/releases/${LLVM_VERSION}/clang+llvm-${LLVM_VERSION}-x86_64-linux-gnu-ubuntu-14.04.tar.xz" - wget -O - ${LLVM_URL} | tar -Jxvf - --strip 1 -C llvm-${LLVM_VERSION} + wget -O - ${LLVM_URL} | tar -Jxvf - --strip 1 -C ${TWD}/llvm-${LLVM_VERSION} + fi + ${TWD}/llvm-${LLVM_VERSION}/bin/llvm-config --version; + export LLVM_CONFIG="${TWD}/llvm-${LLVM_VERSION}/bin/llvm-config"; +fi + +if [[ ${BUILD:-} == cmake ]]; then + # There are cases where the directory exists, but the exe is not available. + # Use this workaround for now. + if [[ ! -x ${TWD}/cmake/bin/cmake && -d ${TWD}/cmake ]]; then + rm -fr ${TWD}/cmake + fi + if [[ ! -d ${TWD}/cmake ]]; then + CMAKE_URL="https://www.cmake.org/files/v3.6/cmake-3.6.1-Linux-x86_64.tar.gz" + wget --version + # wget version 1.13.4 thinks this certificate is invalid, even though it's fine. + # "ERROR: no certificate subject alternative name matches" + # See also: https://github.com/travis-ci/travis-ci/issues/5059 + mkdir ${TWD}/cmake && + wget -O - --no-check-certificate ${CMAKE_URL} | tar --strip-components=1 -xz -C ${TWD}/cmake + cmake --version fi - llvm-${LLVM_VERSION}/bin/llvm-config --version; - export LLVM_CONFIG="llvm-${LLVM_VERSION}/bin/llvm-config"; fi # What versions are we ACTUALLY running? diff --git a/bin/ci/windows/install-dependencies.bat b/bin/ci/windows/install-dependencies.bat new file mode 100644 index 0000000000..68793172a0 --- /dev/null +++ b/bin/ci/windows/install-dependencies.bat @@ -0,0 +1,13 @@ +if "%build%" == "scons" ( + rem Installing pip will install setuptools/easy_install. + python get-pip.py + + 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-220.win-amd64-py2.7.exe + rem (easy_install can do headless installs of .exe wizards) +) \ No newline at end of file