diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c8fd27..b3e1306 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -81,7 +81,7 @@ jobs: sudo add-apt-repository universe sudo apt install libfuse2 chmod +x bundle/linux/create_appimage.sh - ./bundle/linux/create_appimage.sh --qt_path $Qt6_DIR --build_path cmake-build-release + ./bundle/linux/create_appimage.sh -q $Qt6_DIR -b cmake-build-release -o $IQTA_TOOLS/OpenSSLv3/src # Package Mac - if: contains(matrix.os, 'macos') && startsWith(matrix.qt_version, '6') diff --git a/.gitignore b/.gitignore index 8ec1751..5511107 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,4 @@ tests/kimai_server/data/kimai.sqlite /build/ /dist/ +*.AppImage diff --git a/bundle/linux/create_appimage.sh b/bundle/linux/create_appimage.sh old mode 100644 new mode 100755 index d9d51f6..f9ce243 --- a/bundle/linux/create_appimage.sh +++ b/bundle/linux/create_appimage.sh @@ -1,49 +1,65 @@ #!/bin/bash -set -x -set -e - # Run this script once Kemai is built. Install and AppImage will be handle here. # It just need path to Qt and to build directory. - # Read args -qt_path=${qt_path:-} -build_path=${build_path:-} - -while [ $# -gt 0 ]; do - if [[ $1 == *"--"* ]]; then - param="${1/--/}" - declare $param="$2" - fi - shift +usage() { echo "Usage: $0 -b -o -q "; exit 0; } + +while getopts ":hb:o:q:" o; do + case "${o}" in + b) + BUILD_DIR=${OPTARG} + ;; + o) + OPENSSL_DIR=${OPTARG} + ;; + q) + QT_DIR=${OPTARG} + ;; + h | *) + usage + ;; + esac done +if [[ -z ${BUILD_DIR+x} ]] || [[ -z ${OPENSSL_DIR+x} ]] || [[ -z ${QT_DIR+x} ]]; then + usage +fi + # Cleanup -rm $build_path/*.AppImage* || true +APPIMAGE_DESTDIR=${BUILD_DIR}/AppDir +rm -r ${APPIMAGE_DESTDIR} # Run install to AppDir and add linux files -DESTDIR=AppDir cmake --build $build_path --target install -cp bundle/linux/kemai.desktop $build_path/AppDir/ -cp bundle/linux/kemai.png $build_path/AppDir/ +DESTDIR=AppDir cmake --build ${BUILD_DIR} --target install || exit 1 + +# Copy sysroot +cp -rv bundle/linux/sysroot/* ${APPIMAGE_DESTDIR}/ +chmod +x ${APPIMAGE_DESTDIR}/usr/bin/kemai-wrapper.sh # Gets AppImage tools -pushd "$build_path" -wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage -chmod +x linuxdeploy*.AppImage +wget -nc -P ${BUILD_DIR}/ https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage +wget -nc -P ${BUILD_DIR}/ https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage +chmod +x ${BUILD_DIR}/linuxdeploy*.AppImage # Export vars -export QMAKE=$qt_path/bin/qmake -export LD_LIBRARY_PATH=$qt_path/lib -export VERSION=$(cat version.txt) +export QMAKE=${QT_DIR}/bin/qmake +export LD_LIBRARY_PATH=${QT_DIR}/lib +export VERSION=$(cat ${BUILD_DIR}/version.txt) export EXTRA_QT_PLUGINS=platforms,iconengines,wayland-decoration-client,wayland-graphics-integration-client,wayland-shell-integration,platformthemes,tls +# Copy OpenSSLv3 binaries +OPENSSL_APPDIR=${APPIMAGE_DESTDIR}/fallback/libssl.so.3 +mkdir -p ${OPENSSL_APPDIR} +cp -vL ${OPENSSL_DIR}/libssl.so* ${OPENSSL_APPDIR}/ +cp -vL ${OPENSSL_DIR}/libcrypto.so* ${OPENSSL_APPDIR}/ + # Run appimage builder -./linuxdeploy-x86_64.AppImage \ +${BUILD_DIR}/linuxdeploy-x86_64.AppImage \ --appimage-extract-and-run \ - --appdir AppDir \ + --appdir ${APPIMAGE_DESTDIR} \ --plugin qt \ - -d AppDir/kemai.desktop \ - -i AppDir/kemai.png \ + -d ${APPIMAGE_DESTDIR}/kemai-wrapper.desktop \ + -i ${APPIMAGE_DESTDIR}/kemai-wrapper.png \ --output appimage diff --git a/bundle/linux/kemai.desktop b/bundle/linux/sysroot/kemai-wrapper.desktop similarity index 57% rename from bundle/linux/kemai.desktop rename to bundle/linux/sysroot/kemai-wrapper.desktop index a7bda5e..c83ab08 100644 --- a/bundle/linux/kemai.desktop +++ b/bundle/linux/sysroot/kemai-wrapper.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Type=Application Name=Kemai -Exec=Kemai -Icon=kemai +Exec=kemai-wrapper.sh +Icon=kemai-wrapper Categories= \ No newline at end of file diff --git a/bundle/linux/kemai.png b/bundle/linux/sysroot/kemai-wrapper.png similarity index 100% rename from bundle/linux/kemai.png rename to bundle/linux/sysroot/kemai-wrapper.png diff --git a/bundle/linux/sysroot/usr/bin/kemai-wrapper.sh b/bundle/linux/sysroot/usr/bin/kemai-wrapper.sh new file mode 100755 index 0000000..5e72ad4 --- /dev/null +++ b/bundle/linux/sysroot/usr/bin/kemai-wrapper.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# +# Check if fallback libraries are present on host. If not, add embedded fallback libraries to path +# +function find_library() +{ + # Print full path to a library or return exit status 1 if not found + local library="$1" # take library name as input (e.g. "libfoo.so") + # Look for the library in $LD_LIBRARY_PATH + local dir IFS=':' # split path into array on this separator + for dir in "${LD_LIBRARY_PATH[@]}"; do + if [[ -e "${dir}/${library}" ]]; then + echo "${dir}/${library}" + return # Library found + fi + done + # Not found yet so check system cache + ldconfig -p | awk -v lib="${library}" -v arch="${HOSTTYPE}" \ +' +BEGIN {status=1} +($1 == lib && index($0, arch)) {print $NF; status=0; exit} +END {exit status} +' +} + +fallback_libs="" +for fallback_dir in "${APPDIR}/fallback"/*; do + libname="${fallback_dir##*/}" + if ! find_library "${libname}"; then + echo "${APPIMAGE}: Using fallback for ${libname}" + fallback_libs="${fallback_libs}:${fallback_dir}" + fi +done + +export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${fallback_libs}" + +# +# Wrapper to run expected embedded Qinertia app +# +${APPDIR}/usr/bin/Kemai diff --git a/src/client/kimaiCache.cpp b/src/client/kimaiCache.cpp index ebb3e59..c098388 100644 --- a/src/client/kimaiCache.cpp +++ b/src/client/kimaiCache.cpp @@ -9,7 +9,7 @@ using namespace kemai; void KimaiCache::synchronize(const std::shared_ptr& client, const std::set& categories) { - if (!mSyncSemaphore.try_acquire()) + if (!mSyncMutex.try_lock()) { spdlog::error("Sync already in progress"); return; @@ -107,7 +107,7 @@ void KimaiCache::updateSyncProgress(Category finishedCategory) if (mPendingSync.empty()) { mStatus = KimaiCache::Status::Ready; - mSyncSemaphore.release(); + mSyncMutex.unlock(); emit synchronizeFinished(); } } diff --git a/src/client/kimaiCache.h b/src/client/kimaiCache.h index 60ef8c2..e8d3646 100644 --- a/src/client/kimaiCache.h +++ b/src/client/kimaiCache.h @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -54,7 +53,7 @@ class KimaiCache : public QObject Activities mActivities; kemai::KimaiCache::Status mStatus = kemai::KimaiCache::Status::Empty; - std::binary_semaphore mSyncSemaphore{1}; + std::mutex mSyncMutex; std::mutex mProgressMutex; };