Browse Source

Add a post-link script for Linux which fixes up rpath

- script is clean according to shellcheck.net
- added the script to the QGCPostLinkCommon
- added patchelf to the Dockerfile and the github workflows for Linux
QGC4.4
Keith Bennett 4 years ago committed by Don Gagne
parent
commit
92d310f7c1
  1. 3
      .github/workflows/linux_debug.yml
  2. 3
      .github/workflows/linux_release.yml
  3. 2
      QGCPostLinkCommon.pri
  4. 1
      deploy/docker/Dockerfile-build-linux
  5. 72
      deploy/linux-post-link.sh
  6. 5
      deploy/qgroundcontrol-start.sh

3
.github/workflows/linux_debug.yml

@ -45,6 +45,9 @@ jobs: @@ -45,6 +45,9 @@ jobs:
- name: Install ccache
run: sudo apt-get install ccache
- name: Install post-link dependencies
run: sudo apt-get install -y patchelf
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}

3
.github/workflows/linux_release.yml

@ -46,6 +46,9 @@ jobs: @@ -46,6 +46,9 @@ jobs:
- name: Install ccache
run: sudo apt-get install ccache
- name: Install post-link dependencies
run: sudo apt-get install -y patchelf
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}

2
QGCPostLinkCommon.pri

@ -163,4 +163,6 @@ LinuxBuild { @@ -163,4 +163,6 @@ LinuxBuild {
} else {
include($$PWD/custom/custom_deploy.pri)
}
QMAKE_POST_LINK += && QTDIR="$$DESTDIR/Qt" RPATHDIR="$$DESTDIR/Qt/libs" QTCONF_PATH="$$DESTDIR/qt.conf" $$SOURCE_DIR/deploy/linux-post-link.sh
}

1
deploy/docker/Dockerfile-build-linux

@ -47,6 +47,7 @@ RUN apt update && apt -y --quiet --no-install-recommends install \ @@ -47,6 +47,7 @@ RUN apt update && apt -y --quiet --no-install-recommends install \
ninja-build \
openssh-client \
openssl \
patchelf \
pkg-config \
rsync \
speech-dispatcher \

72
deploy/linux-post-link.sh

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
#!/usr/bin/bash
#
# Premise:
# Shared libraries (Qt, airmap, etc) on Linux are built without knowing where
# they will be installed to; they assume they will be installed to the system.
#
# QGC does not install to the system. Instead it copies them to `Qt/libs`. The
# libraries need to have their rpath set correctly to ensure that the built
# application and its libraries are found at runtime. Without this step then the
# libraries won't be found. You might not notice it if you have the libraries
# installed in your system. A lot of systems will have the Qt libs installed,
# but they might be a different version. It "might" work, it might cause subtle
# bugs, or it might not work at all.
#
# To patch the libraries, a tool called `patchelf` is used.
#
# If the libraries' rpath isn't set correctly then LD_LIBRARY_PATH would need
# to be used, like such:
# LD_LIBRARY_PATH=./Qt/libs ./QGroundControl
#
# In addition, Qt will sometimes want to reference its own directory to find
# certain resources. This installs a file, qt.conf, which tells Qt where its
# installation is at.
# Without the qt.conf file, you would need to tell Qt where to find certain
# files, particularly for QML, like such:
# QML2_IMPORT_PATH=./Qt/qml QT_PLUGIN_PATH=./Qt/plugins ./QGroundControl
#
# -x: echo
# -e: stop on error
# -u: undefined variable use is an error
# -o pipefail: if any part of a pipeline fails, then the whole pipeline fails.
set -xeuo pipefail
# To set these arguments, set them as an environment variable. For example:
# QTDIR=/opt/qgc-deploy/Qt RPATHDIR=/opt/qgc-deploy/Qt/libs QTCONF_PATH=/opt/qgc-deploy/qt.conf ./linux-post-link.sh
: "${QTDIR:=./Qt}"
: "${RPATHDIR:="${QTDIR}/libs"}"
: "${QTCONF_PATH:=./qt.conf}"
# find:
# type f (files)
# that end with '.so'
# or that end with '.so.5'
# and are executable
# silence stderr (find will complain if it doesn't have permission to traverse)
find "${QTDIR}" \
-type f \
-iname '*.so' \
-o -iname '*.so.5' \
-executable \
2>/dev/null |
while IFS='' read -r library; do
# Get the directory containing the library
library_dir="$(dirname "${library}")"
# Get the relative path from the library's directory to the Qt/libs directory.
library_rpath="$(realpath --relative-to "${library_dir}" "${RPATHDIR}")"
# patch the library's rpath to point to the Qt/libs directory.
# Note: '$ORIGIN' must not be expanded by the shell!
# shellcheck disable=SC2016
patchelf --set-rpath '$ORIGIN/'"${library_rpath}" "${library}"
done
# Create a qt.conf file
# https://doc.qt.io/qt-5/qt-conf.html
cat <<EOF > "${QTCONF_PATH}"
[Paths]
Prefix=./Qt
Libraries=libs
EOF

5
deploy/qgroundcontrol-start.sh

@ -1,10 +1,7 @@ @@ -1,10 +1,7 @@
#!/bin/sh
HERE="$(dirname "$(readlink -f "${0}")")"
export LD_LIBRARY_PATH="${HERE}/usr/lib/x86_64-linux-gnu":"${HERE}/Qt/libs":$LD_LIBRARY_PATH
export QML2_IMPORT_PATH="${HERE}/Qt/qml"
export QT_PLUGIN_PATH="${HERE}/Qt/plugins"
# hack until icon issue with AppImage is resolved
mkdir -p ~/.icons && cp ${HERE}/qgroundcontrol.png ~/.icons
mkdir -p ~/.icons && cp "${HERE}/qgroundcontrol.png" ~/.icons
"${HERE}/QGroundControl" "$@"

Loading…
Cancel
Save