diff --git a/cpp/Chat/client/CMakeLists.txt b/cpp/Chat/client/CMakeLists.txt new file mode 100644 index 000000000..0b822da79 --- /dev/null +++ b/cpp/Chat/client/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.16) + +project(chat_client CXX) + +include(../../cmake/common.cmake) + +set(common_sources ChatUtils.cpp ChatUtils.h Chat.ice) + +add_executable(chatgl2client Client.cpp ChatSession.ice ${common_sources}) +slice2cpp_generate(chatgl2client) +target_link_libraries(chatgl2client Ice::Ice Ice::Glacier2) + +add_executable(chatpollclient PollingClient.cpp PollingChat.ice ${common_sources}) +slice2cpp_generate(chatpollclient) +target_link_libraries(chatpollclient Ice::Ice) diff --git a/cpp/Chat/client/ChatSession.ice b/cpp/Chat/client/ChatSession.ice index f076f63e8..53dbde58a 100644 --- a/cpp/Chat/client/ChatSession.ice +++ b/cpp/Chat/client/ChatSession.ice @@ -2,9 +2,10 @@ #pragma once +#include "Chat.ice" + #include #include -#include module Chat { diff --git a/cpp/Chat/client/ChatUtils.cpp b/cpp/Chat/client/ChatUtils.cpp index 761a38e3c..770674e54 100644 --- a/cpp/Chat/client/ChatUtils.cpp +++ b/cpp/Chat/client/ChatUtils.cpp @@ -1,7 +1,8 @@ // Copyright (c) ZeroC, Inc. -#include -#include +#include "ChatUtils.h" +#include "Chat.h" + #include using namespace std; diff --git a/cpp/Chat/client/PollingChat.ice b/cpp/Chat/client/PollingChat.ice index 96e8a6e3d..1dff5221a 100644 --- a/cpp/Chat/client/PollingChat.ice +++ b/cpp/Chat/client/PollingChat.ice @@ -2,8 +2,9 @@ #pragma once +#include "Chat.ice" + #include -#include /** * diff --git a/cpp/Chat/client/PollingClient.cpp b/cpp/Chat/client/PollingClient.cpp index 74fd0923e..330baa3cb 100644 --- a/cpp/Chat/client/PollingClient.cpp +++ b/cpp/Chat/client/PollingClient.cpp @@ -2,6 +2,7 @@ #include "ChatUtils.h" #include "PollingChat.h" + #include #include #include diff --git a/cpp/Chat/client/README.md b/cpp/Chat/client/README.md index 3254aa08e..b0d878236 100644 --- a/cpp/Chat/client/README.md +++ b/cpp/Chat/client/README.md @@ -1,3 +1,5 @@ +# Chat Client + This demo is a C++ command-line client for the [ZeroC Chat Demo][1]. It connects to a single chat room, allowing you to chat with other chat room participants. @@ -9,11 +11,41 @@ You may run either the Glacier2 client (`chatgl2client`) or the polling client (`chatpollclient`), as well as any username or password to connect. If you wish to use your own server from the `server` direcory you should specify -the appropriate custom configuration file when launching the client: +the appropriate custom configuration file when launching the client. + +To build the demo run: + +```shell +cmake -B build -S . +cmake --build build --config Release +``` +To run the the Glacier2 client: + +**Linux/macOS:** + +```shell +./build/chatgl2client --Ice.Config=config.gl2client ``` -chatgl2client --Ice.Config=config.gl2client -chatpollclient --Ice.Config=config.pollclient + +**Windows:** + +```shell +build\Release\chatgl2client --Ice.Config=config.gl2client +``` + +To run the the Polling client: + +**Linux/macOS:** + +```shell +./build/chatpollclient --Ice.Config=config.pollclient +``` + +**Windows:** + +```shell +build\Release\chatpollclient --Ice.Config=config.pollclient ``` [1]: https://doc.zeroc.com/display/Doc/Chat+Demo diff --git a/cpp/Chat/server/CMakeLists.txt b/cpp/Chat/server/CMakeLists.txt new file mode 100644 index 000000000..ea83b55f6 --- /dev/null +++ b/cpp/Chat/server/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.16) + +project(chat_client CXX) + +include(../../cmake/common.cmake) + +add_executable(chatserver + ChatRoom.cpp ChatRoom.h + ChatServer.cpp + ChatSessionI.cpp ChatSessionI.h + ChatSessionManagerI.cpp ChatSessionManagerI.h + Chat.ice ChatSession.ice + + PollingChatSessionFactoryI.cpp PollingChatSessionFactoryI.h + PollingChatSessionI.cpp PollingChatSessionI.h + PollingChat.ice + + ChatUtils.cpp ChatUtils.h +) +slice2cpp_generate(chatserver) +target_link_libraries(chatserver Ice::Ice Ice::Glacier2) diff --git a/cpp/Chat/server/ChatRoom.cpp b/cpp/Chat/server/ChatRoom.cpp index 3af467352..18b186911 100644 --- a/cpp/Chat/server/ChatRoom.cpp +++ b/cpp/Chat/server/ChatRoom.cpp @@ -1,6 +1,6 @@ // Copyright (c) ZeroC, Inc. -#include +#include "ChatRoom.h" using namespace std; diff --git a/cpp/Chat/server/ChatSession.ice b/cpp/Chat/server/ChatSession.ice index f076f63e8..53dbde58a 100644 --- a/cpp/Chat/server/ChatSession.ice +++ b/cpp/Chat/server/ChatSession.ice @@ -2,9 +2,10 @@ #pragma once +#include "Chat.ice" + #include #include -#include module Chat { diff --git a/cpp/Chat/server/ChatSessionManagerI.h b/cpp/Chat/server/ChatSessionManagerI.h index de60ff929..80eb30b61 100644 --- a/cpp/Chat/server/ChatSessionManagerI.h +++ b/cpp/Chat/server/ChatSessionManagerI.h @@ -3,7 +3,8 @@ #ifndef CHAT_SESSION_MANAGER_I_H #define CHAT_SESSION_MANAGER_I_H -#include +#include "ChatRoom.h" + #include #include diff --git a/cpp/Chat/server/ChatUtils.cpp b/cpp/Chat/server/ChatUtils.cpp index a1d7ef253..3cb353054 100644 --- a/cpp/Chat/server/ChatUtils.cpp +++ b/cpp/Chat/server/ChatUtils.cpp @@ -1,7 +1,7 @@ // Copyright (c) ZeroC, Inc. -#include -#include +#include "ChatUtils.h" +#include "Chat.h" #include #include diff --git a/cpp/Chat/server/PollingChat.ice b/cpp/Chat/server/PollingChat.ice index 96e8a6e3d..b7b8fe4c1 100644 --- a/cpp/Chat/server/PollingChat.ice +++ b/cpp/Chat/server/PollingChat.ice @@ -2,8 +2,10 @@ #pragma once +#include "Chat.ice" + #include -#include + /** * diff --git a/cpp/Chat/server/PollingChatSessionFactoryI.cpp b/cpp/Chat/server/PollingChatSessionFactoryI.cpp index f456a4225..6f7ccf526 100644 --- a/cpp/Chat/server/PollingChatSessionFactoryI.cpp +++ b/cpp/Chat/server/PollingChatSessionFactoryI.cpp @@ -1,9 +1,10 @@ // Copyright (c) ZeroC, Inc. -#include +#include "PollingChatSessionFactoryI.h" +#include "ChatUtils.h" +#include "PollingChatSessionI.h" + #include -#include -#include using namespace std; diff --git a/cpp/Chat/server/PollingChatSessionI.cpp b/cpp/Chat/server/PollingChatSessionI.cpp index 8bceb3904..d1d4316a5 100644 --- a/cpp/Chat/server/PollingChatSessionI.cpp +++ b/cpp/Chat/server/PollingChatSessionI.cpp @@ -1,7 +1,7 @@ // Copyright (c) ZeroC, Inc. -#include -#include +#include "PollingChatSessionI.h" +#include "ChatUtils.h" using namespace std; diff --git a/cpp/Chat/server/PollingChatSessionI.h b/cpp/Chat/server/PollingChatSessionI.h index 68d57b2b8..35da16334 100644 --- a/cpp/Chat/server/PollingChatSessionI.h +++ b/cpp/Chat/server/PollingChatSessionI.h @@ -3,9 +3,10 @@ #ifndef POLLING_CHAT_SESSION_I_H #define POLLING_CHAT_SESSION_I_H -#include +#include "ChatRoom.h" +#include "PollingChat.h" + #include -#include class PollCallbackAdapter; diff --git a/cpp/Chat/server/README.md b/cpp/Chat/server/README.md index 169502e20..1cc49e5ab 100644 --- a/cpp/Chat/server/README.md +++ b/cpp/Chat/server/README.md @@ -1,3 +1,5 @@ +# Chat Server + This demo is the server for the [ZeroC Chat Demo][1]. The chat demo server implements two different session systems, one using @@ -13,16 +15,31 @@ The Slice definitions for the chat demo are: You can use this demo if you want to host your own Chat Demo server. -To run the server: +To build the demo run: + +```shell +cmake -B build -S . +cmake --build build --config Release +``` + +To run the demo, first start the server: +**Linux/macOS:** + +```shell +./build/chatserver --Ice.Config=config.chatserver ``` -chatserver --Ice.Config=config.chatserver + +**Windows:** + +```shell +build\Release\chatserver --Ice.Config=config.chatserver ``` For push clients Glacier2 is also required, to start it run the following in a new shell: -``` +```shell glacier2router --Ice.Config=config.glacier2router ``` diff --git a/cpp/cmake/IceConfig.cmake b/cpp/cmake/IceConfig.cmake new file mode 100644 index 000000000..de66e7fef --- /dev/null +++ b/cpp/cmake/IceConfig.cmake @@ -0,0 +1,116 @@ +if (NOT Ice_HOME) + if (DEFINED ENV{ICE_HOME}) + set(Ice_HOME $ENV{ICE_HOME} CACHE PATH "Path to the Ice installation directory") + else() + message(FATAL_ERROR "Ice_HOME not set") + endif() +endif() + +if (NOT EXISTS ${Ice_HOME}) + message(FATAL_ERROR "The specified Ice_HOME directory does not exist: ${Ice_HOME}") +endif() + +find_program(Ice_SLICE2CPP_EXECUTABLE slice2cpp HINTS ${Ice_HOME}/cpp/bin PATH_SUFFIXES x64/Release x64/Debug) + +if(NOT DEFINED Ice_SLICE_DIR AND EXISTS ${Ice_HOME}/slice) + set(Ice_SLICE_DIR ${Ice_HOME}/slice CACHE PATH "Path to the Ice Slice files directory") +endif() + +# This is the only version we support for the demos right now +set(Ice_VERSION "3.8.0-alpha.0" CACHE STRING "Ice version") +set(Ice_DLL_VERSION "38a0" CACHE STRING "Ice DLL version") + +find_path(Ice_INCLUDE_DIR NAMES Ice/Ice.h HINTS ${Ice_HOME}/cpp/include) + +find_library(Ice_LIBRARY NAMES Ice Ice${Ice_DLL_VERSION} HINTS ${Ice_HOME}/cpp/lib/ PATH_SUFFIXES x64/Release) + +if (Ice_FIND_COMPONENTS) + foreach(component IN LISTS Ice_FIND_COMPONENTS) + string(TOUPPER "${component}" component_upcase) + find_library(Ice_${component_upcase}_LIBRARY NAMES ${component} ${component}${Ice_DLL_VERSION} HINTS ${Ice_HOME}/cpp/lib/ PATH_SUFFIXES x64/Release ) + endforeach() +endif() + +find_package_handle_standard_args(Ice + REQUIRED_VARS Ice_SLICE2CPP_EXECUTABLE + Ice_INCLUDE_DIR + Ice_LIBRARY + Ice_SLICE_DIR + VERSION_VAR Ice_VERSION) + +if(Ice_FOUND) + # set(Ice_LIBRARIES ${Ice_LIBRARY}) + if(WIN32) + set(Ice_INCLUDE_DIRS ${Ice_INCLUDE_DIR} ${Ice_HOME}/cpp/include/generated ${Ice_HOME}/cpp/include/generated/x64/Release) + else() + set(Ice_INCLUDE_DIRS ${Ice_INCLUDE_DIR} ${Ice_HOME}/cpp/include/generated) + endif() + + add_library(Ice::Ice UNKNOWN IMPORTED) + # set_target_properties(Ice::Ice PROPERTIES IMPORTED_IMPLIB ${Ice_LIBRARY}) + set_target_properties(Ice::Ice PROPERTIES + IMPORTED_LOCATION ${Ice_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES "${Ice_INCLUDE_DIRS}" + ) + + if (Ice_FIND_COMPONENTS) + foreach(component IN LISTS Ice_FIND_COMPONENTS) + string(TOUPPER "${component}" component_upcase) + add_library(Ice::${component} UNKNOWN IMPORTED) + set_target_properties(Ice::${component} PROPERTIES + IMPORTED_LOCATION ${Ice_${component_upcase}_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES "${Ice_INCLUDE_DIRS}" + ) + endforeach() + endif() +endif() + +# Function to generate C++ source files from Slice (.ice) files for a target using slice2cpp +# The target must have the Slice files in its sources +# The generated files are added to the target sources +# Usage: +# add_executable(a_target source1.cpp source2.ice source3.ice) +# slice2cpp_generate(a_target) +function(slice2cpp_generate target) + + # Get the list of source files for the target + get_target_property(sources ${target} SOURCES) + + # Create a directory to store the generated files + set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/generated/${target}) + make_directory(${output_dir}) + + # Add the generated headers files to the target include directories + target_include_directories(${target} PRIVATE ${output_dir}) + + # Process each Slice (.ice) file in the source list + # 1. Run the slice2cpp command to generate the header and source files + # 2. Add the generated files to the target sources + foreach(file IN LISTS sources) + if(file MATCHES "\\.ice$") + + get_filename_component(slice_file_name ${file} NAME_WE) + get_filename_component(slice_file_path ${file} ABSOLUTE) + set(output_files ${output_dir}/${slice_file_name}.h ${output_dir}/${slice_file_name}.cpp) + + add_custom_command( + OUTPUT ${output_files} + COMMAND ${Ice_SLICE2CPP_EXECUTABLE} -I${Ice_SLICE_DIR} ${slice_file_path} --output-dir ${output_dir} + DEPENDS ${slice_file_path} + COMMENT "${Ice_SLICE2CPP_EXECUTABLE} ${file} -> ${slice_file_name}.h ${slice_file_name}.cpp" + ) + + target_sources(${target} PRIVATE ${output_files}) + + endif() + endforeach() +endfunction() + +if(Ice_DEBUG) + message(STATUS "Ice_VERSION: ${Ice_VERSION}") + message(STATUS "Ice_HOME: ${Ice_HOME}") + message(STATUS "Ice_INCLUDE_DIR: ${Ice_INCLUDE_DIR}") + message(STATUS "Ice_INCLUDE_DIRS: ${Ice_INCLUDE_DIRS}") + message(STATUS "Ice_SLICE_DIR directory: ${Ice_SLICE_DIR}") + message(STATUS "Ice_LIBRARY: ${Ice_LIBRARY}") +endif() diff --git a/cpp/cmake/common.cmake b/cpp/cmake/common.cmake index 946e27d96..03978a470 100644 --- a/cpp/cmake/common.cmake +++ b/cpp/cmake/common.cmake @@ -5,88 +5,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Threads REQUIRED) -if (NOT Ice_HOME) - if (DEFINED ENV{ICE_HOME}) - set(Ice_HOME $ENV{ICE_HOME}) - else() - message(FATAL_ERROR "Ice_HOME not set") - endif() -endif() +set(Ice_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to Ice CMake configuration file") -if (NOT EXISTS ${Ice_HOME}) - message(FATAL_ERROR "The specified Ice_HOME directory does not exist: ${Ice_HOME}") -endif() - -find_program(Ice_SLICE2CPP_EXECUTABLE slice2cpp HINTS ${Ice_HOME}/cpp/bin PATH_SUFFIXES x64/Release x64/Debug) - -if (NOT Ice_SLICE2CPP_EXECUTABLE) - message(FATAL_ERROR "slice2cpp executable not found") -endif() - -if (NOT DEFINED Ice_SLICE_DIR) - set(Ice_SLICE_DIR ${Ice_HOME}/slice CACHE PATH "Path to Ice slice files") -endif() - -# TODO Use a variable -if (WIN32) -set(Ice_INCLUDE_DIRS ${Ice_HOME}/cpp/include ${Ice_HOME}/cpp/include/generated ${Ice_HOME}/cpp/include/generated/x64/Release) -find_library(Ice_LIBRARY NAMES ice38a0 HINTS ${Ice_HOME}/cpp/lib PATH_SUFFIXES x64/Release) -# set(Ice_LIBRARY ${ICE_LIBRARY} PARENT_SCOPE) -elseif(APPLE) -set(Ice_INCLUDE_DIRS ${Ice_HOME}/cpp/include ${Ice_HOME}/cpp/include/generated) -set(Ice_LIBRARY ${Ice_HOME}/cpp/lib/libIce.dylib) -# find_library(Ice_LIBRARY NAMES Ice.dylib HINTS ${Ice_HOME}/cpp/lib/) -# set(Ice_LIBRARY ${ICE_LIBRARY} PARENT_SCOPE) -else() -set(Ice_INCLUDE_DIRS ${Ice_HOME}/cpp/include ${Ice_HOME}/cpp/include/generated) -set(Ice_LIBRARY ${Ice_HOME}/cpp/lib/libIce.so) -endif() - -add_library(Ice::Ice SHARED IMPORTED) -set_target_properties(Ice::Ice PROPERTIES IMPORTED_IMPLIB ${Ice_LIBRARY}) -set_target_properties(Ice::Ice PROPERTIES - IMPORTED_LOCATION ${Ice_LIBRARY} - INTERFACE_INCLUDE_DIRECTORIES "${Ice_INCLUDE_DIRS}" -) - -# Function to generate C++ source files from Slice (.ice) files for a target using slice2cpp -# The target must have the Slice files in its sources -# The generated files are added to the target sources -# Usage: -# add_executable(a_target source1.cpp source2.ice source3.ice) -# slice2cpp_generate(a_target) -function(slice2cpp_generate TARGET) - - # Get the list of source files for the target - get_target_property(sources ${TARGET} SOURCES) - - # Create a directory to store the generated files - set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/generated/${TARGET}) - make_directory(${output_dir}) - - # Add the generated headers files to the target include directories - target_include_directories(${TARGET} PRIVATE ${output_dir}) - - # Process each Slice (.ice) file in the source list - # 1. Run the slice2cpp command to generate the header and source files - # 2. Add the generated files to the target sources - foreach(file IN LISTS sources) - if(file MATCHES "\\.ice$") - - get_filename_component(slice_file_name ${file} NAME_WE) - get_filename_component(slice_file_path ${file} ABSOLUTE) - set(output_files ${output_dir}/${slice_file_name}.h ${output_dir}/${slice_file_name}.cpp) - - add_custom_command( - OUTPUT ${output_files} - COMMAND ${Ice_SLICE2CPP_EXECUTABLE} -I${Ice_SLICE_DIR} ${slice_file_path} --output-dir ${output_dir} - DEPENDS ${slice_file_path} - COMMENT "${Ice_SLICE2CPP_EXECUTABLE} ${file} -> ${slice_file_name}.h ${slice_file_name}.cpp" - ) - - target_sources(${TARGET} PRIVATE ${output_files}) - - endif() - endforeach() - -endfunction() +find_package(Ice REQUIRED CONFIG COMPONENTS Glacier2)