AppImage / AppImage/AppImageKit

Make AppImageKit more cross-compile friendly

Ouverte
#789 27 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Aucune donnée de langage
Étoiles
9.4k
Forks
588
Métriques de merge des PR
Métriques de PR en attente

Description

I want to cross-compile my program to several architectures (e.g. i386, x86_64, armel, armhf, etc.) and publish each as an AppImage. Besides cross-compiling my own application, I found that AppImageKit itself needs to be cross-compiled for each architecture in order to create the AppImage bundles for them. However, it has proven to be rather challenging to cross-compile AppImageKit.

`src/build-runtime.sh.in` and `cmake/dependencies.cmake` are the biggest cross-compilation offenders here.

- `src/build-runtime.sh.in` assumes that the build is made using system's native toolchain, it uses `gcc`, `strip`, `readelf`, `ld`, etc. without any way to specify the triplet prefix.
- `cmake/dependencies.cmake` builds dependencies not found on the system without ability to set `--host=` configure's argument, which results in the build failure when cross-compiling.

Here are full examples of how I have patched AppImageKit when cross-compiling it to armel and i386 on an x86_64 machine, so that you could see what I'm talking about and be able to reproduce:

### armel

```
sudo docker run --rm -it debian:stretch-slim /bin/bash

dpkg --add-architecture armel
apt-get update
apt-get install -y --no-install-recommends ca-certificates libgtest-dev:armel git ca-certificates make libarchive-dev:armel automake autoconf libtool make gcc g++ libfuse-dev:armel liblzma-dev:armel libglib2.0-dev:armel libssl-dev:armel libinotifytools0-dev:armel liblz4-dev:armel libcairo-dev:armel desktop-file-utils cmake patch wget xxd patchelf

apt-get install -y --no-install-recommends binutils-arm-linux-gnueabi gcc-arm-linux-gnueabi g++-arm-linux-gnueabi

echo "
SET(CMAKE_SYSTEM_NAME Linux)

SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++)
SET(CMAKE_AR /usr/bin/arm-linux-gnueabi-gcc-ar CACHE FILEPATH "Archiver")

SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
" > /usr/local/share/toolchain.cmake

cd /usr/src/gtest
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/toolchain.cmake .
make install
cd -

# Make AppImageKit pick up liblzma.a instead of liblzma.so by hiding liblzma.so
mv /usr/lib/arm-linux-gnueabi/liblzma.so /usr/lib/arm-linux-gnueabi/foo-liblzma.so

git clone --recursive https://github.com/AppImage/AppImageKit
cd AppImageKit
git checkout c0ff6f738a65bfa890d5286d81d97754167237ea
# The broken stuff
sed -i 's|/configure |/configure --host=arm-linux-gnueabi |' cmake/dependencies.cmake
sed -i 's|gcc|/usr/bin/arm-linux-gnueabi-gcc|' src/build-runtime.sh.in
sed -i 's|ld |/usr/bin/arm-linux-gnueabi-ld |' src/build-runtime.sh.in
sed -i 's|objcopy |/usr/bin/arm-linux-gnueabi-objcopy |' src/build-runtime.sh.in
sed -i 's|readelf |/usr/bin/arm-linux-gnueabi-readelf |' src/build-runtime.sh.in
sed -i 's|strip|/usr/bin/arm-linux-gnueabi-strip|' src/build-runtime.sh.in
sed -i 's|objdump |/usr/bin/arm-linux-gnueabi-objdump |' src/build-runtime.sh.in
mkdir build
cd build
# Don't mind the pkg-config command, this is not broken, that's the proper way to do it
export PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabi/pkgconfig:/usr/share/pkgconfig
cmake -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_TESTING=OFF -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/toolchain.cmake -DUSE_SYSTEM_XZ=ON -DUSE_SYSTEM_INOTIFY_TOOLS=ON -DUSE_SYSTEM_LIBARCHIVE=ON -DUSE_SYSTEM_GTEST=ON ..
make VERBOSE=1
make install

# Restore it back
mv /usr/lib/arm-linux-gnueabi/foo-liblzma.so /usr/lib/arm-linux-gnueabi/liblzma.so
```

### i386

```
sudo docker run --rm -it debian:stretch-slim /bin/bash

dpkg --add-architecture i386
apt-get update
apt-get install -y --no-install-recommends ca-certificates git lib32z1-dev libgtest-dev:i386 gcc-multilib g++-multilib libarchive-dev:i386 automake autoconf libtool make gcc g++ libfuse-dev:i386 liblzma-dev:i386 libglib2.0-dev:i386 libssl-dev:i386 libinotifytools0-dev:i386 liblz4-dev:i386 libcairo-dev:i386 desktop-file-utils cmake patch wget xxd patchelf

# There is no i386 cross-toolchain, you are supposed to use the multilib support for it, so let's create mock toolchain

echo '
#!/bin/sh
/usr/bin/x86_64-linux-gnu-gcc -m32 "$@"
' > /usr/bin/i386-linux-gnu-gcc
chmod +x /usr/bin/i386-linux-gnu-gcc

echo '
#!/bin/sh
/usr/bin/x86_64-linux-gnu-g++ -m32 "$@"
' > /usr/bin/i386-linux-gnu-g++
chmod +x /usr/bin/i386-linux-gnu-g++

echo '
#!/bin/sh
/usr/bin/x86_64-linux-gnu-ar "$@"
' > /usr/bin/i386-linux-gnu-ar
chmod +x /usr/bin/i386-linux-gnu-ar

echo "
SET(CMAKE_SYSTEM_NAME Linux)

SET(CMAKE_C_COMPILER /usr/bin/i386-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /usr/bin/i386-linux-gnu-g++)
SET(CMAKE_AR /usr/bin/i386-linux-gnu-ar CACHE FILEPATH "Archiver")

SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
" > /usr/local/share/toolchain.cmake

cd /usr/src/gtest
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/toolchain.cmake .
make install
cd -

git clone --recursive https://github.com/AppImage/AppImageKit
cd AppImageKit
git checkout c0ff6f738a65bfa890d5286d81d97754167237ea
# The broken stuff
sed -i 's|gcc|/usr/bin/i386-linux-gnu-gcc|' src/build-runtime.sh.in
sed -i 's|ld |ld -m elf_i386 |' src/build-runtime.sh.in
mkdir build
cd build
# Don't mind the pkg-config command, this is not broken, that's the proper way to do it
export PKG_CONFIG_LIBDIR=/usr/lib/i386-linux-gnu/pkgconfig:/usr/share/pkgconfig
cmake -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_TESTING=OFF -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/toolchain.cmake -DUSE_SYSTEM_XZ=ON -DUSE_SYSTEM_INOTIFY_TOOLS=ON -DUSE_SYSTEM_LIBARCHIVE=ON -DUSE_SYSTEM_GTEST=ON ..
make VERBOSE=1
make install
```

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.