Crosscompiler/Applications

From Segfault
Jump to navigation Jump to search

Tor

To build Tor for a different platform[1], we have to build its dependencies too.

Adjust as needed:

export PATH=/opt/ctng/tools/powerpc-unknown-linux-gnu/bin:$PATH

Build openssl:

git clone https://github.com/openssl/openssl.git openssl-git
cd openssl-git

Hint: use a stable release:

git checkout OpenSSL_1_0_2-stable

./Configure --prefix=/opt/openssl-powerpc --cross-compile-prefix=powerpc-unknown-linux-gnu- -fPIC linux-ppc

make
sudo PATH=/opt/ctng/tools/powerpc-unknown-linux-gnu/bin:$PATH make install                   # Adjust as needed

Build libevent:

git clone https://github.com/libevent/libevent.git libevent-git
cd libevent-git
./autogen.sh

CFLAGS="-I/opt/openssl-powerpc/include -fPIC" LDFLAGS="-L/opt/openssl-powerpc/lib" LIBS="-ldl" \
./configure --prefix=/opt/libevent-powerpc --host=powerpc-unknown-linux-gnu --disable-libevent-regress

make
sudo PATH=/opt/ctng/tools/powerpc-unknown-linux-gnu/bin:$PATH make install                   # Adjust as needed

Build zlib:

git clone https://github.com/madler/zlib.git zlib-git
cd zlib-git
CFLAGS="-fPIC" CHOST=powerpc-unknown-linux-gnu ./configure --prefix=/opt/zlib-powerpc

make
sudo make install

Note: we build our libraries with -fPIC[2], otherwise we'd get the following error later on:

$ LD_LIBRARY_PATH=/opt/libevent-powerpc/lib /opt/tor-powerpc/bin/tor --version
/opt/tor-powerpc/bin/tor: error while loading shared libraries: R_PPC_REL24 relocation at 0x207ff1a8 for symbol `time' out of range

And finally, build tor itself:

git clone https://git.torproject.org/tor.git tor-git
cd tor-git
./autogen.sh
./configure --host=powerpc-unknown-linux-gnu --prefix=/opt/tor-powerpc --enable-gcc-warnings \
   --enable-gcc-hardening --enable-linker-hardening --with-libevent-dir=/opt/libevent-powerpc \
   --with-zlib-dir=/opt/zlib-powerpc --with-openssl-dir=/opt/openssl-powerpc \
   --includedir=/opt/openssl-powerpc/include/ --disable-tool-name-check

Remove the enable-gcc-warnings option if compilation fails (and send a bug report!)

# Workaround for:
# redundant redeclaration of 'SSL_get_selected_srtp_profile'
sudo sed 's|.*openssl\/srtp.h.*|//&|' -i.bak /opt/openssl-powerpc/include/openssl/ssl.h
make
sudo make install

Transfer the libraries and tor our target host:

(cd /opt && tar -czf - *-powerpc) | ssh root@host "cd /opt && tar -xvzf - && ln -fs tor-powerpc tor"

Start with:

sudo -u tor LD_LIBRARY_PATH=/opt/libevent-powerpc/lib /opt/tor/bin/tor -f /usr/local/etc/torrc

Samba 4

Trying to cross-compile Samba 4 for AArch64, on a Debian x86-64 system, we needed to build python first[3]. But not a current version, but Python2:

wget https://www.python.org/ftp/python/2.7.14/Python-2.7.14.tar.xz{,.asc}
gpg --verify Python-2.7.14.tar.xz.asc
tar -xJf Python-2.7.14.tar.xz && cd Python-2.7.14/

Create a configuration[4] too:

$ cat config.site 
ac_cv_file__dev_ptmx=no
ac_cv_file__dev_ptc=no

Build (and explicitly enable IPv6[5]):

CONFIG_SITE=config.site ./configure --host=aarch64-linux-gnu --build=aarch64 --prefix=/opt/python2 --enable-ipv6
make && sudo make install

Now we can prepare the Samba 4 build:

sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross qemu-system-arm qemu-user python2.7 libacl1-dev libpam-dev libssl-dev python2.7-dev

Clone the repository:

git clone https://github.com/samba-team/samba.git samba-git                              # Cloning from git.samba.org was just too slow :-\
cd samba-git

That was the easy part. The tricky part is to get Samba 4 to compile with virtually no official documentation in place.[6][7] Let's try this, with the correct options[8] applied:

export PYTHONPATH=/opt/python2/lib/
export PYTHON_CONFIG="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/ /opt/python2/bin/python2 /opt/python2/bin/python-config"

Note: PYTHON_CONFIG only needs to be set if --disable-python is not yet available![9]

CC=aarch64-linux-gnu-gcc buildtools/bin/waf configure --prefix=/opt/sambax --disable-python --without-ad-dc --without-ads --without-ldap --cross-compile \
   --cross-execute="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/"

Note: the --disable-python option is only available since Samba 4.6.9![9]

This completes in under one minute on a fast machine. But then the build breaks:

CC=aarch64-linux-gnu-gcc buildtools/bin/waf build --cross-compile \
   --cross-execute="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/"

Waf: Entering directory `/usr/local/src/samba-git/bin'
       Selected embedded Heimdal build
[ 222/3107] Compiling ASN1 source4/heimdal/lib/asn1/kx509.asn1
[ 223/3107] Compiling ASN1 source4/heimdal/lib/asn1/digest.asn1
/bin/sh: 1: /usr/local/src/samba-git/bin/asn1_compile: Exec format error
/bin/sh: 1: /usr/local/src/samba-git/bin/asn1_compile: Exec format error
Waf: Leaving directory `/usr/local/src/samba-git/bin'
Build failed:
 -> task failed (err #2): 
        {task: HEIMDAL_KX509_ASN1_ASN1 kx509.asn1 -> asn1_kx509_asn1.x,kx509_asn1.hx,kx509_asn1-priv.hx}
 -> task failed (err #2): 
        {task: HEIMDAL_DIGEST_ASN1_ASN1 digest.asn1 -> asn1_digest_asn1.x,digest_asn1.hx,digest_asn1-priv.hx} 

For some reason the asn1_compile is called directly, w/o going through qemu-aarch64[10] :-\

Workarounds

After installing a wrapper for asn1_compile (and compile_et) and applying two fixes[11][12], we were able to compile Samba 4, albeit without PAM[13][14] and without ACL support:

CC=aarch64-linux-gnu-gcc buildtools/bin/waf configure --prefix=/opt/sambax --disable-python --without-ad-dc --without-ads --without-ldap \
   --without-acl-support --without-pam --cross-compile \
   --cross-execute="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/"
 CC=aarch64-linux-gnu-gcc buildtools/bin/waf build --cross-compile \
   --cross-execute="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/"

This will then break of course, and we have to install two wrappers:

$ ls -go bin/*compile*
lrwxrwxrwx 1 71 Jan  6 08:56 bin/asn1_compile -> /usr/local/src/samba-git/bin/default/source4/heimdal_build/asn1_compile
lrwxrwxrwx 1 69 Jan  6 08:56 bin/compile_et -> /usr/local/src/samba-git/bin/default/source4/heimdal_build/compile_et

$ ls -go /usr/local/bin/*compile*
-r-xr-xr-x 1 205 Jan  6 09:04 /usr/local/bin/asn1_compile
-r-xr-xr-x 1 202 Jan  6 09:04 /usr/local/bin/compile_et
$ cat /usr/local/bin/asn1_compile
#!/bin/sh
/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/ \
    /usr/local/src/samba-git/bin/default/source4/heimdal_build/asn1_compile.orig  $@

$ cat /usr/local/bin/compile_et
#!/bin/sh
/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/ \
    /usr/local/src/samba-git/bin/default/source4/heimdal_build/compile_et.orig $@
$ mv bin/default/source4/heimdal_build/asn1_compile{,.orig}
$ mv bin/default/source4/heimdal_build/compile_et{,.orig}

$ ln -s /usr/local/bin/asn1_compile bin/default/source4/heimdal_build/asn1_compile
$ ln -s /usr/local/bin/compile_et   bin/default/source4/heimdal_build/compile_et

Let's try again now:

CC=aarch64-linux-gnu-gcc buildtools/bin/waf build --cross-compile \
   --cross-execute="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/"

Success!

$ find . -type f -name smbd -type f | xargs file
./bin/default/source3/smbd/smbd: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0,[...]

Install with:

sudo mkdir /opt/sambax
sudo chown -c $USER /opt/sambax

CC=aarch64-linux-gnu-gcc buildtools/bin/waf install --cross-compile \
   --cross-execute="/usr/bin/qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib/"

Create a tarball and transfer to target host:

tar -C /opt -cvf ~/sambax.tar sambax
scp ~/sambax.tar arm64:/tmp/

On the target (aarch64) host:

sudo tar -C /opt/ -xf /tmp/sambax.tar

With all that in place, we should be able to run it:

$ /opt/sambax/sbin/smbd -V
Version 4.7.4

$ file /opt/sambax/sbin/smbd 
/opt/sambax/sbin/smbd: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0,[...]

Note: newer versions[15] broke the build again, but for different reasons:

Checking for gnutls >= 3.4.7                                                                    : yes 
Checking for library gnutls                                                                     : not found 
Checking for gnutls_global_init                                                                 : not found 
Checking for library gnutls                                                                     : not found 
Checking for gnutls_certificate_verify_peers3                                                   : not found 
Checking for header gnutls/x509.h                                                               : yes 
Checking for declaration of GNUTLS_CERT_EXPIRED                                                 : not found 
Checking for declaration of GNUTLS_CERT_EXPIRED (as enum)                                       : ok 
Checking for declaration of GNUTLS_CERT_NOT_ACTIVATED                                           : not found 
Checking for declaration of GNUTLS_CERT_NOT_ACTIVATED (as enum)                                 : ok 
Checking for declaration of GNUTLS_CERT_UNEXPECTED_OWNER                                        : not found 
Checking for declaration of GNUTLS_CERT_UNEXPECTED_OWNER (as enum)                              : ok 
Checking for variable gnutls_x509_crt_set_version                                               : ok 
Checking for variable gnutls_x509_crt_set_subject_key_id                                        : ok 
Checking for gnutls_datum                                                                       : ok 
Checking for gnutls_datum_t                                                                     : ok 
Checking for library gcrypt                                                                     : not found 
Checking for gcry_control                                                                       : not found 
Checking for library gpg-error                                                                  : not found 
Checking for gpg_err_code_from_errno                                                            : not found 
Checking for nettle support                                                                     : yes 
Checking for library nettle                                                                     : not found 
Checking for nettle_gcm_aes_encrypt                                                             : not found 
No nettle support for AES GCM
Checking for library gnutls                                                                     : not found 
Checking for gnutls_aead_cipher_init                                                            : not found 
No gnutls support for AEAD encryption
/usr/local/src/samba-git/source4/dsdb/samdb/ldb_modules/wscript:43: error: No AES GCM AEAD support
Try installing gnutls if that does not support AEAD try installing nettle-dev or nettle-devel

References