From 8ec39c1ff8124538d046789eff212f8397192a52 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Wed, 5 Dec 2018 21:47:41 +0100 Subject: [PATCH] ARM builds (#699) Build for armhf and aarch64 architectures (ARM 32 bit and ARM 64 bit). Thanks @TheAssassin --- .travis.yml | 31 ++++++++++++--- build-appdir.sh | 8 +++- build.sh | 11 +++++- cmake/dependencies.cmake | 4 +- cmake/toolchains/aarch64-linux-gnu.cmake | 20 ++++++++++ cmake/toolchains/arm-linux-gnueabihf.cmake | 20 ++++++++++ lib/libappimage | 2 +- src/CMakeLists.txt | 45 ++++++++++++++-------- src/build-runtime.cmake | 8 ++-- src/embed-magic-bytes-in-file.sh | 8 ++++ travis/build-appimage.sh | 2 +- travis/build-binaries.sh | 3 ++ travis/test-appimage.sh | 0 travis/travis-build.sh | 7 ++-- 14 files changed, 135 insertions(+), 34 deletions(-) create mode 100644 cmake/toolchains/aarch64-linux-gnu.cmake create mode 100644 cmake/toolchains/arm-linux-gnueabihf.cmake create mode 100755 src/embed-magic-bytes-in-file.sh mode change 100644 => 100755 travis/build-appimage.sh mode change 100644 => 100755 travis/build-binaries.sh mode change 100644 => 100755 travis/test-appimage.sh mode change 100644 => 100755 travis/travis-build.sh diff --git a/.travis.yml b/.travis.yml index 53d4ae62b..7cc9b7802 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,31 @@ language: c -compiler: gcc +sudo: required services: - docker -env: - - ARCH=x86_64 DOCKER_IMAGE=quay.io/appimage/appimagebuild - - ARCH=i686 DOCKER_IMAGE=quay.io/appimage/appimagebuild-i386 +matrix: + include: + - env: ARCH=x86_64 DOCKER_IMAGE=quay.io/appimage/appimagebuild + - env: ARCH=i686 DOCKER_IMAGE=quay.io/appimage/appimagebuild-i386 + - env: ARCH=armhf DOCKER_IMAGE=quay.io/appimage/appimagebuild-armhf-cross + addons: + apt: + update: true + packages: + # install binfmt support system-wide (for use in Docker containers) + - binfmt-support + # sets up the required binfmt interpreters so that qemu will actually be used (for use in Docker containers) + - qemu-user-static + - env: ARCH=aarch64 DOCKER_IMAGE=quay.io/appimage/appimagebuild-aarch64-cross + addons: + apt: + update: true + packages: + # install binfmt support system-wide (for use in Docker containers) + - binfmt-support + # sets up the required binfmt interpreters so that qemu will actually be used (for use in Docker containers) + - qemu-user-static script: - bash travis/travis-build.sh @@ -16,6 +35,8 @@ after_success: - ls -lh out/* # <= wrong line: see https://travis-ci.org/AppImage/AppImageKit/jobs/347965050#L4211 - ls -lh build/out/* - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh + # make sure only pushes to rewrite create a new release, otherwise pretend PR and upload to transfer.sh + - if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" != "appimagetool/master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi - bash ./upload.sh build/out/* notifications: @@ -24,7 +45,7 @@ notifications: - "chat.freenode.net#AppImage" on_success: always # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always - on_start: always # options: [always|never|change] default: always + on_start: always # options: [always|never|change] default: always template: - "%{repository} build %{build_number}: %{result} %{build_url}" use_notice: true diff --git a/build-appdir.sh b/build-appdir.sh index 6291a3419..51cce0dd9 100644 --- a/build-appdir.sh +++ b/build-appdir.sh @@ -20,6 +20,8 @@ mkdir -p "$APPIMAGETOOL_APPDIR"/usr/lib/appimagekit/ # Copy AppDir specific files cp ../resources/AppRun "$APPIMAGETOOL_APPDIR" cp install_prefix/usr/lib/appimagekit/mksquashfs "$APPIMAGETOOL_APPDIR"/usr/lib/appimagekit/ +# prefer binaries from /deps, if available +export PATH=/deps/bin:"$PATH" cp $(which desktop-file-validate) "$APPIMAGETOOL_APPDIR"/usr/bin/ cp $(which zsyncmake) "$APPIMAGETOOL_APPDIR"/usr/bin/ @@ -36,7 +38,11 @@ if [ -d /deps/ ]; then # https://mail.gnome.org/archives/gtk-devel-list/2012-July/msg00062.html if [ "$ARCH" == "x86_64" ]; then cp /usr/lib64/libffi.so.5 "$APPIMAGETOOL_APPDIR"/usr/lib/ - else + elif [ "$ARCH" == "i686" ]; then cp /usr/lib/libffi.so.5 "$APPIMAGETOOL_APPDIR"/usr/lib/ + elif [ "$ARCH" == "armhf" ] || [ "$ARCH" == "aarch64" ]; then + cp /deps/lib/libffi.so.6 "$APPIMAGETOOL_APPDIR"/usr/lib/ + else + echo "WARNING: unknown architecture, not bundling libffi" fi fi diff --git a/build.sh b/build.sh index 315b10c0a..b69e99ab0 100755 --- a/build.sh +++ b/build.sh @@ -72,7 +72,16 @@ cd build # make sure that deps in separate install tree are found export PKG_CONFIG_PATH=/deps/lib/pkgconfig/ -cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DAPPIMAGEKIT_PACKAGE_DEBS=ON +# make CMake use the right tools for ARM cross-compiling using toolchain file +if [ "$ARCH" == "armhf" ]; then + export PATH=/deps/bin:"$PATH" + export EXTRA_CMAKE_FLAGS="-DCMAKE_TOOLCHAIN_FILE=$HERE/cmake/toolchains/arm-linux-gnueabihf.cmake" +elif [ "$ARCH" == "aarch64" ]; then + export PATH=/deps/bin:"$PATH" + export EXTRA_CMAKE_FLAGS="-DCMAKE_TOOLCHAIN_FILE=$HERE/cmake/toolchains/aarch64-linux-gnu.cmake" +fi + +cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DAPPIMAGEKIT_PACKAGE_DEBS=ON "${EXTRA_CMAKE_FLAGS[@]}" make -j$JOBS make install DESTDIR=install_prefix/ diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index d702f96dd..9f7901f00 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -8,8 +8,10 @@ include(${PROJECT_SOURCE_DIR}/lib/libappimage/cmake/scripts.cmake) # the names of the targets need to differ from the library filenames # this is especially an issue with libcairo, where the library is called libcairo # therefore, all libs imported this way have been prefixed with lib -import_pkgconfig_target(TARGET_NAME libssl PKGCONFIG_TARGET openssl) import_pkgconfig_target(TARGET_NAME libfuse PKGCONFIG_TARGET fuse) +# openssl is required for optional tools only, and doesn't need to be enforced +# FIXME: remove dependency to openssl by implementing own SHA hashes in libappimage_hashlib +import_pkgconfig_target(TARGET_NAME libssl PKGCONFIG_TARGET openssl OPTIONAL) if(USE_CCACHE) diff --git a/cmake/toolchains/aarch64-linux-gnu.cmake b/cmake/toolchains/aarch64-linux-gnu.cmake new file mode 100644 index 000000000..4b35337c3 --- /dev/null +++ b/cmake/toolchains/aarch64-linux-gnu.cmake @@ -0,0 +1,20 @@ +# toolchain file that can be used for cross-compiling AppImageKit using the respective AppImageBuild container + +set(CMAKE_SYSTEM_NAME Linux CACHE STRING "" FORCE) +set(CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "" FORCE) + +set(triple aarch64-linux-gnu CACHE STRING "" FORCE) + +set(CMAKE_C_COMPILER "${triple}-gcc" CACHE STRING "" FORCE) +set(CMAKE_CXX_COMPILER "${triple}-g++" CACHE STRING "" FORCE) + +set(TOOLS_PREFIX "${triple}-" CACHE STRING "" FORCE) + +set(DEPENDENCIES_CFLAGS "-I/deps/include" CACHE STRING "" FORCE) +set(DEPENDENCIES_CPPFLAGS "${DEPENDENCIES_CFLAGS}" CACHE STRING "" FORCE) +set(DEPENDENCIES_LDFLAGS "-L/deps/lib/" CACHE STRING "" FORCE) + +# host = target system +# build = build system +# both must be specified +set(EXTRA_CONFIGURE_FLAGS "--host=${triple}" "--build=x86_64-pc-linux-gnu" "--target=${triple}" CACHE STRING "" FORCE) diff --git a/cmake/toolchains/arm-linux-gnueabihf.cmake b/cmake/toolchains/arm-linux-gnueabihf.cmake new file mode 100644 index 000000000..6c755e66e --- /dev/null +++ b/cmake/toolchains/arm-linux-gnueabihf.cmake @@ -0,0 +1,20 @@ +# toolchain file that can be used for cross-compiling AppImageKit using the respective AppImageBuild container + +set(CMAKE_SYSTEM_NAME Linux CACHE STRING "" FORCE) +set(CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "" FORCE) + +set(triple arm-linux-gnueabihf CACHE STRING "" FORCE) + +set(CMAKE_C_COMPILER "${triple}-gcc" CACHE STRING "" FORCE) +set(CMAKE_CXX_COMPILER "${triple}-g++" CACHE STRING "" FORCE) + +set(TOOLS_PREFIX "${triple}-" CACHE STRING "" FORCE) + +set(DEPENDENCIES_CFLAGS "-I/deps/include" CACHE STRING "" FORCE) +set(DEPENDENCIES_CPPFLAGS "${DEPENDENCIES_CFLAGS}" CACHE STRING "" FORCE) +set(DEPENDENCIES_LDFLAGS "-L/deps/lib/" CACHE STRING "" FORCE) + +# host = target system +# build = build system +# both must be specified +set(EXTRA_CONFIGURE_FLAGS "--host=${triple}" "--build=x86_64-pc-linux-gnu" "--target=${triple}" CACHE STRING "" FORCE) diff --git a/lib/libappimage b/lib/libappimage index 8b3969667..1a99ca0c8 160000 --- a/lib/libappimage +++ b/lib/libappimage @@ -1 +1 @@ -Subproject commit 8b3969667004659f0033c71556a161bca3d60690 +Subproject commit 1a99ca0c8fa67307502e2cd3ffb6a77352f92db8 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 622d9a344..85a9c0b39 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,28 +73,32 @@ target_compile_definitions(AppRun add_sanitizers(AppRun) -add_executable(validate validate.c) +if (NOT TARGET libssl) + message(WARNING "Could not find suitable libssl, skipping build of validate and digest") +else() + add_executable(validate validate.c) -target_link_libraries(validate - libappimage_shared - libglib - libssl -) + target_link_libraries(validate + libappimage_shared + libglib + libssl + ) -target_include_directories(validate - PUBLIC $ - INTERFACE $ + INTERFACE $ ${CMAKE_CURRENT_BINARY_DIR}/16_blank_bytes + COMMAND dd if=/dev/zero bs=1 count=16 of=${CMAKE_CURRENT_BINARY_DIR}/16_blank_bytes ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes - COMMAND printf '\\0%.0s' {0..1023} > ${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes + COMMAND dd if=/dev/zero bs=1 count=1024 of=${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/8192_blank_bytes - COMMAND printf '\\0%.0s' {0..8191} > ${CMAKE_CURRENT_BINARY_DIR}/8192_blank_bytes + COMMAND dd if=/dev/zero bs=1 count=8192 of=${CMAKE_CURRENT_BINARY_DIR}/8192_blank_bytes ) # compile first raw object (not linked yet) into which the sections will be embedded @@ -127,7 +127,7 @@ if(APPIMAGEKIT_EMBED_MAGIC_BYTES) add_custom_command( TARGET runtime POST_BUILD - COMMAND printf '\\x41\\x49\\x02' | dd of=runtime bs=1 seek=8 count=3 conv=notrunc + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/embed-magic-bytes-in-file.sh ${CMAKE_CURRENT_BINARY_DIR}/runtime ) endif() diff --git a/src/embed-magic-bytes-in-file.sh b/src/embed-magic-bytes-in-file.sh new file mode 100755 index 000000000..23a8a97a4 --- /dev/null +++ b/src/embed-magic-bytes-in-file.sh @@ -0,0 +1,8 @@ +#! /bin/bash + +if [ "$1" == "" ]; then + echo "Usage: bash $0 " + exit 2 +fi + +echo -ne 'AI\x02' | dd of="$1" bs=1 count=3 seek=8 conv=notrunc diff --git a/travis/build-appimage.sh b/travis/build-appimage.sh old mode 100644 new mode 100755 index 5ec704cdc..6b6b05cfa --- a/travis/build-appimage.sh +++ b/travis/build-appimage.sh @@ -8,4 +8,4 @@ cd out/ ./appimagetool.AppDir/AppRun ./appimagetool.AppDir/ -s -v \ -u "gh-releases-zsync|AppImage|AppImageKit|continuous|appimagetool-$ARCH.AppImage.zsync" \ - appimagetool-"$ARCH".AppImage || true + appimagetool-"$ARCH".AppImage diff --git a/travis/build-binaries.sh b/travis/build-binaries.sh old mode 100644 new mode 100755 index 75c722780..3292291f5 --- a/travis/build-binaries.sh +++ b/travis/build-binaries.sh @@ -7,4 +7,7 @@ cd /AppImageKit ./build.sh "$@" +# make sure the prebuilt libraries in the container will be found +export LD_LIBRARY_PATH=/deps/lib:"$LD_LIBRARY_PATH" + ./test-appimagetool.sh build/install_prefix/usr/bin/appimagetool diff --git a/travis/test-appimage.sh b/travis/test-appimage.sh old mode 100644 new mode 100755 diff --git a/travis/travis-build.sh b/travis/travis-build.sh old mode 100644 new mode 100755 index 76bc37429..3c0e4749c --- a/travis/travis-build.sh +++ b/travis/travis-build.sh @@ -57,7 +57,7 @@ cd build/ # test AppImages [ "$ARCH" == "i686" ] && sudo apt-get update && sudo apt-get install -y gcc-multilib lib32z1 libfuse2 libfuse2:i386 libglib2.0-0:i386 libcairo2:i386 -bash -x ../travis/test-appimage.sh +[ "$ARCH" != "armhf" ] && [ "$ARCH" != "aarch64" ] && bash -x ../travis/test-appimage.sh # install more tools # (vim-common contains xxd) @@ -68,10 +68,11 @@ sudo chown -R travis.travis . # remove binaries from output directory ls -al out/ -rm -r out/{appimagetool,validate,digest,mksquashfs,*.AppDir} +rm -r out/{appimagetool,mksquashfs,*.AppDir} +rm -r out/{validate,digest} || true # inspect runtime -xxd out/runtime | head -n 1 +xxd out/runtime | head -n 1 | grep "4149 0200" # fix filename for upload mv out/runtime out/runtime-"$ARCH"