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

QXmpp for Android Guide #446

Open
timakas opened this issue Sep 5, 2022 · 11 comments
Open

QXmpp for Android Guide #446

timakas opened this issue Sep 5, 2022 · 11 comments

Comments

@timakas
Copy link

timakas commented Sep 5, 2022

Just wondering if there is a way to use QXmpp in Qt Creator for Android? I'm a bit new to Android development, I'm trying my hand at it in QT, so just wondering if you can offer a helpful guide on how to build the library so that Qt will allow me to use the code? I've set up all the required android dependencies in Qt, I've tried to use cmake to build it with Android NDK, but I'm getting the following errors:

CMake Error at /home/tim/Android/Sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android22-clang++:2:
Parse error. Expected "(", got unquoted argument with text "[".
Call Stack (most recent call first):
/usr/share/cmake-3.16/Modules/CMakeDetermineSystem.cmake:93 (include)
CMakeLists.txt:6 (project)

CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool.
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!

I've also tried to use ndk-build, but it doesn't seem to recognize Qt only c++.

I'm also a bit new to CMake. I've attached my CMakeLists.txt file if anyone can please point me in the right direction.

CMakeLists.txt

Appreciate any help! Thanks

@timakas
Copy link
Author

timakas commented Sep 10, 2022

I have managed to build the QXmpp library for Android according to Kaidan IM app build instructions. However, I'm struggling to link against the library in my CMakeLists.txt. I am getting the following error now:

/home/tim/Documents/myProjects/qxmpp_qt6/qxmpp_qt6/CMakeLists.txt:12: error: By not providing "FindQXmpp.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "QXmpp", but CMake did not find one. Could not find a package configuration file provided by "QXmpp" (requested version 1.5.0) with any of the following names: QXmppConfig.cmake qxmpp-config.cmake Add the installation prefix of "QXmpp" to CMAKE_PREFIX_PATH or set "QXmpp_DIR" to a directory containing one of the above files. If "QXmpp" provides a separate development package or SDK, be sure it has been installed.

Can someone please give me a guide on how to link against the library? I've installed my library in /usr/local/lib.

Below is my current CMakeLists.txt:


cmake_minimum_required(VERSION 3.16)

project(qxmpp_qt6 VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

link_directories(/usr/local/lib)

find_package(Qt6 6.2 COMPONENTS Quick Core Network Xml REQUIRED)
find_package(QXmpp 1.5.0 REQUIRED)

qt_add_executable(appqxmpp_qt6
main.cpp
)

qt_add_qml_module(appqxmpp_qt6
URI qxmpp_qt6
VERSION 1.0
QML_FILES main.qml
)

set_target_properties(appqxmpp_qt6 PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)

target_compile_definitions(appqxmpp_qt6
PRIVATE $<$<OR:$CONFIG:Debug,$CONFIG:RelWithDebInfo>:QT_QML_DEBUG>)

target_link_libraries(appqxmpp_qt6 PRIVATE
Qt6::Quick
Qt6::Network
Qt6::Xml
Qt6::Core
QXmpp::QXmpp
)

include_directories(${PROJECT_SOURCE_DIR}/libs/qxmpp/source/src/base)
include_directories(${PROJECT_SOURCE_DIR}/libs/qxmpp/source/src/client)
include_directories(${PROJECT_SOURCE_DIR}/libs/qxmpp/source/src/server)
include_directories(${PROJECT_SOURCE_DIR}/libs/qxmpp/binary/src/base)

@lnjX
Copy link
Member

lnjX commented Sep 10, 2022

Unfortunately I'm also no expert when it's about building for android. However we have an (outdated) script to build kaidan (we now use craft for the android builds). Maybe that can help you:
https://invent.kde.org/network/kaidan/-/blob/5f9abb28050c4b5f8cf135166b156bb1cdb7cffd/utils/build-android.sh

It uses the android toolchain from ecm (extra-cmake-modules)

@timakas
Copy link
Author

timakas commented Sep 10, 2022

Unfortunately I'm also no expert when it's about building for android. However we have an (outdated) script to build kaidan (we now use craft for the android builds). Maybe that can help you: https://invent.kde.org/network/kaidan/-/blob/5f9abb28050c4b5f8cf135166b156bb1cdb7cffd/utils/build-android.sh

It uses the android toolchain from ecm (extra-cmake-modules)

Thanks for the suggestion. I did manage to successfully build the library for Android x86_64 with the Kaidan build script, although I installed the library in the default path /usr/local/lib. I'm just not quite sure how to link the library in my project CMakeLists.txt file. CMake can't seem to find the QXmpp package. However it can find the include header files. Any ideas?

@lnjX
Copy link
Member

lnjX commented Sep 10, 2022

I think you need to install it into your android toolchain (-DCMAKE_INSTALL_PREFIX=$CUSTOM_ANDROID_TOOLCHAIN), see https://invent.kde.org/network/kaidan/-/blob/5f9abb28050c4b5f8cf135166b156bb1cdb7cffd/utils/build-android.sh#L136

@lnjX
Copy link
Member

lnjX commented Sep 10, 2022

Did it work?

@timakas
Copy link
Author

timakas commented Sep 10, 2022

Did it work?

I installed it into the custom android toolchain. I built the library with x86_64 ABI, my project is using x86_64, and my emulator is x86_64. I have decided to use qmake Android Qt 5.15.2 to build my project instead, as cmake with Qt6 is not cooperating. I can link to the library now, and my project builds fine while including QXmpp headers. But when I run it on the emulator, I get the following error:

E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libqxmpp.so.4" not found: needed by /data/app/~~7dtcSxJ8qyDlTalf7FHHRA==/org.qtproject.example.qxmpp_qt5-WSitchwPOM_RwBChPzaG0g==/lib/x86_64/libqxmpp_qt5_x86_64.so in namespace classloader-namespace

@timakas
Copy link
Author

timakas commented Oct 2, 2022

I've been looking more into this issue, and I think the problem is that the library is not being copied across to the build directory, and when I try to deploy the apk to the emulator it can't find the library. So I've tried the following commands in the .pro file:

QMAKE_EXTRA_TARGETS += cp $$PWD/x86_64/qxmpp_lib/lib/libqxmpp.so $$OUT_PWD/android-build/libs/x86_64
LIBS += -L$$PWD/x86_64/qxmpp_lib/lib/ -lqxmpp
INCLUDEPATH += $$PWD/x86_64/qxmpp_lib/include
DEPENDPATH += $$PWD/x86_64/qxmpp_lib/include

It does copy the library, and I can do a successful build, however the application still does not recognize the library on deployment, and the app crashes. I'm pretty sure this is not an architecture conflict. Maybe I am copying the library to the wrong place?

I was wondering also, if it is possible to put the library source code directly into my project tree instead of linking to the library?

@lnjX
Copy link
Member

lnjX commented Oct 2, 2022

If everything works correctly I think androiddeployqt should automatically copy all linked libraries into your apk.

When you manually copy libqxmpp.so, you probably also need to create symlinks for libqxmpp.so.4. Maybe that fixes it?

Alternatively you can also use craft (https://community.kde.org/Craft/Android) for building your application. Craft does the whole android stuff more or less completely for your, but you probably need to create a craft package for your app (qxmpp should be packaged already).
For Kaidan we also use craft because it's less maintenance effort.

Directly including qxmpp's CMakeLists.txt in your cmake project (then you need to use cmake) should be possible, but I haven't tested that with qxmpp yet.

@timakas
Copy link
Author

timakas commented Oct 2, 2022

If everything works correctly I think androiddeployqt should automatically copy all linked libraries into your apk.

When you manually copy libqxmpp.so, you probably also need to create symlinks for libqxmpp.so.4. Maybe that fixes it?

Alternatively you can also use craft (https://community.kde.org/Craft/Android) for building your application. Craft does the whole android stuff more or less completely for your, but you probably need to create a craft package for your app (qxmpp should be packaged already). For Kaidan we also use craft because it's less maintenance effort.

Directly including qxmpp's CMakeLists.txt in your cmake project (then you need to use cmake) should be possible, but I haven't tested that with qxmpp yet.

Thanks, I'll try craft and see how that goes.

@timakas
Copy link
Author

timakas commented Oct 4, 2022

Directly including qxmpp's CMakeLists.txt in your cmake project (then you need to use cmake) should be possible, but I haven't tested that with qxmpp yet.

I tried directly including the CMakeLists.txt, and I get the attached errors when I build. I included the following to my project CMakeLists.txt "include("${CMAKE_CURRENT_SOURCE_DIR}/qxmpp/CMakeLists.txt")". And I modified the qxmpp CMakeLists.txt, also attached, as well as project CMakeLists.txt. I am able to include qxmpp headers in my own classes without error though. And I'm trying this in Qt 6.2.4

Any ideas how to fix this?

I'm also looking into Craft, just thought I would try this first.

Screenshot from 2022-10-04 20-41-27
QXmpp CMakeLists.txt
Project CMakeLists.txt

@timakas
Copy link
Author

timakas commented Oct 5, 2022

So, I've figured out how to directly incorporate the qxmpp source code into qmake using Qt 5.15.2. I had to leave out the QXmppCall header and source files, but I don't need voice anyway. And I had to leave out the Omemo files as well, but I'll look into this later on. Basically I just merged the base and client folders into a single folder, and added that as an exiting directory into a separate pro file, and included it into the main project pro file.

Now, I get a successful build, and my app starts up on my emulator without crashing, so everything seems to work so far. Oh, and I also had to change some include declarations to be surrounded with double quotes. I'll also look into Craft as well when I get some time, still curious if I can get a successful build that way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants