Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cpp prerequisities cmake #803

Merged
merged 1 commit into from
Jul 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
305 changes: 111 additions & 194 deletions sdks/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/${PROJECT_NAME}>
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/${PROJECT_NAME}>
$<INSTALL_INTERFACE:${PROJECT_NAME}/include>
)

# 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 $<TARGET_PDB_FILE:${PROJECT_NAME}> DESTINATION bin CONFIGURATIONS Debug OPTIONAL)
install(FILES $<TARGET_PDB_FILE:${AGONES_GRPC_TARGETS}> 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)
2 changes: 1 addition & 1 deletion sdks/cpp/build_scripts/msvs_2017_x64_release.bat
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 11 additions & 1 deletion sdks/cpp/cmake/agonesConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -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)
Loading