AppImage / AppImage/AppImageKit

Make AppImageKit more cross-compile friendly

Abierto
#789 27 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Sin datos de lenguaje
Estrellas
9.4k
Forks
588
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.