emqx / qmqtt

MQTT client for Qt

Home Page:https://www.emqx.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Suggestion: add support for Qt6 Android

RoachLin opened this issue · comments

In my test project, I use add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/qmqtt-1.0.3) to make my project succeed to run and all function test good.
But when I change the compiler to Qt6 Android, it can also compile, but will crash in splash screen.
The error message says:

E AndroidRuntime: FATAL EXCEPTION: qtMainLoopThread
E AndroidRuntime: Process: org.emqx.qmqtt.test, PID: 20998
E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "qmqtt.so" not found
E AndroidRuntime: 	at java.lang.Runtime.load0(Runtime.java:938)
E AndroidRuntime: 	at java.lang.System.load(System.java:1632)
E AndroidRuntime: 	at org.qtproject.qt.android.QtNative$4.run(QtNative.java:305)
E AndroidRuntime: 	at org.qtproject.qt.android.QtThread$2.run(QtThread.java:51)
E AndroidRuntime: 	at org.qtproject.qt.android.QtThread$1.run(QtThread.java:25)
E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:929)

But "qmqtt.so" does exist in build folder "\build-untitled3-Qt_6_5_1_Clang_arm64_v8a-Debug\qmqtt-1.0.3"

Now I just simply add all source code(*.h *.cpp) to my CMakeLists.txt, and it can run both on Windows and Android.
I check your CMakeLists.txt, it doesn't contain any code related to Android platform. I think this may be the key reason.
If you could add support for Qt6 Android, I will be very appreciated.

Hi RoachLin,

this library is pretty much in a maintenance-only status. So we are not very keen to add new features since this often causes new dependencies. In this case this seems something we never supported in the past, not even on Qt 5?

Fine, after today's struggle, now I can make it run both on Windows and Android.
Here is the source code:
untitled5.zip
Maybe someone will need it, or for this library's further development in the future......?

For Windows, use add_subdirectory in CMakeLists.txt.
For Android, just simply import the source code, add_subdirectory will make the app crash.
If Windows use the way of importing the source code, it can't compile.

Some variables related to mqtt network should be modified, like "192.168.xxx.xxx".
And I'm sorry for that some codes and UI are written in Chinese, since I'm a Chinese......

If you have no problem, just close this issue.
I'm off work. Have a nice day!

@ejvr I am bit unsure on this. Would you like to have a look?

With PR #254 we have added some Qt6 support. Please re-evaluate which of your changes are still needed.

@ejvr Would be fine if also you could help us here.

dlopen failed: library "qmqtt.so" not found: maybe the files "qmqtt.so" can be found, but one of its depedencies cannot be found.

I'm not sure this is possible with Android (it's a long time ago for me), but I think you can open a linux shell on an android device using the Android sdk. Here is an example. Inside the shell you execute the command ldd qmqtt.so. This will give you a list of shared libraries needed by "qmqtt.so".

The output should like like this (but with more dependencies):

libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)

On the left side of the => is the depedency from the shared library you're scanning. In the right side is the path to the shared library itself on your system. The there is not path but not found instead, it means that one of the depedencies cannot be found.

My guess is that on your android system one or more shared libraries cannot be found. Maybe the don't exist or they are in the wrong directory.

For mwallnoefer:
I use the latest code, and it does support Qt6 perfectly.

For ejvr:
I simply add these codes in my CMakeLists.txt, and it works on Windows, but failed on Android:

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/qmqtt)
target_link_libraries(${PROJECT_NAME} PRIVATE qmqtt)

I check the Android app's libs using LibChecker, and don't found "qmqtt.so". Maybe something go wrong in qmqtt's CMakeLists.txt, result in not compiling "qmqtt.so".

However, I figure out how to make it work on Android about a month ago. Here is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.24)

project(
  untitle5
  VERSION 0.1
  LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Core Network)

set(PROJECT_SOURCES main.cpp MainWindow.cpp MainWindow.h MainWindow.ui)

if(ANDROID)
  file(GLOB EMQX_QMQTT ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt/src/mqtt/*.h
       ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt/src/mqtt/*.cpp)
  set(PROJECT_SOURCES ${PROJECT_SOURCES} ${EMQX_QMQTT})
  include_directories(${CMAKE_CURRENT_SOURCE_DIR}/qmqtt/src/mqtt)
  source_group(emqx_qmqtt FILES ${EMQX_QMQTT})
endif()

qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION ${PROJECT_SOURCES})
set_property(
  TARGET ${PROJECT_NAME}
  APPEND
  PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android)

if(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC OR ${CMAKE_CXX_COMPILER_ID} STREQUAL
                                             GNU)
  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/qmqtt)
  target_link_libraries(${PROJECT_NAME} PRIVATE qmqtt)
endif()

target_link_libraries(
  ${PROJECT_NAME}
  PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Core
          Qt${QT_VERSION_MAJOR}::Network)

set_target_properties(
  ${PROJECT_NAME}
  PROPERTIES WIN32_EXECUTABLE TRUE
             QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android
             QT_ANDROID_MIN_SDK_VERSION 24 # Android 7.0
             QT_ANDROID_TARGET_SDK_VERSION 34 # Android 14
             QT_ANDROID_BUILD_ALL_ABIS ON
             QT_ANDROID_ABIS "arm64-v8a"
             # arm64-v8a
             # armeabi-v7a;arm64-v8a
             # armeabi-v7a;arm64-v8a;x86;x86_64
)

include(GNUInstallDirs)
install(
  TARGETS ${PROJECT_NAME}
  BUNDLE DESTINATION .
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

if(QT_VERSION_MAJOR EQUAL 6)
  qt_finalize_executable(${PROJECT_NAME})
endif()

Here is the source code:
untitled5.zip

Now I use this way as a temporary solution. And I will not spend much time on it, since I turn to qtmqtt. Thank you for everyone participating on this issue.