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} "$@" fi
Potom 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 ;)