added scripts for linux appimage docker image
This commit is contained in:
parent
edcb76bacd
commit
6fd51256f0
3 changed files with 453 additions and 0 deletions
21
build/docker/linux/Dockerfile
Normal file
21
build/docker/linux/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
|||
FROM library/ubuntu:18.04
|
||||
# For maximum AppImage compatibility, build on the oldest Linux distribution
|
||||
# that still receives security updates from its manufacturer.
|
||||
COPY setup.sh /setup.sh
|
||||
RUN bash -ex setup.sh
|
||||
# Note that each additional ADD, RUN or COPY command creates a new "layer"
|
||||
# (i.e. an intermediate Docker image). Any clean-up steps after a RUN command
|
||||
# must be done as part of that same command, like this:
|
||||
#
|
||||
# RUN command \
|
||||
# && clean-up-command # creates single clean layer
|
||||
#
|
||||
# Or if `command` is a script, clean-up could be done as part of that script.
|
||||
#
|
||||
# Avoid doing this:
|
||||
#
|
||||
# RUN command # creates dirty layer
|
||||
# RUN clean-up-command # creates clean layer
|
||||
#
|
||||
# This is like reverting a bad commit: you can't see the dirtiness any more,
|
||||
# but it's still in the history and still takes up space on your hard drive.
|
230
build/docker/linux/build.sh
Normal file
230
build/docker/linux/build.sh
Normal file
|
@ -0,0 +1,230 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "Build Linux MuseScore AppImage"
|
||||
|
||||
# Go one-up from MuseScore root dir regardless of where script was run from:
|
||||
cd "$(dirname "$(readlink -f "${0}")")/../../../.."
|
||||
|
||||
##########################################################################
|
||||
# SETUP ENVIRONMENT
|
||||
##########################################################################
|
||||
ENV_FILE=./musescore_environment.sh
|
||||
. ${ENV_FILE}
|
||||
|
||||
echo "=== ENVIRONMENT === "
|
||||
${CXX} --version
|
||||
${CC} --version
|
||||
echo " "
|
||||
cmake --version
|
||||
echo " "
|
||||
appimagetool --version
|
||||
echo " "
|
||||
linuxdeploy --list-plugins
|
||||
echo "===================="
|
||||
echo " "
|
||||
|
||||
|
||||
##########################################################################
|
||||
# BUILD MUSESCORE
|
||||
##########################################################################
|
||||
|
||||
cd MuseScore
|
||||
#rm -rf ./build.*
|
||||
make revision
|
||||
make "$@" portable
|
||||
cd ..
|
||||
|
||||
##########################################################################
|
||||
# BUNDLE DEPENDENCIES INTO APPDIR
|
||||
##########################################################################
|
||||
|
||||
cd MuseScore
|
||||
prefix="$(cat build.release/PREFIX.txt)" # MuseScore was installed here
|
||||
cd "$(dirname "${prefix}")"
|
||||
appdir="$(basename "${prefix}")" # directory that will become the AppImage
|
||||
|
||||
# Prevent linuxdeploy setting RUNPATH in binaries that shouldn't have it
|
||||
mv "${appdir}/bin/findlib" "${appdir}/../findlib"
|
||||
|
||||
# Remove Qt plugins for MySQL and PostgreSQL to prevent
|
||||
# linuxdeploy-plugin-qt from failing due to missing dependencies.
|
||||
# SQLite plugin alone should be enough for our AppImage.
|
||||
# rm -f ${QT_PATH}/plugins/sqldrivers/libqsql{mysql,psql}.so
|
||||
qt_sql_drivers_path="${QT_PATH}/plugins/sqldrivers"
|
||||
qt_sql_drivers_tmp="/tmp/qtsqldrivers"
|
||||
mkdir -p "$qt_sql_drivers_tmp"
|
||||
mv "${qt_sql_drivers_path}/libqsqlmysql.so" "${qt_sql_drivers_tmp}/libqsqlmysql.so"
|
||||
mv "${qt_sql_drivers_path}/libqsqlpsql.so" "${qt_sql_drivers_tmp}/libqsqlpsql.so"
|
||||
|
||||
# Colon-separated list of root directories containing QML files.
|
||||
# Needed for linuxdeploy-plugin-qt to scan for QML imports.
|
||||
# Qml files can be in different directories, the qmlimportscanner will go through everything recursively.
|
||||
export QML_SOURCES_PATHS=/MuseScore/
|
||||
|
||||
linuxdeploy --appdir "${appdir}" # adds all shared library dependencies
|
||||
linuxdeploy-plugin-qt --appdir "${appdir}" # adds all Qt dependencies
|
||||
|
||||
unset QML_SOURCES_PATHS
|
||||
|
||||
# In case this container is reused multiple times, return the moved libraries back
|
||||
mv "${qt_sql_drivers_tmp}/libqsqlmysql.so" "${qt_sql_drivers_path}/libqsqlmysql.so"
|
||||
mv "${qt_sql_drivers_tmp}/libqsqlpsql.so" "${qt_sql_drivers_path}/libqsqlpsql.so"
|
||||
|
||||
# Put the non-RUNPATH binaries back
|
||||
mv "${appdir}/../findlib" "${appdir}/bin/findlib"
|
||||
|
||||
##########################################################################
|
||||
# BUNDLE REMAINING DEPENDENCIES MANUALLY
|
||||
##########################################################################
|
||||
|
||||
function find_library()
|
||||
{
|
||||
# Print full path to a library or return exit status 1 if not found
|
||||
"${appdir}/bin/findlib" "$@"
|
||||
}
|
||||
|
||||
function fallback_library()
|
||||
{
|
||||
# Copy a library into a special fallback directory inside the AppDir.
|
||||
# Fallback libraries are not loaded at runtime by default, but they can
|
||||
# be loaded if it is found that the application would crash otherwise.
|
||||
local library="$1"
|
||||
local full_path="$(find_library "$1")"
|
||||
local new_path="${appdir}/fallback/${library}"
|
||||
mkdir -p "${new_path}" # directory has the same name as the library
|
||||
cp -L "${full_path}" "${new_path}/${library}"
|
||||
# Use the AppRun script to check at runtime whether the user has a copy of
|
||||
# this library. If not then add our copy's directory to $LD_LIBRARY_PATH.
|
||||
}
|
||||
|
||||
# UNWANTED FILES
|
||||
# linuxdeploy or linuxdeploy-plugin-qt may have added some files or folders
|
||||
# that we don't want. List them here using paths relative to AppDir root.
|
||||
# Report new additions at https://github.com/linuxdeploy/linuxdeploy/issues
|
||||
# or https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues for Qt libs.
|
||||
unwanted_files=(
|
||||
# none
|
||||
)
|
||||
|
||||
# ADDITIONAL QT COMPONENTS
|
||||
# linuxdeploy-plugin-qt may have missed some Qt files or folders that we need.
|
||||
# List them here using paths relative to the Qt root directory. Report new
|
||||
# additions at https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues
|
||||
additional_qt_components=(
|
||||
/plugins/printsupport/libcupsprintersupport.so
|
||||
)
|
||||
|
||||
# ADDITIONAL LIBRARIES
|
||||
# linuxdeploy may have missed some libraries that we need
|
||||
# Report new additions at https://github.com/linuxdeploy/linuxdeploy/issues
|
||||
additional_libraries=(
|
||||
libssl.so.1.0.0 # OpenSSL (for Save Online)
|
||||
libcrypto.so.1.0.0 # OpenSSL (for Save Online)
|
||||
)
|
||||
|
||||
# FALLBACK LIBRARIES
|
||||
# These get bundled in the AppImage, but are only loaded if the user does not
|
||||
# already have a version of the library installed on their system. This is
|
||||
# helpful in cases where it is necessary to use a system library in order for
|
||||
# a particular feature to work properly, but where the program would crash at
|
||||
# startup if the library was not found. The fallback library may not provide
|
||||
# the full functionality of the system version, but it does avoid the crash.
|
||||
# Report new additions at https://github.com/linuxdeploy/linuxdeploy/issues
|
||||
fallback_libraries=(
|
||||
libjack.so.0 # https://github.com/LMMS/lmms/pull/3958
|
||||
)
|
||||
|
||||
for file in "${unwanted_files[@]}"; do
|
||||
rm -rf "${appdir}/${file}"
|
||||
done
|
||||
|
||||
for file in "${additional_qt_components[@]}"; do
|
||||
mkdir -p "${appdir}/$(dirname "${file}")"
|
||||
cp -L "${QT_PATH}/${file}" "${appdir}/${file}"
|
||||
done
|
||||
|
||||
for lib in "${additional_libraries[@]}"; do
|
||||
full_path="$(find_library "${lib}")"
|
||||
cp -L "${full_path}" "${appdir}/lib/${lib}"
|
||||
done
|
||||
|
||||
for fb_lib in "${fallback_libraries[@]}"; do
|
||||
fallback_library "${fb_lib}"
|
||||
done
|
||||
|
||||
# METHOD OF LAST RESORT
|
||||
# Special treatment for some dependencies when all other methods fail
|
||||
|
||||
# Bundle libnss3 and friends as fallback libraries. Needed on Chromebook.
|
||||
# See discussion at https://github.com/probonopd/linuxdeployqt/issues/35
|
||||
libnss3_files=(
|
||||
# https://packages.ubuntu.com/xenial/amd64/libnss3/filelist
|
||||
libnss3.so
|
||||
libnssutil3.so
|
||||
libsmime3.so
|
||||
libssl3.so
|
||||
nss/libfreebl3.chk
|
||||
nss/libfreebl3.so
|
||||
nss/libfreeblpriv3.chk
|
||||
nss/libfreeblpriv3.so
|
||||
nss/libnssckbi.so
|
||||
nss/libnssdbm3.chk
|
||||
nss/libnssdbm3.so
|
||||
nss/libsoftokn3.chk
|
||||
nss/libsoftokn3.so
|
||||
)
|
||||
|
||||
libnss3_system_path="$(dirname "$(find_library libnss3.so)")"
|
||||
libnss3_appdir_path="${appdir}/fallback/libnss3.so" # directory named like library
|
||||
|
||||
mkdir -p "${libnss3_appdir_path}/nss"
|
||||
|
||||
for file in "${libnss3_files[@]}"; do
|
||||
cp -L "${libnss3_system_path}/${file}" "${libnss3_appdir_path}/${file}"
|
||||
rm -f "${appdir}/lib/$(basename "${file}")" # in case it was already packaged by linuxdeploy
|
||||
done
|
||||
|
||||
##########################################################################
|
||||
# TURN APPDIR INTO AN APPIMAGE
|
||||
##########################################################################
|
||||
|
||||
appimage="${appdir%.AppDir}.AppImage" # name to use for AppImage file
|
||||
|
||||
appimagetool_args=( # array
|
||||
# none
|
||||
)
|
||||
|
||||
created_files=(
|
||||
"${appimage}"
|
||||
)
|
||||
|
||||
if [[ "${UPDATE_INFORMATION}" ]]; then
|
||||
appimagetool_args+=( # append to array
|
||||
--updateinformation "${UPDATE_INFORMATION}"
|
||||
)
|
||||
created_files+=(
|
||||
"${appimage}.zsync" # this file will contain delta update data
|
||||
)
|
||||
else
|
||||
cat >&2 <<EOF
|
||||
$0: Automatic updates disabled.
|
||||
To enable automatic updates, please set the env. variable UPDATE_INFORMATION
|
||||
according to <https://github.com/AppImage/AppImageSpec/blob/master/draft.md>.
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create AppImage
|
||||
appimagetool "${appimagetool_args[@]}" "${appdir}" "${appimage}"
|
||||
|
||||
# We are running as root in the Docker image so all created files belong to
|
||||
# root. Allow non-root users outside the Docker image to access these files.
|
||||
chmod a+rwx "${created_files[@]}"
|
||||
parent_dir="${PWD}"
|
||||
while [[ "$(dirname "${parent_dir}")" != "${parent_dir}" ]]; do
|
||||
[[ "$parent_dir" == "/" ]] && break
|
||||
chmod a+rwx "$parent_dir"
|
||||
parent_dir="$(dirname "$parent_dir")"
|
||||
done
|
||||
|
||||
ls -lh "${created_files[@]}"
|
||||
echo "Build has finished!" >&2
|
202
build/docker/linux/setup.sh
Normal file
202
build/docker/linux/setup.sh
Normal file
|
@ -0,0 +1,202 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# For maximum AppImage compatibility, build on the oldest Linux distribution
|
||||
# that still receives security updates from its manufacturer.
|
||||
|
||||
set -e # Exit on errors
|
||||
set -x # Be verbose
|
||||
|
||||
echo "Setup Linux docker image for build AppImage"
|
||||
|
||||
# Go one-up from MuseScore root dir regardless of where script was run from:
|
||||
cd "$(dirname "$(readlink -f "${0}")")/../../../.."
|
||||
|
||||
# Let's remove the file with environment variables to recreate it
|
||||
ENV_FILE=./musescore_environment.sh
|
||||
rm -f ${ENV_FILE}
|
||||
|
||||
echo "echo 'Setup MuseScore build environment'" >> ${ENV_FILE}
|
||||
|
||||
##########################################################################
|
||||
# GET DEPENDENCIES
|
||||
##########################################################################
|
||||
|
||||
# DISTRIBUTION PACKAGES
|
||||
|
||||
# These are installed by default on Travis CI, but not on Docker
|
||||
apt_packages_basic=(
|
||||
# Alphabetical order please!
|
||||
file
|
||||
git
|
||||
pkg-config
|
||||
software-properties-common # installs `add-apt-repository`
|
||||
unzip
|
||||
)
|
||||
|
||||
# These are the same as on Travis CI
|
||||
apt_packages_standard=(
|
||||
# Alphabetical order please!
|
||||
curl
|
||||
libasound2-dev
|
||||
libfontconfig1-dev
|
||||
libfreetype6-dev
|
||||
libgl1-mesa-dev
|
||||
libjack-dev
|
||||
libmp3lame-dev
|
||||
libnss3-dev
|
||||
libportmidi-dev
|
||||
libpulse-dev
|
||||
libsndfile1-dev
|
||||
make
|
||||
portaudio19-dev
|
||||
wget
|
||||
)
|
||||
|
||||
# MuseScore compiles without these but won't run without them
|
||||
apt_packages_runtime=(
|
||||
# Alphabetical order please!
|
||||
libcups2
|
||||
libdbus-1-3
|
||||
libegl1-mesa-dev
|
||||
libodbc1
|
||||
libpq-dev
|
||||
libssl1.0.0
|
||||
libxcomposite-dev
|
||||
libxcursor-dev
|
||||
libxi-dev
|
||||
libxkbcommon-x11-0
|
||||
libxrandr2
|
||||
libxtst-dev
|
||||
)
|
||||
|
||||
apt-get update # no package lists in Docker image
|
||||
apt-get install -y --no-install-recommends \
|
||||
"${apt_packages_basic[@]}" \
|
||||
"${apt_packages_standard[@]}" \
|
||||
"${apt_packages_runtime[@]}"
|
||||
|
||||
##########################################################################
|
||||
# GET QT
|
||||
##########################################################################
|
||||
|
||||
# Get newer Qt (only used cached version if it is the same)
|
||||
qt_version="598"
|
||||
qt_dir="qt/${qt_version}"
|
||||
if [[ ! -d "${qt_dir}" ]]; then
|
||||
mkdir -p "${qt_dir}"
|
||||
qt_url="https://s3.amazonaws.com/utils.musescore.org/qt${qt_version}.zip"
|
||||
wget -q --show-progress -O qt5.zip "${qt_url}"
|
||||
unzip -qq qt5.zip -d "${qt_dir}"
|
||||
rm -f qt5.zip
|
||||
fi
|
||||
qt_path="${PWD%/}/${qt_dir}"
|
||||
|
||||
echo export PATH="${qt_path}/bin:\${PATH}" >> ${ENV_FILE}
|
||||
echo export LD_LIBRARY_PATH="${qt_path}/lib:\${LD_LIBRARY_PATH}" >> ${ENV_FILE}
|
||||
echo export QT_PATH="${qt_path}" >> ${ENV_FILE}
|
||||
echo export QT_PLUGIN_PATH="${qt_path}/plugins" >> ${ENV_FILE}
|
||||
echo export QML2_IMPORT_PATH="${qt_path}/qml" >> ${ENV_FILE}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# GET TOOLS
|
||||
##########################################################################
|
||||
|
||||
# COMPILER
|
||||
|
||||
gcc_version="7"
|
||||
apt-get install -y --no-install-recommends "g++-${gcc_version}"
|
||||
update-alternatives \
|
||||
--install /usr/bin/gcc gcc "/usr/bin/gcc-${gcc_version}" 40 \
|
||||
--slave /usr/bin/g++ g++ "/usr/bin/g++-${gcc_version}"
|
||||
|
||||
#apt-get install -y --no-install-recommends g++
|
||||
echo export CC="/usr/bin/gcc-${gcc_version}" >> ${ENV_FILE}
|
||||
echo export CXX="/usr/bin/g++-${gcc_version}" >> ${ENV_FILE}
|
||||
|
||||
gcc-${gcc_version} --version
|
||||
g++-${gcc_version} --version
|
||||
|
||||
# CMAKE
|
||||
# Get newer CMake (only used cached version if it is the same)
|
||||
cmake_version="3.16.0"
|
||||
cmake_dir="cmake/${cmake_version}"
|
||||
if [[ ! -d "${cmake_dir}" ]]; then
|
||||
mkdir -p "${cmake_dir}"
|
||||
cmake_url="https://cmake.org/files/v${cmake_version%.*}/cmake-${cmake_version}-Linux-x86_64.tar.gz"
|
||||
wget -q --show-progress --no-check-certificate -O - "${cmake_url}" \
|
||||
| tar --strip-components=1 -xz -C "${cmake_dir}"
|
||||
fi
|
||||
echo export PATH="${PWD%/}/${cmake_dir}/bin:\${PATH}" >> ${ENV_FILE}
|
||||
export PATH="${PWD%/}/${cmake_dir}/bin:${PATH}"
|
||||
cmake --version
|
||||
|
||||
# APPIMAGETOOL AND LINUXDEPLOY
|
||||
|
||||
function download_github_release()
|
||||
{
|
||||
local -r repo_slug="$1" release_tag="$2" file="$3"
|
||||
wget -q --show-progress "https://github.com/${repo_slug}/releases/download/${release_tag}/${file}"
|
||||
chmod +x "${file}"
|
||||
}
|
||||
|
||||
function extract_appimage()
|
||||
{
|
||||
# Extract AppImage so we can run it without having to install FUSE
|
||||
local -r appimage="$1" binary_name="$2"
|
||||
local -r appdir="${appimage%.AppImage}.AppDir"
|
||||
"./${appimage}" --appimage-extract >/dev/null # dest folder "squashfs-root"
|
||||
mv squashfs-root "${appdir}" # rename folder to avoid collisions
|
||||
ln -s "${appdir}/AppRun" "${binary_name}" # symlink for convenience
|
||||
rm -f "${appimage}"
|
||||
}
|
||||
|
||||
function download_appimage_release()
|
||||
{
|
||||
local -r github_repo_slug="$1" binary_name="$2" tag="$3"
|
||||
local -r appimage="${binary_name}-x86_64.AppImage"
|
||||
download_github_release "${github_repo_slug}" "${tag}" "${appimage}"
|
||||
extract_appimage "${appimage}" "${binary_name}"
|
||||
}
|
||||
|
||||
if [[ ! -d "appimagetool" ]]; then
|
||||
mkdir appimagetool
|
||||
cd appimagetool
|
||||
# `12` and not `continuous` because see https://github.com/AppImage/AppImageKit/issues/1060
|
||||
download_appimage_release AppImage/AppImageKit appimagetool 12
|
||||
cd ..
|
||||
fi
|
||||
echo export PATH="${PWD%/}/appimagetool:\${PATH}" >> ${ENV_FILE}
|
||||
export PATH="${PWD%/}/appimagetool:${PATH}"
|
||||
appimagetool --version
|
||||
|
||||
function download_linuxdeploy_component()
|
||||
{
|
||||
download_appimage_release "linuxdeploy/$1" "$1" continuous
|
||||
}
|
||||
|
||||
if [[ ! -d "linuxdeploy" ]]; then
|
||||
mkdir linuxdeploy
|
||||
cd linuxdeploy
|
||||
download_linuxdeploy_component linuxdeploy
|
||||
download_linuxdeploy_component linuxdeploy-plugin-qt
|
||||
cd ..
|
||||
fi
|
||||
echo export PATH="${PWD%/}/linuxdeploy:\${PATH}" >> ${ENV_FILE}
|
||||
export PATH="${PWD%/}/linuxdeploy:${PATH}"
|
||||
linuxdeploy --list-plugins
|
||||
|
||||
|
||||
##########################################################################
|
||||
# POST INSTALL
|
||||
##########################################################################
|
||||
|
||||
chmod +x "${ENV_FILE}"
|
||||
|
||||
# tidy up (reduce size of Docker image)
|
||||
apt-get clean autoclean
|
||||
apt-get autoremove --purge -y
|
||||
rm -rf /tmp/* /var/{cache,log,backups}/* /var/lib/apt/*
|
||||
|
||||
echo "All done!!"
|
||||
|
Loading…
Reference in a new issue