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

Build 32 bit AppImages (fix #95541 improvement) #2398

Merged
merged 1 commit into from Feb 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 20 additions & 5 deletions .travis.yml
Expand Up @@ -7,11 +7,15 @@ env:
- "ARTIFACTS_S3_BUCKET=vtest.musescore.org"
- secure: "lVj+9BBtJIjW3CwfXstvNyYVn0AkXEwTyiPmp4BprcheP78WIqZNC0uG2RjG9MgyHbZkprE7zRdqR9YPWTitg+XYkkD6+jPHRO+PQFLARuiTAX9yhUO53yQQZC2wMkQ#+bFuZsFmz1rfAsPHx3bXeZAMsz+Qnh8D2yIqqV7qxwWw="
- secure: "L+66yQZIZJTyIAfrG89ncKIkMAr4+UvaOZMsd420OSdnEH9kpdm5Kws8rG0VVLAtqhfQfi3K9DuC8Ub7IiXqil//h+I9WJ2LHKirWK0m/MkhTFC6hfi0uSnQCX/jud3Keewxf3ovgiKQvIw6VR37UC50YJM9+KhZKtsNYhGAdos="
# Branches for uploads of Linux nightly builds & stable release AppImages
- "APPIMAGE_UPLOAD_BRANCHES=\"master 2.0.3\""
# AppImages are built on all branches, but only uploaded on those listed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would make sense to not build if we don't upload no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it would! But the build has to start anyway to check which branch we are on so I thought it might as well continue. There are supposed to be ways to prevent the build from starting at all but I couldn't get them to work in a way that would satisfy our needs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of discarding the AppImages or trying to prevent the build from starting at all for PRs, I recommend that they be uploaded to a seperate PR repository, and have travis post links to issue tracker and to github PR, so other devs can easily test the PRs. Please reply to my feature request here: https://musescore.org/en/node/101496


matrix:
fast_finish: true
allow_failures:
- env: "JOB=AppImage"
- env: "JOB=AppImage_64bit"
- env: "JOB=AppImage_32bit"
include:
# 1st parallel build job - debug build on Ubuntu
- env: "JOB=Tests"
Expand Down Expand Up @@ -53,8 +57,8 @@ matrix:
- "./build/travis/job1_Tests/run_tests.sh"
after_script:
- 'ARTIFACTS_PATHS="$(ls vtest/html | tr "\n" ":")" artifacts upload'
# 2nd parallel build job - portable Linux AppImage build on CentOS
- env: "JOB=AppImage"
# 2nd parallel build job - portable Linux AppImage 64-bit build on CentOS
- env: "JOB=AppImage_64bit"
addons:
apt:
packages:
Expand All @@ -64,8 +68,19 @@ matrix:
services:
- docker
script:
- "./build/travis/job2_AppImage/build.sh --upload-branches master 2.0.3"
# AppImages are built on all branches, but only uploaded on those listed
- "./build/travis/job2_AppImage/build.sh --upload-branches $APPIMAGE_UPLOAD_BRANCHES"
# 3rd parallel build job - portable Linux AppImage 32-bit build on CentOS
- env: "JOB=AppImage_32bit"
addons:
apt:
packages:
- bsdtar
- curl
- zsync
services:
- docker
script:
- "./build/travis/job2_AppImage/build.sh --32bit --upload-branches $APPIMAGE_UPLOAD_BRANCHES"

notifications:
recipients:
Expand Down
29 changes: 10 additions & 19 deletions build/Linux+BSD/portable/Recipe
Expand Up @@ -54,20 +54,20 @@ cd "$(dirname "$(readlink -f "${0}")")/../../../.."

yum -y install epel-release

# basic dependencies (present on CentOS LiveCD ISO but needed by Docker image)
yum -y install wget which automake
# basic dependencies (needed by Docker image)
yum -y install git wget which automake

if [ "${OS}" == "CentOS 6" ]; then
# Get newer version of git than available by default
# Get newer compiler than available by default
wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo
yum install -y devtoolset-2-git
source /opt/rh/devtoolset-2/enable # enable the new version
yum -y install devtoolset-2-gcc devtoolset-2-gcc-c++ devtoolset-2-binutils
source /opt/rh/devtoolset-2/enable # enable new compiler
else
yum -y install git
yum -y install gcc gcc-c++ binutils
fi

# Build AppImageKit now to avoid conflicts with MuseScore's dependencies (LAME)
[ -d "AppImageKit" ] || git clone -b master --single-branch --depth 1 https://github.com/probonopd/AppImageKit.git
[ -d "AppImageKit" ] || git clone --depth 1 https://github.com/probonopd/AppImageKit.git
cd AppImageKit
./build.sh

Expand All @@ -78,26 +78,17 @@ cd ..
#wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo
yum -y install cmake mesa-libGL-devel pulseaudio-libs-devel alsa-lib-devel jack-audio-connection-kit-devel portaudio-devel libsndfile-devel libvorbis-devel qt5-qtbase-devel qt5-qttools-libs-designercomponents qt5-qttools-devel qt5-qtdeclarative-devel qt5-qtscript-devel qt5-qtwebkit-devel qt5-qtxmlpatterns-devel qt5-qtquick1-devel qt5-qtsvg-devel qt5-qttools-devel qt5-qttools-static qt5-qtmultimedia-devel qt5-qtwebchannel-devel qt5-qtimageformats qt5-qtquickcontrols

if [ "${OS}" == "CentOS 6" ]; then
# Get newer compiler than available by default
# wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo
yum -y install devtoolset-2-gcc devtoolset-2-gcc-c++ devtoolset-2-binutils
source /opt/rh/devtoolset-2/enable # enable new compiler
else
yum -y install gcc gcc-c++ binutils
fi

# Install LAME (get this dependency last because rpmforge and epel-release conflict)
wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
rpm -ivh rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm || true # don't fail if already installed
wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.$(arch).rpm
rpm -ivh rpmforge-release-0.5.3-1.el6.rf.$(arch).rpm || true # don't fail if already installed
yum -y install lame-devel

##########################################################################
# BUILD MUSESCORE
##########################################################################

# If not building on Travis then might need to fetch MuseScore
[ -d "MuseScore" ] || git clone -b portable-linux-build-on-travis --single-branch --depth 1 https://github.com/shoogle/MuseScore.git
[ -d "MuseScore" ] || git clone --depth 1 https://github.com/musescore/MuseScore.git

cd MuseScore
make revision
Expand Down
29 changes: 24 additions & 5 deletions build/Linux+BSD/portable/copy-libs
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash

# Usage: copy-libs $share_path

Expand All @@ -18,7 +18,15 @@ main() {

num_failures=0 # store number of libraries that couldn't be copied
getCrossPlatformDependencies
getLinuxOnlyDependencies

# get linux-specific dependencies, based on which distro is making the AppImage
if [ "$(grep "CentOS release 6" /etc/*release*)" ]; then
building_on_CentOS_6
else
echo "${0}: Warning: Not running on a supported build system!" >&2
# Try to fetch all dependencies, just in case
building_on_CentOS_6
fi

if [ "$num_failures" != "0" ]; then
echo "Error: $num_failures libraries couldn't be copied."
Expand Down Expand Up @@ -96,9 +104,10 @@ getCrossPlatformDependencies() {

##########################################################################
# LINUX-ONLY DEPENDENCIES (no equivalents in "mscore/CMakeLists.txt")
# Note: always check the oldest distribution first
# These differ depending on the distribution used to build the AppImage.
# Note: always check the oldest supported distribution first
##########################################################################
getLinuxOnlyDependencies() {
building_on_CentOS_6() {
# Needed by Centos 6.7:
dest_dir="$lib_dest"
copyLib libjack.so.0
Expand Down Expand Up @@ -128,7 +137,17 @@ getLinuxOnlyDependencies() {
}

locateLib() {
local path="$(ldconfig -p | grep "$1" | awk '{print $4}')"
# First search $LD_LIBRARY_PATH
declare -a dir_array
IFS=':' read -ra dir_array <<< "${LD_LIBRARY_PATH}"
for d in "${dir_array[@]}"; do
if [ -e "$d/$1" ]; then
echo "$d/$1"
return
fi
done
# If it wasn't found then search library cache
local path="$(ldconfig -p | awk '{print $4}' | grep "$1" | head -n1)"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dorinaaaaaaa

[ "$path" ] || echo "$1 not found." >&2
echo "$path"
}
Expand Down
12 changes: 6 additions & 6 deletions build/travis/job2_AppImage/bintray.sh
Expand Up @@ -60,13 +60,13 @@ FILE="$1"
# MUSESCORE NAMING SCHEME:
# File: MuseScore-X.Y.Z-<arch>.AppImage (e.g. MuseScore-2.0.3-x86_64)
# Version: X.Y.Z
# Package: MuseScore-Linux
# Package: MuseScore-Linux-<arch>
#
# NIGHTLY NAMING SCHEME:
# File: MuseScoreNightly-<datetime>-<branch>-<commit>-<arch>.AppImage
# (e.g. MuseScoreNightly-201601151332-master-f53w6dg-x86_64.AppImage)
# Version: <datetime>-<branch>-<commit> (e.g. 201601151332-master-f53w6dg)
# Package: MuseScoreNightly-<branch> (e.g. MuseScoreNightly-master)
# Package: MuseScoreNightly-<branch>-<arch> (e.g. MuseScoreNightly-master-x86_64)

# Read app name from file name (get characters before first dash)
APPNAME="$(basename "$FILE" | sed -r 's|^([^-]*)-.*$|\1|')"
Expand All @@ -93,12 +93,12 @@ case "${ARCH}" in
;;
esac

FILE_UPLOAD_PATH="$ARCH/$(basename "${FILE}")"
FILE_UPLOAD_PATH="$(basename "${FILE}")"

if [ "${APPNAME}" == "MuseScore" ]; then
# Upload a new version but don't publish it (invisible until published)
url_query="" # Don't publish, don't overwrite existing files with same name
PCK_NAME="$APPNAME-Linux"
PCK_NAME="$APPNAME-Linux-$ARCH"
BINTRAY_REPO="MuseScore"
LABELS="[\"music\", \"audio\", \"MIDI\", \"AppImage\"]"
elif [ "${APPNAME}" == "MuseScoreNightly" ]; then
Expand All @@ -108,7 +108,7 @@ elif [ "${APPNAME}" == "MuseScoreNightly" ]; then
# Get Git branch from $VERSION (get characters between first and last dash)
BRANCH="$(echo $VERSION | sed -r 's|^[^-]*-(.*)-[^-]*$|\1|')"

PCK_NAME="$APPNAME-$BRANCH"
PCK_NAME="$APPNAME-$BRANCH-$ARCH"
BINTRAY_REPO="nightlies-linux"
LABELS="[\"nightly\", \"unstable\", \"testing\"]"
else
Expand Down Expand Up @@ -150,7 +150,7 @@ if [ "${APPNAME}" == "MuseScore" ]; then
DESCRIPTION=$(bsdtar -f "${FILE}" -O -x ./"${DESKTOP}" | grep -e "^Comment=" | sed s/Comment=//g)
elif [ "${APPNAME}" == "MuseScoreNightly" ]; then
# Use custom description for nightly builds
DESCRIPTION="Automated builds of the $BRANCH development branch for Linux systems. FOR TESTING PURPOSES ONLY!"
DESCRIPTION="Automated builds of the $BRANCH development branch for $SYSTEM Linux systems. FOR TESTING PURPOSES ONLY!"
fi

ICONNAME=$(bsdtar -f "${FILE}" -O -x "${DESKTOP}" | grep -e "^Icon=" | sed s/Icon=//g)
Expand Down
22 changes: 19 additions & 3 deletions build/travis/job2_AppImage/build.sh
Expand Up @@ -4,6 +4,8 @@
# Build portable Linux AppImages and upload them to Bintray. AppImages will
# always be uploaded unless a list of specific branches is passed in. e.g.:
# $ build.sh --upload-branches master my-branch-1 my-branch-2
# Builds will be for the native architecture (64 bit) unless another is
# specified for cross-compiling. (e.g. build.sh --32bit)

set -e # exit on error
set -x # echo commands
Expand All @@ -27,17 +29,31 @@ else
makefile_overrides="" # use Makefile defaults
fi

# Build MuseScore AppImage inside Docker image
docker run -i -v "${PWD}:/MuseScore" library/centos:6 \
/bin/bash -c "/MuseScore/build/Linux+BSD/portable/Recipe $makefile_overrides"
# Build AppImage. Are we cross-compiling?
case "$1" in
--32bit )
shift
# Build MuseScore AppImage inside 32-bit Docker image
docker run -i -v "${PWD}:/MuseScore" toopher/centos-i386:centos6 /bin/bash -c \
"linux32 --32bit i386 /MuseScore/build/Linux+BSD/portable/Recipe $makefile_overrides"
;;
* )
[ "$1" == "--64bit" ] && shift || true
# Build MuseScore AppImage inside native (64-bit) Docker image
docker run -i -v "${PWD}:/MuseScore" library/centos:6 /bin/bash -c \
"/MuseScore/build/Linux+BSD/portable/Recipe $makefile_overrides"
;;
esac
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericfont If you want to cross-compile for ARM on Travis this is the place to do it. Add a new case --arm for the ARM-specific build command. You can then call it from .travis.yml like this: build.sh --arm (see how the 32 bit works). The best way to cross-compile is to enter a chroot so that you can avoid conflicts with the native system's libraries when you run copy-libs, which could otherwise end up fetching x86_64 libraries instead of ARM ones.

I haven't fully looked into this myself, but it looks like you need to install a static QEMU binary, and then enter the chroot somehow, possibly using AppImageKit or Docker. There are a few ARM-based Docker images:
Search for "rpi" or "arm" here: https://hub.docker.com
Or here's an Arch linux image: https://hub.docker.com/r/cellofellow/rpi-arch/

I'm not sure if it will work with Docker, but here's how another guy did something similar.

Or I may have a look into this myself at some point if you don't fancy it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to look into it. I did read that running-travis-ci-tests-on-arm article last week.

(I've used QEMU ~10 years ago...I've yet to use docker but am at least familiar with it.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool.
I had to make some changes to copy-libs for this PR so I ended up including all of the changes we discussed on your branch, except for the ^processor change to the Makefile because I felt that belongs in the ARM PR so we know why it's there when reviewing the code a few years from now. You basically just need to make that change and add your Jessie (or eqivalent) function to copy-libs and update the dependency section of the Recipe for your target distribution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericfont Keep an eye on this issue for AppImageKit where RazZziel has succeeded in building AppImages for ARM on Travis. He's building on the feature/32bit_builds_docker branch. Build logs are here. He only had to change .travis.yml to make ARM builds work for AppImageKit (MuseScore will probably be a bit harder because you'll have to find the dependencies for the OS you choose).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent! I am going to get back on that right with I finish with this current crash issue.

I was at the point where I was going to use these debian wheezy docker images (https://github.com/multiarch/debian-debootstrap) instead of the raspbian wheezy for a few reasons: (1) Raspbian image is unecesarily larger (2) Raspbian might contain some specific RPi stuff, (3) I discovered that I no longer see a raspbian wheezy image on raspberry website, and (4) I want to consider possibly doing armv7 and armv8 (which is 64-bit) in addition to armv6 (which is the only architecture that raspbian is compiled for) and (5) incase there are any other random architectures now in the future, plain debian will support them all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@probonopd In https://github.com/probonopd/AppImageKit/blob/master/README.md#objectives line 8 you write:

Do not require recompilation. AppImages must be possible to create from already-existing binaries, without the need for recompilation. This greatly speeds up the AppImage creation process, since no compiler has to be involved. This also allows third parties to package closed-source applications as AppImages. (Nevertheless, it can be beneficial for upstream application developers to build from source specifically for the purpose of generating an AppImage.)

That leads me to think that yes, I can use crosscompiler to build musescore, and then just package the AppImage inside an ARM container (so gets the ARM libraries).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be possible, but would create a lot of extra work I think. The libraries need to be present during the build as well as at runtime, so you would end up having to maintain two sets of dependencies. Also, you'd have to get the two versions to match exactly, which may not be possible if the Docker image is a different distro to Travis. Finally, I'm not sure if cross-compiling will be any faster than building in QEMU, but I don't know this for sure.

I'd recommend just trying the QEMU option first, as it appears to be the easiest, and just see how long it takes. If it takes too long then we can follow @probonopd's example of creating our own custom Docker image to save having to fetch dependencies. If it's still too long after that then we can look into cross-compiling.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok...long story, but I'm holding off on what I would call "native cross compiler" (i.e. the cross compiler is x86-64 running on the Travis x86-64 ubuntu 12.04 using the linaro cross compiler to build arm) which I argue would use much less cpu resources than an emulated arm compiler. I was going to use an exactly equivalent armv7 ubuntu 12.04.05 docker image, to make sure all the libraries correspond to each other...anyway I stopped at the point where I would have to extract all the libraries out of the docker file and put in travis (fyi, I was setting up a cmake toolchain file where I would have needed to provide a root directory of the arm system)... And so maybe, yeah, that is more complicated then just building inside qemu docker image.

So I'm at the point now where I went through that resin.io blog on my own computer. Note that their prebuilt docker files with qemu are actually using Debian Jessie, but it was no problem to fork their Dockerfile and make a docker image w/qemu for Debian Wheezy: https://hub.docker.com/r/ericfont/armv7hf-debian-qemu/~/dockerfile/

So then I used that image as base for one that includes all the musescore dependencies (including qt5 debug symbols, and including compiling AppImageKit) here: https://github.com/ericfont/armv7hf-debian-qemu-musescore-dependencies/blob/master/Dockerfile

I know you said to not worry about pre-creating the docker image, but I think it is very important to do so, because setting up the docker file will use up travis alloted time. That build should be going on now...https://hub.docker.com/r/ericfont/armv7hf-debian-qemu-musescore-dependencies/builds/

Note that that image is useing qt5.3.2 from debian wheezy backports, but I intended to setup the dockerfile to compile the latest qt version from http://download.qt.io/official_releases/qt/5.5/5.5.1/single/qt-everywhere-opensource-src-5.5.1.tar.gz and then only update that docker image when a new qt version comes out. I think I can setup the docker file to do the qt building, so I just need to update the qt version number and do a commit & push to my github.

I'll check back in a few hours.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I have compiled AppImageKit, compile a HelloWorld, and run using AppRun: https://hub.docker.com/r/ericfont/armv7hf-debian-qemu-appimagekit/builds/bnywuskzyttfjagcp6o6at5/

But note that anything cpu intensive is much much slower when running in emulated qemu-arm. I'm think the qemu will be fine for running musescore travis tests and for packaging the AppImage. However, I'm certain now that compilng musescore inside of qemu-arm is not feasable. I'm going to investigate running x86-64 -> arm cross compiler inside travis...so the next step is to use a root filesystem from http://www.armhf.com/download/ for ubuntu 12.04 arm and using that for the cmake toolchain file root directory of arm system (after putting all the musescore dependencies there). Then hopefully would have equivalent libraries to the ubuntu 12.04 x86-64 travis image.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! If ARM builds take ages then we needn't necessarily compile one on each commit, and it could be done on Docker Hub rather Travis if there's no time limit on Docker Hub. (Or maybe Travis could even be set up to trigger a build on Docker Hub?)


# Should the AppImage be uploaded?
if [ "$1" == "--upload-branches" ]; then
# User passed in list of branchs so only upload those listed
shift
for upload_branch in "$@" ; do
[ "$branch" == "$upload_branch" ] && upload=true || true # bypass `set -e`
done
else
# No list passed in so upload on every branch
upload=true
fi

Expand Down