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

KDMqtt #45

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
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
20 changes: 18 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
os:
- ubuntu-24.04
- ubuntu-22.04
- ubuntu-20.04
#- ubuntu-20.04 -> disabled during introduction of KDMqtt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still the case, that it doesn't work on 20.04?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I see it, mosquitto v1.6.9 is the latest version available in Ubuntu 20.04:
https://launchpad.net/ubuntu/focal/+package/libmosquitto-dev
Without additional changes to KDMqtt the project won't compile on 20.04

I'd suggest to disable KDMqtt build via KDUTILS_BUILD_MQTT_SUPPORT for os: ubuntu 20.04, document this in the README and re-enable the os in build.yml.

What do you think?

- windows-2022
- macos-13
- macos-14
Expand All @@ -26,6 +26,9 @@ jobs:
- ON
- OFF

env:
MOSQUITTO_VERSION: 2.0.20

steps:
- name: Checkout sources
uses: actions/checkout@v4
Expand All @@ -43,7 +46,20 @@ jobs:
sudo apt update -qq
sudo apt install -y libxkbcommon-dev libxcb-xkb-dev \
libxkbcommon-x11-dev wayland-scanner++ wayland-protocols \
libwayland-dev xvfb ninja-build
libwayland-dev xvfb ninja-build \
libmosquittopp-dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC we're not using the C++ mosquitto wrapper but rather the C API directly. In this case, this should be libmosquitto-dev

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, we are using the C API, therefore libmosquitto-dev is correct.


- name: Download mosquitto (MacOS)
if: runner.os == 'macOS'
run: |
brew install mosquitto

- name: Download mosquitto (Windows)
if: runner.os == 'Windows'
run: |
curl --no-progress-meter --location --remote-name `
https://mosquitto.org/files/binary/win64/mosquitto-$env:MOSQUITTO_VERSION-install-windows-x64.exe
& .\mosquitto-$env:MOSQUITTO_VERSION-install-windows-x64.exe /S

- name: Configure project
run: >
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ endif()
add_subdirectory(src/KDUtils)
add_subdirectory(src/KDFoundation)
add_subdirectory(src/KDGui)
add_subdirectory(src/KDMqtt)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make building KDMqtt optional behind an option. And this option should be by default OFF on Windows as currently, the example doesn't seem to work. Probably something's wrong with the fd notifiers? Dunno. We can create an issue to fix it.

Our current target is Linux anyway so for now it should be fine to have KDMqtt working on Linux only.

Some KDUTILS_BUILD_MQTT_SUPPORT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I forgot about the fd notifier issue on Windows.


if(KDUTILS_BUILD_EXAMPLES)
add_subdirectory(examples)
Expand Down
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ You get:
- Keyboard and mouse events
- GuiApplication

## KDMqtt

KDMqtt provides a cross-platform MQTT client solution, based on [mosquitto](https://mosquitto.org/).

You get a thin wrapper around libmosquitto that

* seamlessly integrates into KDFoundation's `CoreAppliation`
* comes with an API featuring properties and signals using [KDBindings](https://github.com/KDAB/KDBindings)

For now, we don't support building mosquitto from source so you need to have it installed on your machine.

You can find setup instructions and download links at

<https://mosquitto.org/download/>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also encourage the user to look at .github/workflows/build.yml

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea!

## KDUtils/KDUtils

This namespace is the namesake of the entire library, and contains the STL
Expand All @@ -52,7 +67,7 @@ You get:
On Linux:

```bash
sudo apt install libxkbcommon-dev libxcb-xkb-dev libxkbcommon-x11-dev wayland-scanner++ wayland-protocols libwayland-dev
sudo apt install libxkbcommon-dev libxcb-xkb-dev libxkbcommon-x11-dev wayland-scanner++ wayland-protocols libwayland-dev libmosquittopp-dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like in workflow file, that should be libmosquitto-dev right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Good you spotted this.

```

For debug builds with code coverage:
Expand Down
77 changes: 77 additions & 0 deletions cmake/FindMosquitto.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# This file is part of KDUtils.
#
# SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# Author: Marco Thaller <[email protected]>
#
# SPDX-License-Identifier: MIT
#
# Contact KDAB at <[email protected]> for commercial licensing options.
#

find_file(
MOSQUITTO_HEADER
NAMES mosquitto.h
PATHS /usr/include
/usr/local/include
/usr/local/opt/mosquitto/include
$ENV{PROGRAMFILES}/mosquitto/devel
$ENV{PROGRAMFILES\(X86\)}/mosquitto/devel
)

if(APPLE OR UNIX)
find_library(
MOSQUITTO_LIBRARY
NAMES mosquitto
PATHS /usr/lib /usr/local/lib /usr/local/opt/mosquitto/lib
)

if(MOSQUITTO_HEADER AND MOSQUITTO_LIBRARY)
set(Mosquitto_FOUND TRUE)
endif()
endif()

if(WIN32)
find_file(
MOSQUITTO_DLL
NAMES mosquitto.dll
PATHS $ENV{PROGRAMFILES}/mosquitto $ENV{PROGRAMFILES\(X86\)}/mosquitto
)

find_library(
MOSQUITTO_LIBRARY
NAMES mosquitto
PATHS $ENV{PROGRAMFILES}/mosquitto/devel $ENV{PROGRAMFILES\(X86\)}/mosquitto/devel
)

file(GLOB MOSQUITTO_RUNTIME_DLLS "$ENV{PROGRAMFILES}/mosquitto/*.dll" "$ENV{PROGRAMFILES\(X86\)}/mosquitto/*.dll")

if(MOSQUITTO_HEADER
AND MOSQUITTO_DLL
AND MOSQUITTO_LIBRARY
)
set(Mosquitto_FOUND TRUE)
endif()
endif()

if(Mosquitto_FOUND)
cmake_path(GET MOSQUITTO_HEADER PARENT_PATH MOSQUITTO_INCLUDE_DIRECTORY)

add_library(Mosquitto::Mosquitto SHARED IMPORTED)

if(APPLE OR UNIX)
set_target_properties(
Mosquitto::Mosquitto PROPERTIES IMPORTED_LOCATION "${MOSQUITTO_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES
"${MOSQUITTO_INCLUDE_DIRECTORY}"
)
endif()

if(WIN32)
set_target_properties(
Mosquitto::Mosquitto
PROPERTIES IMPORTED_IMPLIB "${MOSQUITTO_LIBRARY}"
IMPORTED_LOCATION "${MOSQUITTO_DLL}"
INTERFACE_INCLUDE_DIRECTORIES "${MOSQUITTO_INCLUDE_DIRECTORY}"
)
endif()

endif()
3 changes: 3 additions & 0 deletions cmake/dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,6 @@ if(NOT TARGET mio::mio)
)
fetchcontent_makeavailable(mio)
endif()

# mosquitto library
find_package(Mosquitto REQUIRED)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be dependent on the mosquitto build option

1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
#

add_subdirectory(gui_window)
add_subdirectory(mqtt_client)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be dependent on the mosquitto build option

34 changes: 34 additions & 0 deletions examples/mqtt_client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This file is part of KDUtils.
#
# SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# Author: Marco Thaller <[email protected]>
#
# SPDX-License-Identifier: MIT
#
# Contact KDAB at <[email protected]> for commercial licensing options.
#

project(mqtt_client_example LANGUAGES CXX)

add_executable(
${PROJECT_NAME}
mqtt_client.cpp
)

target_link_libraries(
${PROJECT_NAME} KDMqtt
)

if(WIN32)
# Deployment: On Windows, copy all DLLs from the mosquitto install directory next to the application binary so that they're found.
if(BUILD_INTEGRATION_MQTT AND MOSQUITTO_RUNTIME_DLLS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BUILD_INTEGRATION_MQTT doesn't seem to exist anymore so this condition is always false on Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be Mosquitto_FOUND, I'll fix this.

foreach(MOSQUITTO_RUNTIME_DLL ${MOSQUITTO_RUNTIME_DLLS})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${MOSQUITTO_RUNTIME_DLL}"
$<TARGET_FILE_DIR:${PROJECT_NAME}>
)
endforeach()
endif()
endif()
54 changes: 54 additions & 0 deletions examples/mqtt_client/mqtt_client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
This file is part of KDUtils.

SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Marco Thaller <[email protected]>

SPDX-License-Identifier: MIT

Contact KDAB at <[email protected]> for commercial licensing options.
*/
#include <KDFoundation/core_application.h>
#include <KDMqtt/mqtt.h>

using namespace KDFoundation;
using namespace KDMqtt;

int main()
{
const Url url("test.mosquitto.org");
const std::string topic = "mytopic";
const std::string payload = "Hello World!";

CoreApplication app;

MqttLib::instance().init();
MqttClient mqttClient("KDMqttClient", true, true);

auto onMqttConnectionStateChanged = [&](const MqttClient::ConnectionState &connectionState) {
if (connectionState == MqttClient::ConnectionState::CONNECTED) {
mqttClient.subscribe(topic.c_str());
}
};
std::ignore = mqttClient.connectionState.valueChanged().connect(onMqttConnectionStateChanged);

auto onMqttSubscriptionStateChanged = [&](const MqttClient::SubscriptionState &subscriptionState) {
if (subscriptionState == MqttClient::SubscriptionState::SUBSCRIBED) {
mqttClient.publish(nullptr, topic.c_str(), payload.length(), payload.c_str());
}
};
std::ignore = mqttClient.subscriptionState.valueChanged().connect(onMqttSubscriptionStateChanged);

auto onMqttMessageReceived = [&](const mosquitto_message *message) {
const auto timestamp = std::time(nullptr);
const auto timestring = std::string(std::asctime(std::localtime(&timestamp)));
const auto topic = std::string(message->topic);
const auto payload = std::string(static_cast<char *>(message->payload));
spdlog::info("Received MQTT message. Topic: {}. Payload: {}", topic, payload);
};
std::ignore = mqttClient.msgReceived.connect(onMqttMessageReceived);

mqttClient.connect(url);

app.exec();
}
90 changes: 90 additions & 0 deletions src/KDMqtt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# This file is part of KDUtils.
#
# SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# Author: Marco Thaller <[email protected]>
#
# SPDX-License-Identifier: MIT
#
# Contact KDAB at <[email protected]> for commercial licensing options.
#

set(SOURCES mqtt.cpp)

set(HEADERS mosquitto_wrapper.h mqtt.h)

add_library(
KDMqtt
${SOURCES} ${HEADERS}
)

add_library(
KDUtils::KDMqtt ALIAS KDMqtt
)

target_link_libraries(
KDMqtt
PUBLIC KDUtils::KDFoundation
PUBLIC Mosquitto::Mosquitto
)

target_include_directories(
KDMqtt
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes mosquitto_wrapper.h a public header. Shouldn't we rather make it an implementation detail and private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, keeping the header private makes perfect sense.

)

#
# Logging configuration
#
# Compile out some of the SPDLOG macros based on build type
target_compile_definitions(
KDMqtt PRIVATE SPDLOG_ACTIVE_LEVEL=$<IF:$<CONFIG:Debug>,SPDLOG_LEVEL_TRACE,SPDLOG_LEVEL_WARN>
)
target_link_libraries(
KDMqtt
PRIVATE spdlog::spdlog
)

generate_export_header(KDMqtt BASE_NAME kdmqtt)
configure_file(${CMAKE_CURRENT_BINARY_DIR}/kdmqtt_export.h ${CMAKE_BINARY_DIR}/include/KDMqtt/kdmqtt_export.h)
# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h ${CMAKE_BINARY_DIR}/include/KDMqtt/config.h)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a leftover.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll remove this.

install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/kdmqtt_export.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/KDMqtt
)
install(
FILES ${CMAKE_BINARY_DIR}/include/KDMqtt/config.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/KDMqtt
)
Comment on lines +54 to +57
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto, we don't have config.h in KDMqtt if I'm looking correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we don't have a config.h, this can be removed.


foreach(file ${HEADERS})
get_filename_component(dir ${file} DIRECTORY)
install(FILES ${file} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/KDMqtt/${dir})
endforeach()

set(project_config_in "${CMAKE_CURRENT_LIST_DIR}/cmake/KDMqttConfig.cmake.in")
set(project_config_out "${CMAKE_CURRENT_BINARY_DIR}/KDMqttConfig.cmake")

install(
TARGETS KDMqtt
EXPORT KDMqtt
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
EXPORT KDMqtt
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/KDMqtt
NAMESPACE KDUtils::
FILE KDMqttConfigTargets.cmake
)
include(CMakePackageConfigHelpers)
configure_file("${project_config_in}" "${project_config_out}" @ONLY)
install(
FILES "${project_config_out}"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/KDMqtt
)
install(
FILES ${HEADERS}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/KDMqtt
)
15 changes: 15 additions & 0 deletions src/KDMqtt/cmake/KDMqttConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is part of KDUtils.
#
# SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# Author: Marco Thaller <[email protected]>
#
# SPDX-License-Identifier: MIT
#
# Contact KDAB at <[email protected]> for commercial licensing options.
#

include(CMakeFindDependencyMacro)
find_dependency(KDFoundation)
find_dependency(mosquitto)

include("${CMAKE_CURRENT_LIST_DIR}/KDMqttConfigTargets.cmake")
16 changes: 16 additions & 0 deletions src/KDMqtt/kdmqtt_global.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
This file is part of KDUtils.

SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Marco Thaller <[email protected]>

SPDX-License-Identifier: MIT

Contact KDAB at <[email protected]> for commercial licensing options.
*/

#pragma once

#include <KDMqtt/kdmqtt_export.h>

#define KDMQTT_API KDMQTT_EXPORT
Loading
Loading