Cross kompilácia nginx, aleb pokus o najpomalší configure skript
NGINX je síce krásny webserver no jeho kompilácia nie je ani zďaleka taká sranda ako by sa mohlo na prvý pohľad zdať.
Na rozdiel od väčšiny softvéru NGINX nepoužíva žiaden existujúci build systém. V balíku síce nájdeme configure skript, ktorého použitie sa na prvý pohľad nijak zvlášne neodlišuje od autotools. Jeho veľkosť (okolo 2kB) je však podozrivo malá ;)
Po letmom nahliadnutí do súboru môžme vidieť, že jeho autorom je Igor Sysoev. Na rozdiel od automaticky generovaného configure vyzerá skutočne elegantne.
Samotná funkcionalita je skrytá v adresári auto. Zisťovanie prítomností jednotlivých systémových balíkov (alebo ako to nazvať) je v súbore auto/feature.
Spúšťanie testov má na starosti riadok if sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then. V premennej $NGX_AUTOTEST bash príkaz (zvyčajne spúšťajúci len obyčajnú binárku skompilovanú pomocou gcc). Pri cross kompilácii však nie je možné priamo spustiť binárku pre inú platformu. V prípade autotools je cross kompilácia riešená dosť šialeným spôsobom (configure skripty fakt nie sú tak veľké len tak zo srandy), tu sú skripty malé a elegantné, nie sú však prispôsobené na cross kompiláciu.
Ak máme prístup cez SSH na dané zariadenie môžme použiť malý trik so spúšťaním príkazov cez SSH. Najskôr vytvoríme súbor auto/run, ktorý je
prakticky kópiou súboru z tohto tutoriálu.
#!/bin/bash
basedir=$(dirname $(readlink -f $0))
keyfile=${basedir}/remote-ssh-key
logfile=${basedir}/run.txt
verbose=
if [ -f "${basedir}/remote" ] ; then
remote=$(<${basedir}/remote)
else
echo -n "Vzdialeny stroj (username@192.168.1.1): "
read remote
echo "$remote" > ${basedir}/remote
fi
if [ "$1" = "-v" ] ; then
verbose=1
shift
fi
if [ -z "$1" ] ; then
echo "Usage: $0 COMMAND ARG..."
exit 1
fi
set -e -u
if [ ! -f $keyfile ] ; then
echo "Generovanie kluca $keyfile" >> ${logfile}
ssh-keygen -f ${keyfile} -N ""
echo "Prenos kluca na vzdialeny system (zadajte prosim heslo)" >> ${logfile}
scp -q ${keyfile}.pub ${remote}:/tmp
echo "Pridanie kluca do authorized_keys (zadajte prosim heslo)" >> ${logfile}
ssh -q ${remote} "mkdir -p ~/.ssh; chmod 700 ~ ~/.ssh; cat /tmp/remote-ssh-key.pub >> ~/.ssh/authorized_keys;"
fi
if [ -x "$1" ] ; then
if [ -n "$verbose" ] ; then
echo "Copying $1 to $remote" >&2
else
echo "$(date) Copying $1 to $remote" >> ${logfile}
fi
scp -q -i ${keyfile} "$1" ${remote}:/tmp
remotename="/tmp/$(basename $1)"
shift
if [ -n "$verbose" ] ; then
echo "Vzdialene spustenie: ${remotename} $@" >&2
else
echo "$(date) Vzdialene spustenie: ${remotename} $@" >> ${logfile}
fi
ssh -q -i ${keyfile} ${remote} "${remotename} $@"
else
if [ -n "$verbose" ] ; then
echo "Vzdialene spustenie: $@" >&2
else
echo "$(date) Vzdialene spustenie: $@" >> ${logfile}
fi
ssh -q -i ${keyfile} ${remote} "$@"
fiPotom už stačí len na pár miestach nahradiť sh -c príkazom auto/run, ktorý vykoná test na vzdialenom stroji (nechce sa mi to celé rozpisovať, prikladám patch pre nginx 1.6.0).
Nakoniec stačí už len spustiť príkazy configure (dlhá pauza lebo sa všetko spúšťa cez ssh) a make (ukážka pre ARM).
$buildhost = "/home/mirec/buildroot-armhf/output/host" $sysroot = "$buildhost/usr/arm-buildroot-linux-gnueabihf/sysroot" export PKG_CONFIG="$buildhost/usr/bin/pkg-config" export PKG_CONFIG_LIBDIR="$sysroot/usr/lib/pkgconfig" export PKG_CONFIG_SYSROOT_DIR="$sysroot" export MAKEFLAGS=" -j3" export cc=$buildhost/usr/bin/arm-cortex_a8-linux-gnueabi-gcc export cpp=$buildhost/usr/bin/arm-cortex_a8-linux-gnueabi-cpp export cflags="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -pipe -Os " export ldflags="" ./configure \
--with-cc=$cc \
--with-cpp=$cpp \
--with-cc-opt=$cflags \
--with-ld-opt=$ldflags \
--crossbuild=arm-buildroot-linux-gnueabihf
Pre pridávanie komentárov sa musíte prihlásiť.

Patch ;)