diff --git a/CMakeLists.txt b/CMakeLists.txt index 770b4a9..68decbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,84 @@ cmake_minimum_required(VERSION 3.10) project(jay - VERSION 0.0.1 - LANGUAGES CXX + VERSION 0.0.1 + LANGUAGES CXX ) +# Build type options +option(JAY_ENABLE_ASAN "Enable Address Sanitizer" OFF) +option(JAY_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF) +option(JAY_ENABLE_TSAN "Enable Thread Sanitizer" OFF) +option(JAY_ENABLE_STRICT "Enable strict compiler warnings" OFF) +option(JAY_ENABLE_LTO "Enable Link Time Optimization" OFF) + +# Set default build type if not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build (Debug/Release)" FORCE) +endif() + +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS "Compiler: ${CMAKE_CXX_COMPILER_ID}") + set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_compile_options( + -Wall + -Wextra + -Wpedantic + ) + + if(JAY_ENABLE_STRICT) + add_compile_options( + -Werror + -Wconversion + -Wnon-virtual-dtor + -Wold-style-cast + -Wcast-align + -Wunused + -Woverloaded-virtual + -Wsign-conversion + -Wnull-dereference + ) + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_compile_options(-O0 -g3 -ggdb) + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Release") + add_compile_options(-O3 -DNDEBUG) + endif() + + if(JAY_ENABLE_ASAN) + add_compile_options(-fsanitize=address -fno-omit-frame-pointer) + add_link_options(-fsanitize=address) + endif() + + if(JAY_ENABLE_UBSAN) + add_compile_options(-fsanitize=undefined) + add_link_options(-fsanitize=undefined) + endif() + + if(JAY_ENABLE_TSAN) + add_compile_options(-fsanitize=thread) + add_link_options(-fsanitize=thread) + endif() +endif() + +# Link Time Optimization +if(JAY_ENABLE_LTO) + include(CheckIPOSupported) + check_ipo_supported(RESULT supported OUTPUT error) + if(supported) + message(STATUS "IPO / LTO enabled") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(STATUS "IPO / LTO not supported: <${error}>") + endif() +endif() + cmake_policy(SET CMP0076 NEW) find_package(PkgConfig REQUIRED) @@ -18,20 +90,4 @@ pkg_check_modules(UUID REQUIRED uuid) set(EXEC_NAME "jay") -add_executable(${EXEC_NAME} main.cpp jay.cpp) - -add_subdirectory(component) -add_subdirectory(connection) -add_subdirectory(module) -add_subdirectory(shared) - -target_include_directories(${EXEC_NAME} PRIVATE ${GLOOX_INCLUDE_DIRS}) -target_include_directories(${EXEC_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(${EXEC_NAME} PRIVATE ${UUID_INCLUDE_DIRS}) -target_link_libraries(${EXEC_NAME} PRIVATE - ${GLOOX_LIBRARIES} - yaml-cpp - ${UUID_LIBRARIES} -) - -install(TARGETS ${EXEC_NAME} RUNTIME DESTINATION bin) +add_subdirectory(src) \ No newline at end of file diff --git a/component/CMakeLists.txt b/component/CMakeLists.txt deleted file mode 100644 index 5089020..0000000 --- a/component/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(SOURCES - config.cpp - actor.cpp - router.cpp - core.cpp - loop.cpp -) - -set(HEADERS - config.h - actor.h - router.h - core.h - loop.h -) - -target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt deleted file mode 100644 index 0224a26..0000000 --- a/module/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(SOURCES - module.cpp - actor.cpp - publish.cpp -) - -set(HEADERS - module.h - actor.h - publish.h -) - -target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt deleted file mode 100644 index e590cf4..0000000 --- a/shared/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(SOURCES - logger.cpp - loggable.cpp - utils.cpp -) - -set(HEADERS - logger.h - loggable.h - definitions.h - result.h - utils.h -) - -target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..9dc4d80 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,28 @@ +set(SOURCES + main.cpp + jay.cpp +) + +set(HEADERS + jay.h +) + +add_executable(${EXEC_NAME} main.cpp jay.cpp) + +add_subdirectory(component) +add_subdirectory(connection) +add_subdirectory(module) +add_subdirectory(shared) + +target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) + +target_include_directories(${EXEC_NAME} PRIVATE ${GLOOX_INCLUDE_DIRS}) +target_include_directories(${EXEC_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${EXEC_NAME} PRIVATE ${UUID_INCLUDE_DIRS}) +target_link_libraries(${EXEC_NAME} PRIVATE + ${GLOOX_LIBRARIES} + yaml-cpp + ${UUID_LIBRARIES} +) + +install(TARGETS ${EXEC_NAME} RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/src/component/CMakeLists.txt b/src/component/CMakeLists.txt new file mode 100644 index 0000000..dc65e35 --- /dev/null +++ b/src/component/CMakeLists.txt @@ -0,0 +1,17 @@ +set(SOURCES + config.cpp + actor.cpp + router.cpp + core.cpp + loop.cpp +) + +set(HEADERS + config.h + actor.h + router.h + core.h + loop.h +) + +target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) diff --git a/component/actor.cpp b/src/component/actor.cpp similarity index 72% rename from component/actor.cpp rename to src/component/actor.cpp index dd98794..e1ea7b3 100644 --- a/component/actor.cpp +++ b/src/component/actor.cpp @@ -3,9 +3,9 @@ #include "actor.h" -Actor::Actor(const std::string& jid, const std::string& group) : - jid(jid), - group(group) +Actor::Actor(const std::string& _jid, const std::string& _group) : + jid(_jid), + group(_group) {} void Actor::setGroup(const std::string& newGroup) { diff --git a/component/actor.h b/src/component/actor.h similarity index 100% rename from component/actor.h rename to src/component/actor.h diff --git a/component/config.cpp b/src/component/config.cpp similarity index 100% rename from component/config.cpp rename to src/component/config.cpp diff --git a/component/config.h b/src/component/config.h similarity index 100% rename from component/config.h rename to src/component/config.h diff --git a/component/core.cpp b/src/component/core.cpp similarity index 95% rename from component/core.cpp rename to src/component/core.cpp index e65ca51..b420989 100644 --- a/component/core.cpp +++ b/src/component/core.cpp @@ -70,6 +70,6 @@ void Core::initializeActors() { } void Core::initializeResponses() { - for (const std::pair& pair : config.getResponses()) + for (const std::pair& pair : config.getResponses()) router.setResponses(pair.first, pair.second); } diff --git a/component/core.h b/src/component/core.h similarity index 100% rename from component/core.h rename to src/component/core.h diff --git a/component/loop.cpp b/src/component/loop.cpp similarity index 94% rename from component/loop.cpp rename to src/component/loop.cpp index ac7e69c..5531548 100644 --- a/component/loop.cpp +++ b/src/component/loop.cpp @@ -5,9 +5,12 @@ #include #include -#include -#include + +#include #include +#include + +#include "shared/definitions.h" Loop::Loop(const Shared::Logger& logger): Shared::Loggable(logger, {"Loop"}), @@ -19,8 +22,9 @@ Loop::Loop(const Shared::Logger& logger): running(false) { if (pipe(wakePipe) < 0) { - fatal(std::string("pipe: ") + strerror(errno)); - std::exit(1); + std::string message(strerror(errno)); + fatal("could not create Loop: " + message); + throw std::runtime_error(message); } fcntl(wakePipe[0], F_SETFL, O_NONBLOCK); @@ -203,6 +207,9 @@ void Loop::unregisterInstance(Loop* loop) { } void Loop::signalHandler(int signum) { + UNUSED(signum); + + std::lock_guard lock(instanceMutex); for (Loop* loop : instances) loop->stop(); } diff --git a/component/loop.h b/src/component/loop.h similarity index 95% rename from component/loop.h rename to src/component/loop.h index fbe2382..5bd1f5d 100644 --- a/component/loop.h +++ b/src/component/loop.h @@ -19,7 +19,7 @@ public: typedef std::function Callback; typedef std::map Handlers; - Loop(const Shared::Logger& logger); + explicit Loop(const Shared::Logger& logger); ~Loop(); void run(); @@ -35,7 +35,6 @@ private: void syncHandlers(); private: - int wakePipe[2]; Handlers handlers; Handlers handlersToAdd; diff --git a/component/router.cpp b/src/component/router.cpp similarity index 100% rename from component/router.cpp rename to src/component/router.cpp diff --git a/component/router.h b/src/component/router.h similarity index 100% rename from component/router.h rename to src/component/router.h diff --git a/connection/CMakeLists.txt b/src/connection/CMakeLists.txt similarity index 63% rename from connection/CMakeLists.txt rename to src/connection/CMakeLists.txt index 28a7488..f17b98a 100644 --- a/connection/CMakeLists.txt +++ b/src/connection/CMakeLists.txt @@ -1,9 +1,9 @@ set(SOURCES - connection.cpp + connection.cpp ) set(HEADERS - connection.h + connection.h ) target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) diff --git a/connection/connection.cpp b/src/connection/connection.cpp similarity index 98% rename from connection/connection.cpp rename to src/connection/connection.cpp index c9f0e3e..4528535 100644 --- a/connection/connection.cpp +++ b/src/connection/connection.cpp @@ -70,7 +70,7 @@ int Connection::connect() { } void Connection::disconnect() { - if (state != connecting || state != connected) + if (state != connecting && state != connected) return; gloox->disconnect(); @@ -125,6 +125,8 @@ std::string Connection::errorTypeToString(gloox::StanzaErrorType err) { } void Connection::handleMessage(const gloox::Message& message, gloox::MessageSession* session) { + UNUSED(session); + if (message.subtype() != gloox::Message::Chat) return; @@ -138,6 +140,9 @@ void Connection::handleMessage(const gloox::Message& message, gloox::MessageSess } void Connection::handleItemPublication(const std::string& id, const gloox::JID& service, const std::string& node, const gloox::PubSub::ItemList& itemList, const gloox::Error* err) { + UNUSED(itemList); + UNUSED(err); + std::string srv(node + "@" + service.full()); if (err) { diff --git a/connection/connection.h b/src/connection/connection.h similarity index 100% rename from connection/connection.h rename to src/connection/connection.h diff --git a/jay.cpp b/src/jay.cpp similarity index 100% rename from jay.cpp rename to src/jay.cpp diff --git a/jay.h b/src/jay.h similarity index 100% rename from jay.h rename to src/jay.h diff --git a/main.cpp b/src/main.cpp similarity index 85% rename from main.cpp rename to src/main.cpp index a7d92ec..e95b5ba 100644 --- a/main.cpp +++ b/src/main.cpp @@ -4,13 +4,11 @@ #include "jay.h" #include -#include #include std::string readEnv(const std::string& key, const std::string& defaultValue = "") { - const char* val = std::getenv(key.data()); - if (val) - return std::string(val); + if (const char* val = std::getenv(key.data())) + return {val}; return defaultValue; } diff --git a/src/module/CMakeLists.txt b/src/module/CMakeLists.txt new file mode 100644 index 0000000..7f96195 --- /dev/null +++ b/src/module/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SOURCES + module.cpp + actor.cpp + publish.cpp +) + +set(HEADERS + module.h + actor.h + publish.h +) + +target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) diff --git a/module/actor.cpp b/src/module/actor.cpp similarity index 100% rename from module/actor.cpp rename to src/module/actor.cpp diff --git a/module/actor.h b/src/module/actor.h similarity index 100% rename from module/actor.h rename to src/module/actor.h diff --git a/module/module.cpp b/src/module/module.cpp similarity index 100% rename from module/module.cpp rename to src/module/module.cpp diff --git a/module/module.h b/src/module/module.h similarity index 100% rename from module/module.h rename to src/module/module.h diff --git a/module/publish.cpp b/src/module/publish.cpp similarity index 100% rename from module/publish.cpp rename to src/module/publish.cpp diff --git a/module/publish.h b/src/module/publish.h similarity index 100% rename from module/publish.h rename to src/module/publish.h diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt new file mode 100644 index 0000000..303a42d --- /dev/null +++ b/src/shared/CMakeLists.txt @@ -0,0 +1,15 @@ +set(SOURCES + logger.cpp + loggable.cpp + utils.cpp +) + +set(HEADERS + logger.h + loggable.h + definitions.h + result.h + utils.h +) + +target_sources(${EXEC_NAME} PRIVATE ${SOURCES}) \ No newline at end of file diff --git a/shared/definitions.h b/src/shared/definitions.h similarity index 94% rename from shared/definitions.h rename to src/shared/definitions.h index 0196cf3..c612244 100644 --- a/shared/definitions.h +++ b/src/shared/definitions.h @@ -7,6 +7,8 @@ #include #include +#define UNUSED(x) (void)(x) + namespace Shared { typedef std::vector Strings; typedef std::map Permissions; diff --git a/shared/loggable.cpp b/src/shared/loggable.cpp similarity index 86% rename from shared/loggable.cpp rename to src/shared/loggable.cpp index 7828e28..68d4ad6 100644 --- a/shared/loggable.cpp +++ b/src/shared/loggable.cpp @@ -3,9 +3,9 @@ #include "loggable.h" -Shared::Loggable::Loggable(const Logger& logger, const std::vector& domain) : - logger(logger), - domain(domain) +Shared::Loggable::Loggable(const Logger& _logger, const std::vector& _domain) : + logger(_logger), + domain(_domain) {} void Shared::Loggable::trace(const std::string& message) const { diff --git a/shared/loggable.h b/src/shared/loggable.h similarity index 100% rename from shared/loggable.h rename to src/shared/loggable.h diff --git a/shared/logger.cpp b/src/shared/logger.cpp similarity index 99% rename from shared/logger.cpp rename to src/shared/logger.cpp index fb8ddab..9a713cc 100644 --- a/shared/logger.cpp +++ b/src/shared/logger.cpp @@ -120,7 +120,7 @@ Shared::Logger::Logger(Level level): level(level) {} -Shared::Logger::~Logger() {} +Shared::Logger::~Logger() = default; void Shared::Logger::handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message) { writeTimestamp(); diff --git a/shared/logger.h b/src/shared/logger.h similarity index 91% rename from shared/logger.h rename to src/shared/logger.h index f1f08e5..fa4ea06 100644 --- a/shared/logger.h +++ b/src/shared/logger.h @@ -22,8 +22,8 @@ public: }; public: - Logger(Level level = info); - ~Logger(); + explicit Logger(Level level = info); + ~Logger() override; void handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message) override; diff --git a/shared/result.h b/src/shared/result.h similarity index 100% rename from shared/result.h rename to src/shared/result.h diff --git a/shared/utils.cpp b/src/shared/utils.cpp similarity index 100% rename from shared/utils.cpp rename to src/shared/utils.cpp diff --git a/shared/utils.h b/src/shared/utils.h similarity index 100% rename from shared/utils.h rename to src/shared/utils.h