File indexing completed on 2024-11-10 04:05:17

0001 #!/bin/bash
0002 #
0003 #  SPDX-License-Identifier: GPL-3.0-or-later
0004 #
0005 
0006 # Halt on errors and be verbose about what we are doing
0007 set -e
0008 set -x
0009 
0010 # Read in our parameters
0011 export BUILD_PREFIX=$1
0012 export KRITA_SOURCES=$2
0013 export CHANNEL="${3}"
0014 
0015 # Save some frequently referenced locations in variables for ease of use / updating
0016 export APPDIR=${KRITA_APPDIR_PATH:-$BUILD_PREFIX/krita.appdir}
0017 export PLUGINS=$APPDIR/usr/lib/kritaplugins/
0018 
0019 # qjsonparser, used to add metadata to the plugins needs to work in a en_US.UTF-8 environment.
0020 # That's not always the case, so make sure it is
0021 export LC_ALL=en_US.UTF-8
0022 export LANG=en_us.UTF-8
0023 
0024 # We want to use $prefix/deps/usr/ for all our dependencies
0025 export DEPS_INSTALL_PREFIX=${KRITA_DEPS_PATH:-$BUILD_PREFIX/deps/usr}
0026 export BUILD_DIR=${KRITA_BUILD_PATH:-$BUILD_PREFIX/krita-build/}
0027 export DOWNLOADS_DIR=${KRITA_DOWNLOADS_PATH:-$BUILD_PREFIX/downloads/}
0028 
0029 # Setup variables needed to help everything find what we built
0030 ARCH=`dpkg --print-architecture`
0031 TRIPLET=`gcc -dumpmachine`
0032 export LD_LIBRARY_PATH=$DEPS_INSTALL_PREFIX/lib/:$DEPS_INSTALL_PREFIX/lib/$TRIPLET/:$APPDIR/usr/lib/:$LD_LIBRARY_PATH
0033 export PATH=$DEPS_INSTALL_PREFIX/bin/:$PATH
0034 export PKG_CONFIG_PATH=$DEPS_INSTALL_PREFIX/share/pkgconfig/:$DEPS_INSTALL_PREFIX/lib/pkgconfig/:/usr/lib/pkgconfig/:$PKG_CONFIG_PATH
0035 export CMAKE_PREFIX_PATH=$DEPS_INSTALL_PREFIX:$CMAKE_PREFIX_PATH
0036 # https://docs.python.org/3.10/using/cmdline.html#envvar-PYTHONHOME
0037 if [ -d $DEPS_INSTALL_PREFIX/sip ] ; then
0038 export PYTHONPATH=$DEPS_INSTALL_PREFIX/sip
0039 fi
0040 export PYTHONHOME=$DEPS_INSTALL_PREFIX
0041 
0042 source ${KRITA_SOURCES}/packaging/linux/appimage/override_compiler.sh.inc
0043 
0044 # Switch over to our build prefix
0045 cd $BUILD_PREFIX
0046 
0047 #
0048 # Now we can get the process started!
0049 #
0050 
0051 # Step 0: place the translations where ki18n and Qt look for them
0052 if [ -d $APPDIR/usr/share/locale ] ; then
0053     rsync -prul $APPDIR/usr/share/locale $APPDIR/usr/share/krita
0054     rm -rf $APPDIR/usr/share/locale
0055 fi
0056 
0057 # Step 1: Copy over all necessary resources required by dependencies or libraries that are missed by linuxdeployqt
0058 cp -r $DEPS_INSTALL_PREFIX/share/locale $APPDIR/usr/share/krita
0059 cp -r $DEPS_INSTALL_PREFIX/share/kf5 $APPDIR/usr/share
0060 cp -r $DEPS_INSTALL_PREFIX/share/mime $APPDIR/usr/share
0061 cp -r $DEPS_INSTALL_PREFIX/lib/python3.10 $APPDIR/usr/lib
0062 if [ -d $DEPS_INSTALL_PREFIX/share/sip ] ; then
0063 cp -r $DEPS_INSTALL_PREFIX/share/sip $APPDIR/usr/share
0064 fi
0065 
0066 cp -r $DEPS_INSTALL_PREFIX/translations $APPDIR/usr/
0067 
0068 if [ ! -d $APPDIR/usr/libstdcpp-fallback/ ] ; then
0069     mkdir -p $APPDIR/usr/libstdcpp-fallback/
0070     cd $APPDIR/usr/libstdcpp-fallback/
0071     cp  /usr/lib/x86_64-linux-gnu/libstdc++.so.6.* ./
0072     ln -s `find ./ -name 'libstdc++.so.6.*' -maxdepth 1 -type f | head -n1 | xargs basename` libstdc++.so.6
0073 fi
0074 
0075 mkdir $BUILD_PREFIX/krita-apprun-build
0076 (
0077     cd $BUILD_PREFIX/krita-apprun-build
0078     cmake -DCMAKE_BUILD_TYPE=Release $KRITA_SOURCES/packaging/linux/appimage/krita-apprun/
0079     cmake --build .
0080     cp AppRun $APPDIR
0081 )
0082 rm -rf $BUILD_PREFIX/krita-apprun-build
0083 
0084 if [ -d $APPDIR/usr/lib/python3.10/site-packages ]; then
0085     rm -rf $APPDIR/usr/lib/python3.10/site-packages/packaging*
0086     rm -rf $APPDIR/usr/lib/python3.10/site-packages/pip*
0087     rm -rf $APPDIR/usr/lib/python3.10/site-packages/pyparsing*
0088     rm -rf $APPDIR/usr/lib/python3.10/site-packages/PyQt_builder*
0089     rm -rf $APPDIR/usr/lib/python3.10/site-packages/setuptools*
0090     rm -rf $APPDIR/usr/lib/python3.10/site-packages/sip*
0091     rm -rf $APPDIR/usr/lib/python3.10/site-packages/toml*
0092     rm -rf $APPDIR/usr/lib/python3.10/site-packages/easy-install.pth
0093 fi
0094 
0095 ## Font related deps are explicitly ignored by AppImage build script,
0096 ## so we should copy them manually
0097 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libfontconfig.so.1* $APPDIR/usr/lib/
0098 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libharfbuzz.so.0* $APPDIR/usr/lib/
0099 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libfribidi.so.0* $APPDIR/usr/lib/
0100 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libfreetype.so.6* $APPDIR/usr/lib/
0101 
0102 ## == MLT Dependencies and Resources ==
0103 cp -r $DEPS_INSTALL_PREFIX/share/mlt-7 $APPDIR/usr/share/mlt
0104 cp -r $DEPS_INSTALL_PREFIX/lib/mlt-7 $APPDIR/usr/lib/mlt
0105 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libmlt*.so* $APPDIR/usr/lib/
0106 
0107 export MLT_BINARIES=""
0108 for BIN in $APPDIR/usr/lib/libmlt*.so*; do
0109   MLT_BINARIES="${MLT_BINARIES} -executable=${BIN}"
0110 done
0111 
0112 for BIN in $APPDIR/usr/lib/mlt/*.so*; do
0113   MLT_BINARIES="${MLT_BINARIES} -executable=${BIN}"
0114 done
0115 
0116 ## == FFMPEG Dependencies and Resources ==
0117 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libav*.s* $APPDIR/usr/lib/
0118 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libpostproc*.s* $APPDIR/usr/lib/
0119 cp -av --preserve=links $DEPS_INSTALL_PREFIX/lib/libsw*.s* $APPDIR/usr/lib/
0120 cp -av $DEPS_INSTALL_PREFIX/bin/ff* $APPDIR/usr/bin/
0121 
0122 export FFMPEG_BINARIES=""
0123 
0124 for BIN in $APPDIR/usr/bin/ff*; do
0125   FFMPEG_BINARIES="${FFMPEG_BINARIES} -executable=${BIN}"
0126 done
0127 
0128 for BIN in $APPDIR/usr/lib/libav*.s*; do
0129   FFMPEG_BINARIES="${FFMPEG_BINARIES} -executable=${BIN}"
0130 done;
0131 
0132 for BIN in $APPDIR/usr/lib/libpostproc*; do
0133   FFMPEG_BINARIES="${FFMPEG_BINARIES} -executable=${BIN}"
0134 done;
0135 
0136 for BIN in $APPDIR/usr/lib/libsw*.s*; do
0137   FFMPEG_BINARIES="${FFMPEG_BINARIES} -executable=${BIN}"
0138 done;
0139 
0140 # Step 2: Relocate binaries from the architecture specific directory as required for Appimages
0141 if [[ -d "$APPDIR/usr/lib/$TRIPLET" ]] ; then
0142   rsync -prul $APPDIR/usr/lib/$TRIPLET/ $APPDIR/usr/lib/
0143   rm -rf $APPDIR/usr/lib/$TRIPLET/
0144 fi
0145 
0146 # Depending on the status of qt.conf file, qml destination path might be different,
0147 # fix that
0148 if [ -d $APPDIR/usr/lib/qml ] ; then
0149     mkdir -p $APPDIR/usr/qml
0150     rsync -prul $APPDIR/usr/lib/qml/ $APPDIR/usr/qml/
0151     rm -rf $APPDIR/usr/lib/qml
0152 fi
0153 
0154 # Step 3: Update the rpath in the various plugins we have to make sure they'll be loadable in an Appimage context
0155 for lib in $PLUGINS/*.so*; do
0156   patchelf --set-rpath '$ORIGIN/..' $lib;
0157 done
0158 
0159 for lib in $APPDIR/usr/lib/python3.10/site-packages/PyQt5/*.so*; do
0160   patchelf --set-rpath '$ORIGIN/../..' $lib;
0161 done
0162 
0163 for lib in $APPDIR/usr/lib/python3.10/lib-dynload/*.so*; do
0164   patchelf --set-rpath '$ORIGIN/../..' $lib;
0165 done
0166 
0167 patchelf --set-rpath '$ORIGIN/../../../..' $APPDIR/usr/qml/org/krita/draganddrop/libdraganddropplugin.so
0168 patchelf --set-rpath '$ORIGIN/../../../..' $APPDIR/usr/qml/org/krita/sketch/libkritasketchplugin.so
0169 patchelf --set-rpath '$ORIGIN/../..' $APPDIR/usr/lib/krita-python-libs/PyKrita/krita.so
0170 if [ -f $APPDIR/usr/lib/python3.10/site-packages/PyQt5/sip.so ] ; then
0171 patchelf --set-rpath '$ORIGIN/../..' $APPDIR/usr/lib/python3.10/site-packages/PyQt5/sip.so
0172 fi
0173 
0174 # Step 4: Find out what version of Krita we built and give the Appimage a proper name
0175 cd $BUILD_DIR
0176 
0177 KRITA_VERSION=$(grep "#define KRITA_VERSION_STRING" libs/version/kritaversion.h | cut -d '"' -f 2)
0178 # Also find out the revision of Git we built
0179 # Then use that to generate a combined name we'll distribute
0180 cd $KRITA_SOURCES
0181 if git rev-parse --is-inside-work-tree; then
0182     GIT_REVISION=$(git rev-parse --short HEAD)
0183     export VERSION=$KRITA_VERSION-$GIT_REVISION
0184     VERSION_TYPE="development"
0185 
0186     if [ -z "${CHANNEL}" ]; then
0187         BRANCH="$(git rev-parse --abbrev-ref HEAD)"
0188 
0189         if [ "${JOB_NAME}" == "Krita_Nightly_Appimage_Build" ]; then
0190             CHANNEL="Next"
0191         elif [ "${JOB_NAME}" == "Krita_Stable_Appimage_Build" ]; then
0192             CHANNEL="Plus"
0193         elif [ "$BRANCH" = "master" ]; then
0194             CHANNEL="Next"
0195         elif [[ "${BRANCH}" =~ krita/.* ]]; then
0196             CHANNEL="Plus"
0197         fi
0198     fi
0199 else
0200         export VERSION=$KRITA_VERSION
0201 
0202     pushd $BUILD_DIR
0203 
0204     #if KRITA_BETA is set, set channel to Beta, otherwise set it to stable
0205     is_beta=0
0206     grep "define KRITA_BETA 1" libs/version/kritaversion.h || is_beta=$?
0207 
0208     is_rc=0
0209     grep "define KRITA_RC 1" libs/version/kritaversion.h || is_rc=$?
0210 
0211     popd
0212 
0213     if [ $is_beta -eq 0 ]; then
0214         VERSION_TYPE="development"
0215     else
0216         VERSION_TYPE="stable"
0217     fi
0218 
0219     if [ -z "${CHANNEL}" ]; then
0220         if [ $is_beta -eq 0 ] || [ $is_rc -eq 0 ]; then
0221             CHANNEL="Beta"
0222         else
0223             CHANNEL="Stable"
0224         fi
0225     fi
0226 fi
0227 
0228 DATE=$(git log -1 --format="%ct" | xargs -I{} date -d @{} +%Y-%m-%d)
0229 if [ "$DATE" = "" ] ; then
0230         DATE=$(date +%Y-%m-%d)
0231 fi
0232 
0233 sed -e "s|<release version=\"\" date=\"\" />|<release version=\"$VERSION\" date=\"$DATE\" type=\"$VERSION_TYPE\"/>|" -i $APPDIR/usr/share/metainfo/org.kde.krita.appdata.xml
0234 
0235 if [ -n "${CHANNEL}" ]; then # if channel argument is set, we wish to embed update information
0236     # set zsync url for linuxdeployqt
0237     if [ "$CHANNEL" = "Next" ]; then
0238         ZSYNC_URL="zsync|https://binary-factory.kde.org/job/Krita_Nightly_Appimage_Build/lastSuccessfulBuild/artifact/Krita-${CHANNEL}-x86_64.appimage.zsync"
0239     elif [ "$CHANNEL" = "Plus" ]; then
0240         ZSYNC_URL="zsync|https://binary-factory.kde.org/job/Krita_Stable_Appimage_Build/lastSuccessfulBuild/artifact/Krita-${CHANNEL}-x86_64.appimage.zsync"
0241     elif [ "$CHANNEL" = "Stable" ]; then
0242         ZSYNC_URL="zsync|https://download.kde.org/stable/krita/updates/Krita-${CHANNEL}-x86_64.appimage.zsync"
0243     elif [ "$CHANNEL" = "Beta" ]; then
0244         ZSYNC_URL="zsync|https://download.kde.org/unstable/krita/updates/Krita-${CHANNEL}-x86_64.appimage.zsync"
0245     fi
0246 fi
0247 
0248 # Return to our build root
0249 cd $BUILD_PREFIX
0250 
0251 # Step 5: Install AppImageUpdate
0252 
0253 if [[ $ARCH == "amd64" ]]; then
0254     # download
0255     # XXX: bundle this inside the Docker image *and* make it portable to ARM
0256     mkdir -p $DOWNLOADS_DIR
0257     cd $DOWNLOADS_DIR
0258 
0259     UPDATER_SHA256=414f10d9ab2dc72dc6874dbdb99454227124473a7ae691db2288d60f14f810fe
0260 
0261     if ! test -f "AppImageUpdate" || ! echo -n "$UPDATER_SHA256 AppImageUpdate" | sha256sum -c -; then
0262         wget "https://files.kde.org/krita/build/AppImageUpdate-x86_64.AppImage" -O AppImageUpdate
0263         echo -n "$UPDATER_SHA256 AppImageUpdate" | sha256sum -c -
0264     fi
0265 
0266     cd $BUILD_PREFIX
0267 fi
0268 
0269 if [ -f $DOWNLOADS_DIR/AppImageUpdate ]; then
0270        cp $DOWNLOADS_DIR/AppImageUpdate $APPDIR/usr/bin/
0271        chmod +x $APPDIR/usr/bin/AppImageUpdate
0272 fi
0273 
0274 # place the icon where linuxdeployqt seems to expect it
0275 find $APPDIR -name krita.png
0276 cp $APPDIR/usr/share/icons/hicolor/256x256/apps/krita.png $APPDIR
0277 ls $APPDIR
0278 
0279 if [ -n "$STRIP_APPIMAGE" ]; then
0280     # strip debugging information
0281     function find-elf-files {
0282         # * python libraries are not strippable (strip fails with error)
0283         # * AppImage packages should not be stripped, because it breaks them
0284         find $1 -type f -name "*" -not -name "*.o" -not -path "*/python3.10/*" -not -name "AppImageUpdate" -not -name "libstdc++.so.6.*" -exec sh -c '
0285             case "$(head -n 1 "$1")" in
0286             ?ELF*) exit 0;;
0287             esac
0288             exit 1
0289             ' sh {} \; -print
0290     }
0291 
0292     TEMPFILE=`tempfile`
0293     find-elf-files $APPDIR > $TEMPFILE
0294 
0295     for i in `cat $TEMPFILE`; do
0296         strip -v --strip-unneeded --strip-debug $i
0297     done
0298 
0299     rm -f $TEMPFILE
0300 fi
0301 
0302 # Step 4: Build the image!!!
0303 linuxdeployqt $APPDIR/usr/share/applications/org.kde.krita.desktop \
0304   -executable=$APPDIR/usr/bin/krita \
0305   ${MLT_BINARIES} \
0306   ${FFMPEG_BINARIES} \
0307   -qmldir=$DEPS_INSTALL_PREFIX/qml \
0308   -verbose=2 \
0309   -bundle-non-qt-libs \
0310   -extra-plugins=$PLUGINS,$APPDIR/usr/lib/krita-python-libs/PyKrita/krita.so,$APPDIR/usr/qml/org/krita/sketch/libkritasketchplugin.so,$APPDIR/usr/qml/org/krita/draganddrop/libdraganddropplugin.so  \
0311   -updateinformation="${ZSYNC_URL}" \
0312   -appimage
0313 
0314 # Generate a new name for the Appimage file and rename it accordingly
0315 
0316 if [[ $ARCH == "arm64" ]]; then
0317   APPIMAGE_ARCHITECTURE="aarch64"
0318 elif [[ $ARCH == "amd64" ]]; then
0319   APPIMAGE_ARCHITECTURE="x86_64"
0320 else
0321   APPIMAGE_ARCHITECTURE=$ARCH
0322 fi
0323 
0324 OLD_APPIMAGE_NAME="Krita-${VERSION}-${APPIMAGE_ARCHITECTURE}.AppImage"
0325 NEW_APPIMAGE_NAME="krita-${VERSION}-${APPIMAGE_ARCHITECTURE}.appimage"
0326 mv ${OLD_APPIMAGE_NAME} ${NEW_APPIMAGE_NAME}