From ead8495dbf58c097555f3b901357630863670c1c Mon Sep 17 00:00:00 2001 From: Dmitry Sazonov Date: Fri, 12 Jul 2019 17:57:16 +0300 Subject: [PATCH] Cpp SDK. Cross-platform cmake-based build of third parties. --- sdks/cpp/CMakeLists.txt | 305 +++++++----------- .../build_scripts/msvs_2017_x64_release.bat | 2 +- sdks/cpp/cmake/agonesConfig.cmake.in | 12 +- sdks/cpp/cmake/prerequisites.cmake | 198 ++++++++++++ .../content/en/docs/Guides/Client SDKs/cpp.md | 51 +-- 5 files changed, 353 insertions(+), 215 deletions(-) create mode 100644 sdks/cpp/cmake/prerequisites.cmake diff --git a/sdks/cpp/CMakeLists.txt b/sdks/cpp/CMakeLists.txt index b601e3614d..6020ab071d 100644 --- a/sdks/cpp/CMakeLists.txt +++ b/sdks/cpp/CMakeLists.txt @@ -20,38 +20,72 @@ cmake_minimum_required (VERSION 3.13.0) # For *nix: cmake --build . --target install -- -s option(AGONES_SILENT_OUTPUT "Show only warnings/error messages" OFF) if (AGONES_SILENT_OUTPUT) - function(message) - list(GET ARGV 0 MessageType) - if(MessageType STREQUAL FATAL_ERROR OR - MessageType STREQUAL SEND_ERROR OR - MessageType STREQUAL WARNING OR - MessageType STREQUAL AUTHOR_WARNING) - list(REMOVE_AT ARGV 0) - _message(${MessageType} "${ARGV}") - endif() - endfunction() - - set(CMAKE_INSTALL_MESSAGE NEVER) - set(CMAKE_VERBOSE_MAKEFILE OFF) - set_property(GLOBAL PROPERTY RULE_MESSAGES OFF) - set_property(GLOBAL PROPERTY TARGET_MESSAGES OFF) + function(message) + list(GET ARGV 0 MessageType) + list(REMOVE_AT ARGV 0) + if (MessageType STREQUAL FATAL_ERROR OR + MessageType STREQUAL SEND_ERROR OR + MessageType STREQUAL WARNING OR + MessageType STREQUAL AUTHOR_WARNING OR + NOT ${AGONES_SILENT_OUTPUT} + ) + _message(${MessageType} "${ARGV}") + endif() + endfunction() + + set(CMAKE_INSTALL_MESSAGE NEVER) + set(CMAKE_VERBOSE_MAKEFILE OFF) + set_property(GLOBAL PROPERTY RULE_MESSAGES OFF) + set_property(GLOBAL PROPERTY TARGET_MESSAGES OFF) endif(AGONES_SILENT_OUTPUT) -# Project AGONES -project(agones VERSION 0.9.0 HOMEPAGE_URL https://github.com/googleforgames/agones LANGUAGES C CXX) +# Getting version from git +find_package(Git QUIET) +set(AGONES_VERSION "0.0.0") +if (Git_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ) + if (${result} EQUAL 0) + string(REGEX MATCH "\\d+.\\d+.\\d+" AGONES_VERSION ${output}) + endif() +else() + message(WARNING "Git was not found. Current Agones version is set to ${AGONES_VERSION}") +endif() -# Build options -option(AGONES_BUILD_SHARED "Build Agones C++ SDK as dynamic library" OFF) -option(AGONES_FORCE_GRPC_VERSION "Build Agones C++ SDK only with officially supported gRPC version" ON) -option(AGONES_CREATE_PACKAGE "Generate CMake installation step and package files for Agones C++ SDK" ON) +# Project AGONES +project(agones VERSION ${AGONES_VERSION} HOMEPAGE_URL https://github.com/googleforgames/agones LANGUAGES C CXX) + +# Options +option(AGONES_FORCE_GRPC_VERSION "Build Agones C++ SDK only with supported gRPC version" ON) +option(AGONES_BUILD_ONLY_PREREQUISITIES "Build only prerequisites of Agones" OFF) +option(AGONES_ZLIB_STATIC "Use static version of ZLIB" ON) +option(AGONES_BUILD_THIRDPARTY_DEBUG "Build debug version of thirdparty libraries (MSVC only)" OFF) +set(AGONES_THIRDPARTY_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}" CACHE STRING "Path for installing third-party OpenSSL and gRPC, if they are not found with find_package") +set(AGONES_OPENSSL_CONFIG_STRING "VC-WIN64A" CACHE STRING "See https://github.com/openssl/openssl/blob/master/INSTALL for details") + +# Prerequisities +include(./cmake/prerequisites.cmake) +find_package(ZLIB REQUIRED) +find_package(Protobuf REQUIRED CONFIG) +find_package(gRPC ${AGONES_GRPC_VERSION} ${AGONES_GRPC_VERSION_MATCH} REQUIRED CONFIG) + +if (AGONES_BUILD_ONLY_PREREQUISITIES) + return() +endif() -# Currently we doesn't support build time generation of proto/grpc files, +# Currently we doesn't support build time generation of proto/gRPC files, # so gRPC version should be strict set(AGONES_FORCE_GRPC_VERSION ON) +set(AGONES_GRPC_VERSION_MATCH "") +if (AGONES_FORCE_GRPC_VERSION) + set(AGONES_GRPC_VERSION_MATCH EXACT) +endif() # Settings -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") - set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(CMAKE_CXX_STANDARD 14) @@ -62,210 +96,93 @@ set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) set(CMAKE_DEBUG_POSTFIX "d") set(AGONES_GRPC_VERSION "1.16.1") -if (AGONES_BUILD_SHARED) - add_compile_definitions( - PROTOBUF_USE_DLLS - LIBPROTOBUF_EXPORTS - ) -endif() - -# --> Connecting gRPC -macro(validate_path IN_PATH OUT_RESULT) - set(${OUT_RESULT} FALSE) - if (NOT IS_DIRECTORY ${${IN_PATH}}) - file(TO_CMAKE_PATH "$ENV{${IN_PATH}}" ${IN_PATH}) - else() - file(TO_CMAKE_PATH "${${IN_PATH}}" ${IN_PATH}) - endif() - if (IS_DIRECTORY ${${IN_PATH}}) - set(${OUT_RESULT} TRUE) - endif() -endmacro(validate_path) - -set(GRPC_IS_INSTALLED FALSE) -set(GRPC_PATH_FOUND FALSE) -validate_path(grpc_SOURCE_DIR GRPC_PATH_FOUND) -if (GRPC_PATH_FOUND) - # Checking if we use gRPC package or gRPC source folder - # Usually it should be findXXX.cmake or xxxConfig.cmake files, but for gRPC we need to check gRPCTargets.cmake too - if (EXISTS ${grpc_SOURCE_DIR}/gRPCTargets.cmake) - set(GRPC_IS_INSTALLED TRUE) - find_package(gRPC CONFIG REQUIRED) - endif() -else() - # Download gRPC, if necessary - include(Fetch_gRPC) -endif() - -add_subdirectory(${grpc_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL) - -# Check gRPC version -get_directory_property(GRPC_VERSION DIRECTORY ${grpc_SOURCE_DIR} DEFINITION PACKAGE_VERSION) -if (NOT GRPC_VERSION STREQUAL AGONES_GRPC_VERSION) - set(GRPC_VERSION_SEVERITY WARNING) - if (AGONES_FORCE_GRPC_VERSION) - set(GRPC_VERSION_SEVERITY FATAL_ERROR) - endif() - message(${GRPC_VERSION_SEVERITY} "Agones SDK currently supports only \"${AGONES_GRPC_VERSION}\" version. Building with \"${GRPC_VERSION}\" may cause unexpected problems.") -endif() - -# Configuring -set(AGONES_DEPENDENCIES libprotobuf grpc++_unsecure) -set(AGONES_GRPC_TARGETS address_sorting c-ares gpr grpc_unsecure grpc++_unsecure libprotobuf zlibstatic) -foreach(THIRDPARTY_TARGET ${AGONES_GRPC_TARGETS}) - set_property(TARGET ${THIRDPARTY_TARGET} PROPERTY FOLDER third_party) -endforeach() -# <-- Connecting gRPC - # Platform specific stuff if (WIN32) - # Windows - add_compile_definitions( - _WIN32_WINNT=0x0600 - WINDOWS - ) + # Windows + add_compile_definitions( + _WIN32_WINNT=0x0600 + WINDOWS + ) elseif (APPLE) - # Mac OS + # Mac OS elseif (UNIX AND NOT APPLE) - # Linux -endif() - -if (MSVS) - set(OPT_DISABLE_COMPILER_WARNINGS /wd4101 /wd4146 /wd4251 /wd4661) - target_compile_options(libprotobuf PUBLIC ${OPT_DISABLE_COMPILER_WARNINGS}) - target_compile_options(${PROJECT_NAME} PUBLIC ${OPT_DISABLE_COMPILER_WARNINGS}) -else() - set(OPT_DISABLE_COMPILER_WARNINGS -wd4101 -wd4146 -wd4251 -wd4661) + # Linux endif() # Agones SDK include(./sources.cmake) -set(AGONES_BUILD_TYPE STATIC) -if (AGONES_BUILD_SHARED) - set(AGONES_BUILD_TYPE SHARED) +# Global header +set(GLOBAL_HEADER "${PROJECT_NAME}_global.h") +set(GLOBAL_CONFIG_CONTENT "\n") +configure_file(cmake/${GLOBAL_HEADER}.in ${GLOBAL_HEADER} @ONLY) + +if(MSVC) + add_definitions(/FI"${GLOBAL_HEADER}") +else() + # GCC or Clang + add_definitions(-include ${GLOBAL_HEADER}) endif() -add_library(${PROJECT_NAME} ${AGONES_BUILD_TYPE} ${ALL_FILES}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${AGONES_DEPENDENCIES}) +add_library(${PROJECT_NAME} STATIC ${ALL_FILES}) +target_link_libraries(${PROJECT_NAME} PUBLIC protobuf::libprotobuf gRPC::grpc++_unsecure) target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ - $ + $ + $ + $ ) # Fix compiler warnings # https://github.com/protocolbuffers/protobuf/blob/master/cmake/README.md#notes-on-compiler-warnings +if (MSVC) + set(OPT_DISABLE_COMPILER_WARNINGS /wd4101 /wd4146 /wd4251 /wd4661) + target_compile_options(${PROJECT_NAME} PUBLIC ${OPT_DISABLE_COMPILER_WARNINGS}) +endif() # Export header include(GenerateExportHeader) set(EXPORT_HEADER "${PROJECT_NAME}_export.h") generate_export_header(${PROJECT_NAME} EXPORT_FILE_NAME ${EXPORT_HEADER} DEFINE_NO_DEPRECATED) -# Global header -set(GLOBAL_HEADER "${PROJECT_NAME}_global.h") -set(GLOBAL_CONFIG_CONTENT "") -if (AGONES_BUILD_SHARED) - set(GLOBAL_CONFIG_CONTENT "\ -// Dynamic linkage require macro for protobuf\n\ -#ifndef PROTOBUF_USE_DLLS\n\ -#define PROTOBUF_USE_DLLS\n\ -#endif\n" - ) -endif() -configure_file(cmake/${GLOBAL_HEADER}.in ${GLOBAL_HEADER} @ONLY) - -if(MSVC) - add_definitions(/FI"${GLOBAL_HEADER}") -else() - # GCC or Clang - add_definitions(-include ${GLOBAL_HEADER}) -endif() - # CMake package generation include(CMakePackageConfigHelpers) -if (AGONES_CREATE_PACKAGE) - set(_INCLUDE_DIRS "include") - set(_CMAKE_CONFIG_DESTINATION "cmake") +set(_INCLUDE_DIRS "agones/include") +set(_CMAKE_CONFIG_DESTINATION "agones/cmake") - # If gRPC is built from source (not from package), then we need to redistribute gRPC and it dependencies - if (NOT GRPC_IS_INSTALLED) - # gRPC headers - install(DIRECTORY ${grpc_SOURCE_DIR}/include/ DESTINATION ${_INCLUDE_DIRS}) - # Protobuf headers - install(DIRECTORY ${grpc_SOURCE_DIR}/third_party/protobuf/src/ DESTINATION ${_INCLUDE_DIRS} FILES_MATCHING PATTERN "*.h") - # gRPC and it dependencies - if (NOT AGONES_BUILD_SHARED) - install(TARGETS ${AGONES_GRPC_TARGETS} EXPORT gRPC - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION ${_INCLUDE_DIRS} - ) - endif() - endif() - - # Config for find_package - configure_package_config_file( +# Config for find_package +configure_package_config_file( cmake/${PROJECT_NAME}Config.cmake.in ${PROJECT_NAME}Config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/${_CMAKE_CONFIG_DESTINATION} PATH_VARS _INCLUDE_DIRS PROJECT_VERSION - NO_SET_AND_CHECK_MACRO - ) - # Build artifacts - install(TARGETS ${PROJECT_NAME} ${AGONES_GRPC_TARGETS} EXPORT ${PROJECT_NAME} - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin + NO_SET_AND_CHECK_MACRO +) + +# Build artifacts +install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} + LIBRARY DESTINATION ${PROJECT_NAME}/lib + ARCHIVE DESTINATION ${PROJECT_NAME}/lib + RUNTIME DESTINATION ${PROJECT_NAME}/bin INCLUDES DESTINATION ${_INCLUDE_DIRS} - ) - install(EXPORT ${PROJECT_NAME} DESTINATION ${_CMAKE_CONFIG_DESTINATION} FILE ${PROJECT_NAME}Targets.cmake) - # Package config - install( +) +install(EXPORT ${PROJECT_NAME} DESTINATION ${_CMAKE_CONFIG_DESTINATION} FILE ${PROJECT_NAME}Targets.cmake) +# Package config +install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake DESTINATION ${_CMAKE_CONFIG_DESTINATION} - ) - # Agones header files - install( +) +# Agones header files +install( FILES ${HEADER_FILES} "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_HEADER}" "${CMAKE_CURRENT_BINARY_DIR}/${GLOBAL_HEADER}" - DESTINATION include/${PROJECT_NAME} - ) - # Google header files - install( + DESTINATION ${_INCLUDE_DIRS}/${PROJECT_NAME} +) +# Google header files +install( FILES ${GOOGLE_HEADER_FILES} - DESTINATION include/google/api - ) - # PDB file - if (AGONES_BUILD_SHARED) - install(FILES $ DESTINATION bin CONFIGURATIONS Debug OPTIONAL) - install(FILES $ DESTINATION bin CONFIGURATIONS Debug OPTIONAL) - endif() - - unset(_INCLUDE_DIRS) - unset(_CMAKE_CONFIG_DESTINATION) -else() # Package is created with absolute pathes in build folder - # Use agones and thirdparty include directories - set(_INCLUDE_DIRS - "${CMAKE_CURRENT_LIST_DIR}/include" - "${grpc_SOURCE_DIR}/include" - "${grpc_SOURCE_DIR}/third_party/protobuf/src" - ) - set(_CMAKE_CONFIG_DESTINATION "${CMAKE_BINARY_DIR}") - - configure_package_config_file( - cmake/${PROJECT_NAME}Config.cmake.in - "${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - INSTALL_DESTINATION ${_CMAKE_CONFIG_DESTINATION} - PATH_VARS _INCLUDE_DIRS PROJECT_VERSION - NO_SET_AND_CHECK_MACRO - ) - export(TARGETS ${PROJECT_NAME} ${AGONES_GRPC_TARGETS} FILE "${CMAKE_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") - # Register SDK local artifacts in system https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#package-registry-example - #export(PACKAGE ${PROJECT_NAME}) + DESTINATION ${_INCLUDE_DIRS}/google/api +) - unset(_INCLUDE_DIRS) - unset(_CMAKE_CONFIG_DESTINATION) -endif(AGONES_CREATE_PACKAGE) +unset(_INCLUDE_DIRS) +unset(_CMAKE_CONFIG_DESTINATION) diff --git a/sdks/cpp/build_scripts/msvs_2017_x64_release.bat b/sdks/cpp/build_scripts/msvs_2017_x64_release.bat index e56429ba06..9c586fb432 100644 --- a/sdks/cpp/build_scripts/msvs_2017_x64_release.bat +++ b/sdks/cpp/build_scripts/msvs_2017_x64_release.bat @@ -17,6 +17,6 @@ pushd .. if not exist ".build" md ".build" pushd ".build" cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=./install -Wno-dev -cmake --build . --config Release --target INSTALL +cmake --build . --config Release --target install popd popd diff --git a/sdks/cpp/cmake/agonesConfig.cmake.in b/sdks/cpp/cmake/agonesConfig.cmake.in index 64c1e609ac..981b761d63 100644 --- a/sdks/cpp/cmake/agonesConfig.cmake.in +++ b/sdks/cpp/cmake/agonesConfig.cmake.in @@ -1,10 +1,20 @@ -set(agones_VERSION 0.9.0) +set(agones_VERSION @agones_VERSION@) @PACKAGE_INIT@ set(agones_INCLUDE_DIRS @PACKAGE__INCLUDE_DIRS@) +set(AGONES_OWN_GRPC @AGONES_OWN_GRPC@) +if (${AGONES_OWN_GRPC}) + set(ZLIB_ROOT @zlib_DIR@) + set(ZLIB_LIBRARIES @ZLIB_LIBRARIES@) + set(OPENSSL_ROOT_DIR @OPENSSL_ROOT_DIR@) +endif() + include(CMakeFindDependencyMacro) +find_dependency(ZLIB REQUIRED) +find_dependency(Protobuf REQUIRED CONFIG) +find_dependency(gRPC REQUIRED CONFIG) include("${CMAKE_CURRENT_LIST_DIR}/agonesTargets.cmake") check_required_components(agones) \ No newline at end of file diff --git a/sdks/cpp/cmake/prerequisites.cmake b/sdks/cpp/cmake/prerequisites.cmake new file mode 100644 index 0000000000..849235879a --- /dev/null +++ b/sdks/cpp/cmake/prerequisites.cmake @@ -0,0 +1,198 @@ +# Copyright 2019 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required (VERSION 3.13.0) + +option(AGONES_BUILD_THIRDPARTY_DEBUG "Build debug version of thirdparty libraries (MSVC only)" OFF) +set(AGONES_OPENSSL_CONFIG_STRING "VC-WIN64A" CACHE STRING "See https://github.com/openssl/openssl/blob/master/INSTALL for details") +set(AGONES_THIRDPARTY_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}" CACHE STRING "Path for installing third-party OpenSSL and gRPC, if they are not found with find_package") + +if (NOT DEFINED MSVC) + set(AGONES_BUILD_THIRDPARTY_DEBUG OFF) + set(AGONES_OPENSSL_CONFIG_STRING "" CACHE STRING "" FORCE) +endif() + +include(ProcessorCount) +ProcessorCount(CPU_COUNT) +if (CPU_COUNT GREATER 0 AND NOT DEFINED CMAKE_BUILD_PARALLEL_LEVEL) + set($ENV{CMAKE_BUILD_PARALLEL_LEVEL} ${CPU_COUNT}) +endif(CPU_COUNT) + +# gRPC repo and version +set(gRPC_GIT_REPO "https://github.com/gRPC/gRPC.git") +set(gRPC_GIT_TAG "v1.16.1") + +# OpenSSL required only for successful build gRPC +set(OPENSSL_GIT_REPO "https://github.com/openssl/openssl.git") +set(OPENSSL_GIT_TAG "OpenSSL_1_1_1-stable") + +include(FetchContent) + +function(download_git_repo NAME REPO TAG) + set(BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NAME}) + set(${NAME}_SOURCE_DIR "${BASE_DIR}/src") + FetchContent_Declare( + ${NAME} + GIT_REPOSITORY "${REPO}" + GIT_TAG "${TAG}" + PREFIX ${NAME} + SOURCE_DIR "${BASE_DIR}/src" + BINARY_DIR "${BASE_DIR}/.bin" + INSTALL_DIR "${BASE_DIR}/.install" + SUBBUILD_DIR "${BASE_DIR}/.build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + ) + FetchContent_GetProperties(${NAME}) + if (NOT ${NAME}_POPULATED) + message("Fetching ${NAME} ${TAG}") + FetchContent_Populate( + ${NAME} + QUIET + GIT_REPOSITORY "${REPO}" + GIT_TAG "${TAG}" + PREFIX ${NAME} + SOURCE_DIR "${BASE_DIR}/src" + BINARY_DIR "${BASE_DIR}/.bin" + INSTALL_DIR "${BASE_DIR}/.install" + SUBBUILD_DIR "${BASE_DIR}/.build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + ) + endif() + set(${NAME}_SOURCE_DIR "${${NAME}_SOURCE_DIR}" CACHE PATH "Source directory for ${NAME}" FORCE) +endfunction(download_git_repo) + +function(execute_and_check WORKING_DIR) + execute_process( + COMMAND ${ARGN} + WORKING_DIRECTORY ${WORKING_DIR} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + ) + set(OUTPUT_TYPE STATUS) + if (NOT ${result} EQUAL 0) + set(OUTPUT_TYPE FATAL_ERROR) + endif() + message(${OUTPUT_TYPE} ${output}) +endfunction() + +function(invoke_cmake_build NAME CMAKELISTS_PATH) + message(STATUS "Building ${NAME}...") + + # Build directory + set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/.bin) + set(INSTALL_DIR ${AGONES_THIRDPARTY_INSTALL_PATH}/${NAME}) + file(MAKE_DIRECTORY ${BUILD_DIR}) + + # Makefile generation + set(ARG_BUILD_TYPE "") + set(ARG_CONFIG_DEBUG "--config" "Debug") + set(ARG_CONFIG_RELEASE "--config" "Release") + if (NOT ${CMAKE_BUILD_TYPE} STREQUAL "") + set(ARG_BUILD_TYPE "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") + set(ARG_CONFIG_DEBUG "") + set(ARG_CONFIG_RELEASE "") + endif() + + execute_and_check(${BUILD_DIR} ${CMAKE_COMMAND} ${CMAKELISTS_PATH} -G ${CMAKE_GENERATOR} -Wno-dev ${ARG_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DCMAKE_PREFIX_PATH=${AGONES_THIRDPARTY_INSTALL_PATH} ${ARGN}) + + # Building + if (${AGONES_BUILD_THIRDPARTY_DEBUG}) + execute_and_check(${BUILD_DIR} ${CMAKE_COMMAND} --build . ${ARG_CONFIG_DEBUG} --target install) + endif() + + execute_and_check(${BUILD_DIR} ${CMAKE_COMMAND} --build . ${ARG_CONFIG_RELEASE} --target install) + set(${NAME}_DIR "${INSTALL_DIR}" CACHE PATH "CMake package directory for ${NAME}" FORCE) +endfunction(invoke_cmake_build) + +find_package(gRPC CONFIG QUIET) +find_package(OpenSSL QUIET) + +# OpenSSL // Required only for gRPC build. Do not build, if gRPC is found. +if (NOT ${OpenSSL_FOUND} AND NOT ${gRPC_FOUND}) + set(OPENSSL_ROOT_DIR "${AGONES_THIRDPARTY_INSTALL_PATH}/OpenSSL" CACHE PATH "OpenSSL root directory" FORCE) + find_package(OpenSSL QUIET) + if (NOT ${OpenSSL_FOUND}) + download_git_repo(openssl ${OPENSSL_GIT_REPO} ${OPENSSL_GIT_TAG}) + message(STATUS "Building OpenSSL... ${AGONES_OPENSSL_CONFIG_STRING}") + if (WIN32) + execute_and_check(${openssl_SOURCE_DIR} perl Configure ${AGONES_OPENSSL_CONFIG_STRING} "--prefix=${OPENSSL_ROOT_DIR}" "--openssldir=${OPENSSL_ROOT_DIR}") + execute_and_check(${openssl_SOURCE_DIR} nmake) + execute_and_check(${openssl_SOURCE_DIR} nmake install) + else() + execute_and_check(${openssl_SOURCE_DIR} "./config" "--prefix=${OPENSSL_ROOT_DIR}" "--openssldir=${OPENSSL_ROOT_DIR}") + execute_and_check(${openssl_SOURCE_DIR} make) + execute_and_check(${openssl_SOURCE_DIR} make install) + endif() + endif() +endif() + +# gRPC +set(AGONES_OWN_GRPC FALSE CACHE BOOL "Third party is built by Agones") +if (NOT ${gRPC_FOUND}) + download_git_repo(gRPC ${gRPC_GIT_REPO} ${gRPC_GIT_TAG}) + file(MAKE_DIRECTORY ${AGONES_THIRDPARTY_INSTALL_PATH}) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${AGONES_THIRDPARTY_INSTALL_PATH}) + + # Build gRPC prerequisites + invoke_cmake_build(zlib ${gRPC_SOURCE_DIR}/third_party/zlib) + set(ZLIB_ROOT "${zlib_DIR}" CACHE PATH "ZLIB_ROOT" FORCE) + set(ZLIB_PARAM) + if (AGONES_ZLIB_STATIC) + set(ZLIB_NAME "libz${CMAKE_STATIC_LIBRARY_SUFFIX}") + if (WIN32) + set(ZLIB_NAME "zlibstatic${CMAKE_STATIC_LIBRARY_SUFFIX}") + endif() + set(ZLIB_LIBRARY "${ZLIB_ROOT}/lib/${ZLIB_NAME}" CACHE PATH "ZLIB path" FORCE) + set(ZLIB_PARAM "-DZLIB_LIBRARY=${ZLIB_LIBRARY}") + endif() + + invoke_cmake_build(c-ares ${gRPC_SOURCE_DIR}/third_party/cares/cares + "-DCARES_STATIC=ON" + "-DCARES_SHARED=OFF" + ) + invoke_cmake_build(Protobuf ${gRPC_SOURCE_DIR}/third_party/protobuf/cmake + "-DZLIB_ROOT=${zlib_DIR}" + "${ZLIB_PARAM}" + "-Dprotobuf_MSVC_STATIC_RUNTIME=OFF" + "-Dprotobuf_BUILD_TESTS=OFF" + ) + + # Build gRPC as cmake package + set(OPENSSL_PARAM "") + if (DEFINED OPENSSL_ROOT_DIR) + set(OPENSSL_PARAM "-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}") + endif() + invoke_cmake_build(gRPC ${gRPC_SOURCE_DIR} + "${OPENSSL_PARAM}" + "-DZLIB_ROOT=${zlib_DIR}" + "${ZLIB_PARAM}" + "-DgRPC_INSTALL=ON" + "-DgRPC_BUILD_TESTS=OFF" + "-DgRPC_BUILD_CSHARP_EXT=OFF" + "-DgRPC_PROTOBUF_PROVIDER=package" + "-DgRPC_PROTOBUF_PACKAGE_TYPE=CONFIG" + "-DgRPC_ZLIB_PROVIDER=package" + "-DgRPC_CARES_PROVIDER=package" + "-DgRPC_SSL_PROVIDER=package" + ) + set(AGONES_OWN_GRPC TRUE CACHE BOOL "Third party is built by Agones" FORCE) +endif() +mark_as_advanced(AGONES_OWN_GRPC) \ No newline at end of file diff --git a/site/content/en/docs/Guides/Client SDKs/cpp.md b/site/content/en/docs/Guides/Client SDKs/cpp.md index 12a6b8bf3d..3c34ad80d5 100644 --- a/site/content/en/docs/Guides/Client SDKs/cpp.md +++ b/site/content/en/docs/Guides/Client SDKs/cpp.md @@ -91,7 +91,6 @@ status = sdk->SetAnnotation("test-annotation", "test value"); if (!status.ok()) { ... } ``` - To get the details on the [backing `GameServer`]({{< relref "_index.md#gameserver" >}}) call `sdk->GameServer(&gameserver)`, passing in a `stable::agones::dev::sdk::GameServer*` to push the results of the `GameServer` configuration into. @@ -127,46 +126,60 @@ When running on Agones, the above functions should only fail under exceptional c file a bug if it occurs. ### Building the Libraries from source -CMake is used to build SDK for all platforms. It is possible to build SDK as a static or dynamic library. +CMake is used to build SDK for all supported platforms (Linux/Window/MacOS). ## Prerequisites * CMake >= 3.13.0 * Git * C++14 compiler +Agones SDK depends on [gRPC](https://github.com/grpc/grpc/blob/master/BUILDING.md). If CMake can't find gRPC with find_package(), it download and build gRPC. +There are some extra prerequisites for OpenSSL on Windows, see [documentation](https://github.com/openssl/openssl/blob/master/NOTES.WIN): +* Perl +* NASM + +Note that OpenSSL is not used in Agones SDK, but it required to have full successfull build of gRPC. + ## Options -Following options are available -- **AGONES_BUILD_SHARED** (default is OFF) - build sdk as a shared library. -- **AGONES_CREATE_PACKAGE** (default is ON) - create an "install" step, to create a cmake package. +Following options are available: +- **AGONES_THIRDPARTY_INSTALL_PATH** (default is CMAKE_INSTALL_PREFIX) - installation path for Agones prerequisites (used only if gRPC and Protobuf are not found by find_package) +- **AGONES_ZLIB_STATIC** (default is ON) - use static version of zlib for gRPC + +(Windows only): +- **AGONES_BUILD_THIRDPARTY_DEBUG** (default is OFF) - build both debug and release versions of SDK's prerequisities. Option is not used if you already have built gRPC. +- **AGONES_OPENSSL_CONFIG_STRING** (default is VC-WIN64A) - arguments to configure OpenSSL build ([documentation](https://github.com/openssl/openssl/blob/master/INSTALL)). Used only if OpenSSL and gRPC is built by Agones. + +## Linux / MacOS +``` +mkdir -p .build +cd .build +cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./install +cmake --build . --target install +``` ## Windows Building with Visual Studio: ``` md .build cd .build -cmake .. -G "Visual Studio 15 2017 Win64" -Wno-dev -cmake --build . --config Release +cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=./install +cmake --build . --config Release --target install ``` Building with NMake ``` md .build cd .build -cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -Wno-dev -cmake --build . -``` - -## Linux / MacOS -``` -mkdir -p .build -cd .build -cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" -Wno-dev -cmake --build . +cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./install +cmake --build . --target install ``` ## Remarks -CMake option `-Wno-dev` is specified to suppress [CMP0048](https://cmake.org/cmake/help/v3.13/policy/CMP0048.html) deprecation warning for gRPC dependency. +**CMAKE_INSTALL_PREFIX** may be skipped if it is OK to install Agones SDK to a default location (usually /usr/local or c:/Program Files/Agones). + +CMake option `-Wno-dev` is specified to suppress [CMP0048](https://cmake.org/cmake/help/v3.13/policy/CMP0048.html) deprecation warning for gRPC build. + +If **AGONES_ZLIB_STATIC** is set to OFF, ensure that you have installed zlib. For Windows it's enough to copy zlib.dll near to gameserver executable. For Linux/Mac usually no actions are needed. ### Using SDK In CMake-based projects it's enough to specify a folder where SDK is installed with `CMAKE_PREFIX_PATH` and use `find_package(agones CONFIG REQUIRED)` command. For example: {{< ghlink href="examples/cpp-simple" >}}cpp-simple{{< / >}}. -If **AGONES_CREATE_PACKAGE** option is off, then `CMAKE_PREFIX_PATH` should be set to a path where SDK is built (usually `agones/sdks/cpp/.build`). It maybe useful to disable some [protobuf warnings](https://github.com/protocolbuffers/protobuf/blob/master/cmake/README.md#notes-on-compiler-warnings) in your project.