diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8cf8b5e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "googletest"] + path = googletest + url = https://github.com/google/googletest.git diff --git a/CMakeLists.txt b/CMakeLists.txt index ef461cf..9e8292f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,92 +21,63 @@ # SOFTWARE. ### -# config -### -cmake_minimum_required(VERSION 2.8.7) -set(CMAKE_MACOSX_RPATH 1) -include(${CMAKE_ROOT}/Modules/ExternalProject.cmake) - - -### -# verbose make +# project ### -# set(CMAKE_VERBOSE_MAKEFILE TRUE) - +# see cmake --help-policy CMP +cmake_policy(SET CMP0048 NEW) +cmake_policy(SET CMP0077 NEW) +project(tacopie + LANGUAGES CXX + VERSION 3.2.0 + DESCRIPTION "C++ TCP Library" + HOMEPAGE_URL "") ### -# project +# config ### -set(PROJECT tacopie) -project(${PROJECT} CXX) +cmake_minimum_required(VERSION 3.13) +option(VERBOSE_MAKEFILE "Generate verbose output from Makefile builds" OFF) +set(CMAKE_VERBOSE_MAKEFILE ${VERBOSE_MAKEFILE}) +set(CMAKE_MACOSX_RPATH 1) +set(CMAKE_CXX_STANDARD 11) +set(EXPORT_TARGET_NAME ${PROJECT_NAME} CACHE STRING "Name of the exported CMake target used in install(EXPORT)") ### # compilation options ### -IF (MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /O2 /bigobj") +if (MSVC) + add_compile_options(/W3 /O2 /bigobj) # was causing conflics with gtest build string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) - - IF ("${MSVC_RUNTIME_LIBRARY_CONFIG}" STREQUAL "") + # CMake 3.15 has support for automatically configuring MSVC runtime + # through target property MSVC_RUNTIME_LIBRARY. Since I'm not + # planning on supporting old CMake versions I will most likely bump + # cmake_minimum_required to 3.15 at some point. + if ("${MSVC_RUNTIME_LIBRARY_CONFIG}" STREQUAL "") set(MSVC_RUNTIME_LIBRARY_CONFIG "/MT") - ENDIF() + endif () foreach (flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE) - IF ("${MSVC_RUNTIME_LIBRARY_CONFIG}" STREQUAL "/MT") + if ("${MSVC_RUNTIME_LIBRARY_CONFIG}" STREQUAL "/MT") string(REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - ELSEIF ("${MSVC_RUNTIME_LIBRARY_CONFIG}" STREQUAL "/MD") + elseif ("${MSVC_RUNTIME_LIBRARY_CONFIG}" STREQUAL "/MD") string(REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}") - ELSE () + else () string(REPLACE "/MD" "${MSVC_RUNTIME_LIBRARY_CONFIG}" ${flag_var} "${${flag_var}}") string(REPLACE "/MT" "${MSVC_RUNTIME_LIBRARY_CONFIG}" ${flag_var} "${${flag_var}}") - ENDIF() + endif() endforeach() add_definitions(-D_UNICODE) add_definitions(-DUNICODE) add_definitions(-DWIN32_LEAN_AND_MEAN) -ELSE () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -W -Wall -Wextra -O3") -ENDIF (MSVC) - - -### -# variables -### -set(DEPS_INCLUDES ${PROJECT_SOURCE_DIR}/deps/include) -set(DEPS_LIBRARIES ${PROJECT_SOURCE_DIR}/deps/lib) -set(TACOPIE_INCLUDES ${PROJECT_SOURCE_DIR}/includes) - - -### -# includes -### -include_directories(${TACOPIE_INCLUDES}) - -### -# sources -### -set(SRC_DIRS "sources" "sources/network" "sources/network/common" "sources/utils" "includes/tacopie" "includes/tacopie/network" "includes/tacopie/utils") - -IF (WIN32) - set(SRC_DIRS ${SRC_DIRS} "sources/network/windows") -ELSE () - set(SRC_DIRS ${SRC_DIRS} "sources/network/unix") -ENDIF (WIN32) - -foreach(dir ${SRC_DIRS}) - # get directory sources and headers - file(GLOB s_${dir} "${dir}/*.cpp") - file(GLOB h_${dir} "${dir}/*.hpp") - file(GLOB i_${dir} "${dir}/*.ipp") - - # set sources - set(SOURCES ${SOURCES} ${s_${dir}} ${h_${dir}} ${i_${dir}}) -endforeach() +else () + add_compile_options(-W -Wall -Wextra -O3) +endif () +include(sources.cmake) ### # outputs @@ -116,78 +87,83 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_PKGCONFIG_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig) - ### # pkg-config ### configure_file("tacopie.pc.in" "${CMAKE_PKGCONFIG_OUTPUT_DIRECTORY}/tacopie.pc" @ONLY) - ### # executable ### -add_library(${PROJECT} ${SOURCES}) -set_property(TARGET ${PROJECT} PROPERTY POSITION_INDEPENDENT_CODE ON) +add_library(${PROJECT_NAME} SHARED ${tacopie_sources}) +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $) -IF (WIN32) - set_target_properties(${PROJECT} - PROPERTIES COMPILE_PDB_NAME ${PROJECT} - COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -ENDIF (WIN32) +if (WIN32) + set_target_properties(${PROJECT_NAME} PROPERTIES + COMPILE_PDB_NAME ${PROJECT_NAME} + COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +endif () -IF (WIN32) - target_link_libraries(${PROJECT} ws2_32) -ELSE () - target_link_libraries(${PROJECT} pthread) -ENDIF (WIN32) +set_target_properties(${PROJECT_NAME} PROPERTIES + SOVERSION ${PROJECT_VERSION} + RESOURCE ${CMAKE_PKGCONFIG_OUTPUT_DIRECTORY}/tacopie.pc) + +find_package(Threads REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE Threads::Threads) # __TACOPIE_LOGGING_ENABLED -IF (LOGGING_ENABLED) - set_property(TARGET ${PROJECT} APPEND_STRING PROPERTY COMPILE_DEFINITIONS " __TACOPIE_LOGGING_ENABLED=${LOGGING_ENABLED}") -ENDIF (LOGGING_ENABLED) +option(LOGGING_ENABLED "Enable logging" OFF) +if (LOGGING_ENABLED) + target_compile_definitions(${PROJECT_NAME} PRIVATE __TACOPIE_LOGGING_ENABLED=${LOGGING_ENABLED}) +endif () # __TACOPIE_CONNECTION_QUEUE_SIZE -IF (CONNECTION_QUEUE_SIZE) - set_property(TARGET ${PROJECT} APPEND_STRING PROPERTY COMPILE_DEFINITIONS " __TACOPIE_CONNECTION_QUEUE_SIZE=${CONNECTION_QUEUE_SIZE}") -ENDIF (CONNECTION_QUEUE_SIZE) +set(CONNECTION_QUEUE_SIZE "" CACHE STRING "Custom connection queue size") +if (CONNECTION_QUEUE_SIZE MATCHES "^[0-9]+") + target_compile_definitions(${PROJECT_NAME} PRIVATE __TACOPIE_CONNECTION_QUEUE_SIZE=${CONNECTION_QUEUE_SIZE}) +endif () #__TACOPIE_IO_SERVICE_NB_WORKERS -IF (IO_SERVICE_NB_WORKERS) - set_property(TARGET ${PROJECT} APPEND_STRING PROPERTY COMPILE_DEFINITIONS " __TACOPIE_IO_SERVICE_NB_WORKERS=${IO_SERVICE_NB_WORKERS}") -ENDIF(IO_SERVICE_NB_WORKERS) +set(IO_SERVICE_NB_WORKERS "" CACHE STRING "Number of service workers") +if (IO_SERVICE_NB_WORKERS MATCHES "^[1-9]+") + target_compile_definitions(${PROJECT_NAME} PRIVATE __TACOPIE_IO_SERVICE_NB_WORKERS=${IO_SERVICE_NB_WORKERS}) +endif () #__TACOPIE_TIMEOUT -IF (SELECT_TIMEOUT) - set_property(TARGET ${PROJECT} APPEND_STRING PROPERTY COMPILE_DEFINITIONS " __TACOPIE_TIMEOUT=${SELECT_TIMEOUT}") -ENDIF(SELECT_TIMEOUT) - +set(SELECT_TIMEOUT "" CACHE STRING "Select timeout") +if (SELECT_TIMEOUT MATCHES "^[0-9]+") + target_compile_definitions(${PROJECT_NAME} PRIVATE __TACOPIE_TIMEOUT=${SELECT_TIMEOUT}) +endif () ### # install ### -# ensure lib and bin directories exist -install(CODE "FILE(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})") -install(CODE "FILE(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})") -# install tacopie -install(DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ DESTINATION lib USE_SOURCE_PERMISSIONS) -install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ DESTINATION bin USE_SOURCE_PERMISSIONS) -install(DIRECTORY ${TACOPIE_INCLUDES}/ DESTINATION include USE_SOURCE_PERMISSIONS) - +# NOTE: this fails if more directories are added to ${tacopie_includes} +include(GNUInstallDirs) +install(DIRECTORY ${tacopie_includes}/ DESTINATION include USE_SOURCE_PERMISSIONS) +install(TARGETS ${PROJECT_NAME} EXPORT ${EXPORT_TARGET_NAME} + LIBRARY + RESOURCE DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) ### # examples ### -IF (BUILD_EXAMPLES) +option(BUILD_EXAMPLES "Build examples" OFF) +if (BUILD_EXAMPLES) add_subdirectory(examples) -ENDIF(BUILD_EXAMPLES) +endif () ### # tests ### -IF (BUILD_TESTS) +option(BUILD_TESTS "Build tests" OFF) +if (BUILD_TESTS) + if (NOT TARGET gtest) + set(INSTALL_GTEST OFF) + add_subdirectory(googletest) + endif () add_subdirectory(tests) - ExternalProject_Add("googletest" - GIT_REPOSITORY "https://github.com/google/googletest.git" - CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/deps") -ENDIF(BUILD_TESTS) +endif () diff --git a/googletest b/googletest new file mode 160000 index 0000000..703bd9c --- /dev/null +++ b/googletest @@ -0,0 +1 @@ +Subproject commit 703bd9caab50b139428cea1aaff9974ebee5742e diff --git a/sources.cmake b/sources.cmake new file mode 100644 index 0000000..85620c1 --- /dev/null +++ b/sources.cmake @@ -0,0 +1,26 @@ +### +# sources +### +set(tacopie_sources + sources/network/common/tcp_socket.cpp + sources/network/io_service.cpp + sources/network/tcp_client.cpp + sources/network/tcp_server.cpp + sources/utils/error.cpp + sources/utils/logger.cpp + sources/utils/thread_pool.cpp) + +if (MSVC) + list(APPEND tacopie_sources + sources/network/windows/windows_self_pipe.cpp + sources/network/windows/windows_tcp_socket.cpp) +else() + list(APPEND tacopie_sources + sources/network/unix/unix_self_pipe.cpp + sources/network/unix/unix_tcp_socket.cpp) +endif() + +### +# includes +### +set(tacopie_includes ${PROJECT_SOURCE_DIR}/includes) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b732b75..5bd0747 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,55 +20,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -### -# project -### -set(PROJECT tacopie_tests) -project(${PROJECT} CXX) - - -### -# compilation options -### -IF (NOT WIN32) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -ENDIF (NOT WIN32) - - -### -# includes -### -include_directories(${DEPS_INCLUDES} ${TACOPIE_INCLUDES}) - - -### -# libraries -### -link_directories(${DEPS_LIBRARIES}) - - ### # sources ### -set(SOURCES "") -set(DIRS "sources" "sources/spec" "sources/spec/**") -foreach(dir ${DIRS}) - # get directory sources - file(GLOB s_${dir} "${dir}/*.cpp") - # set sources - set(SOURCES ${SOURCES} ${s_${dir}}) -endforeach() - +set(tacopie_test_sources + sources/main.cpp) ### # executable ### -add_executable(${PROJECT} ${SOURCES}) - -target_link_libraries(${PROJECT} tacopie gtest) - -IF (WIN32) - target_link_libraries(${PROJECT} ws2_32) -ELSE () - target_link_libraries(${PROJECT} pthread) -ENDIF (WIN32) +add_executable(${PROJECT_NAME}_tests ${tacopie_test_sources}) +target_link_libraries(${PROJECT_NAME}_tests PRIVATE ${PROJECT_NAME} gtest) +add_test(NAME ${PROJECT_NAME}::tests COMMAND ${PROJECT_NAME}_tests)