Last active
February 7, 2024 19:03
-
-
Save lcrilly/670642988f417e091a31a021c6c9977c to your computer and use it in GitHub Desktop.
build_unit.sh - builds NGINX Unit from source based on installed version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
NJS_VER="" | |
RBT=0 | |
UNIT_VER="" | |
SUFFIX=() | |
PATCH_FILES=() | |
CONFIGURE_OPTIONS="" | |
STARTDIR=$PWD | |
WORKDIR=/tmp/build_unit.$$ | |
UNITD_FILENAME="" | |
while [ $# -gt 0 ]; do | |
case $1 in | |
"-h" | "--help") | |
echo "${0##*/} - builds NGINX Unit from source" | |
echo "" | |
echo "USAGE: ${0##*/} [OPTIONS] [patch …]" | |
echo "" | |
echo "Options:" | |
echo " -d | --debug # Build with debugging symbols and logging" | |
echo " -j | --njs <version|off> # JavaScript support (default: latest) " | |
echo " -o | --output <filename> # Produces a unitd binary with the specified filename" | |
echo " -v | --version <version|latest> # Override version (default: already-installed version)" | |
echo "" | |
echo " Patches are applied in command-line order from these locations:" | |
echo " - filename" | |
echo " - URL to GitHub PR URL (requires curl)" | |
echo " - URL to plaintext diff/patch (requires curl)" | |
echo " - Review Board patch number (requires rbt)" | |
echo "" | |
exit 0 | |
;; | |
"-d" | "--debug") | |
CONFIGURE_OPTIONS="--debug" | |
shift | |
;; | |
"-j" | "--njs") | |
NJS_VER=$2 | |
shift; shift | |
;; | |
"-o" | "--output") | |
UNITD_FILENAME=$2 | |
shift; shift | |
;; | |
"-v" | "--version") | |
UNIT_VER=$2 | |
shift; shift | |
;; | |
*) | |
if [ -f $1 ] && [ -r $1 ]; then | |
FILENAME=${1##*/} | |
echo "${0##*/}: INFO: Using patch file $FILENAME" | |
mkdir -p $WORKDIR/patches | |
cp $1 $WORKDIR/patches/${FILENAME%.*} | |
PATCHES+=(${FILENAME%.*}) | |
elif [ -n "$1" ] && [ "$1" -eq "$1" ] 2> /dev/null; then | |
echo "${0##*/}: INFO: Using Review Board patch $1" | |
RBT=1 | |
MISSING=$(hash hg rbt 2>&1 | cut -f4 -d: | tr -d '\n') | |
if [ $? -ne 0 ]; then | |
echo "${0##*/}: ERROR: You must install and configure$MISSING to apply this patch" | |
exit 3 | |
fi | |
PATCHES+=($1) | |
elif [ "${1:0:35}" = "https://github.com/nginx/unit/pull/" ]; then | |
echo "${0##*/}: INFO: Using GitHub PR ${1##*/}" | |
hash curl 2> /dev/null | |
if [ $? -ne 0 ]; then | |
echo "${0##*/}: ERROR: curl(1) is required to obtain patches from GitHub" | |
exit 3 | |
fi | |
PATCHES+=($1.diff) | |
elif [ "${1:0:4}" = "http" ]; then | |
echo "${0##*/}: INFO: Using remote patch $1" | |
hash curl 2> /dev/null | |
if [ $? -ne 0 ]; then | |
echo "${0##*/}: ERROR: curl(1) is required to obtain remote patches" | |
exit 3 | |
fi | |
PATCHES+=($1) | |
else | |
echo "${0##*/}: ERROR: Unrecognized option, $1" | |
exit 2 | |
fi | |
shift | |
;; | |
esac | |
done | |
if [ "$UNIT_VER" = "" ]; then | |
hash unitd 2> /dev/null | |
if [ $? -eq 0 ]; then | |
UNIT_VER=$(unitd --version 2>&1 | head -1 | cut -f3 -d' ') | |
else | |
echo "${0##*/}: WARNING: Unit not installed and no version specified, using the head/tip" | |
fi | |
fi | |
# Prefer Mercurial but fallback to Git | |
# | |
hash hg 2> /dev/null | |
if [ $? -eq 0 ]; then | |
CLONE_PREFIX="hg clone http://hg.nginx.org" | |
CLONE_BRANCH="-u" | |
else | |
CLONE_PREFIX="git clone https://github.com/nginx" | |
CLONE_BRANCH="--branch" | |
fi | |
# Obtain and patch Unit | |
# | |
echo "${0##*/}: INFO: Cloning Unit $UNIT_VER" | |
SUFFIX=$UNIT_VER | |
if [ "$UNIT_VER" = "latest" ]; then | |
UNIT_VER="" | |
fi | |
mkdir -p $WORKDIR | |
cd $WORKDIR | |
if [ "$UNIT_VER" = "" ]; then | |
$CLONE_PREFIX/unit > /dev/null | |
else | |
$CLONE_PREFIX/unit $CLONE_BRANCH $UNIT_VER > /dev/null | |
fi | |
cd unit | |
if [ ${#PATCHES[@]} -eq 0 ]; then | |
echo "${0##*/}: INFO: No patches" | |
else | |
echo "${0##*/}: INFO: Patching Unit" | |
if [ $RBT -eq 1 ]; then | |
hg qnew ${0##*/} | |
fi | |
for PATCH in "${PATCHES[@]}"; do | |
if [ -f ../patches/$PATCH ]; then | |
SUFFIX="${SUFFIX}+${PATCH##*/}" | |
patch -p1 < ../patches/$PATCH > $WORKDIR/patch.out | |
elif [ -n "$PATCH" ] && [ "$PATCH" -eq "$PATCH" ] 2> /dev/null; then | |
SUFFIX="${SUFFIX}+$PATCH" | |
hg qref | |
rbt patch $PATCH > $WORKDIR/patch.out | |
else | |
SUFFIX="${SUFFIX}+$(echo ${PATCH##*/} | cut -f1 -d. | cut -f2 -d= | tr -d '?&_+%=')" | |
curl -fsL $PATCH | patch -p1 > $WORKDIR/patch.out | |
fi | |
if [ $? -ne 0 ]; then | |
if [ $(grep -c 'changes.xml' $WORKDIR/patch.out) -gt 0 ]; then | |
echo "${0##*/}: WARNING: Could not patch changes.xml, continuing" | |
else | |
echo "${0##*/}: ERROR: Patch failed" | |
cat $WORKDIR/patch.out | |
exit 1 | |
fi | |
fi | |
cat $WORKDIR/patch.out | |
done | |
fi | |
# Build njs (as late as possible, to avoid wasting time if the patch failed) | |
# | |
if [ "$NJS_VER" != "off" ]; then | |
echo "${0##*/}: INFO: Cloning NGINX JavaScript $NJS_VER" | |
if [ "$NJS_VER" = "" ]; then | |
$CLONE_PREFIX/njs > /dev/null | |
else | |
$CLONE_PREFIX/njs $CLONE_BRANCH $NJS_VER > /dev/null | |
fi | |
cd njs | |
echo "${0##*/}: INFO: Configuring NGINX JavaScript" | |
./configure --no-libxml2 --no-zlib 2>&1 > configure.out | |
if [ $? -gt 0 ]; then | |
echo "${0##*/}: ERROR: Failed to configure njs" | |
cat configure.out | |
exit 1 | |
fi | |
echo "${0##*/}: INFO: Compiling NGINX JavaScript" | |
make 2>&1 > make.out | |
if [ $? -gt 0 ]; then | |
echo "${0##*/}: ERROR: Failed to build njs" | |
tail make.out | |
exit 1 | |
fi | |
cd .. | |
fi | |
# Build Unit (keeping only the include paths from installed version) | |
# | |
echo "${0##*/}: INFO: Configuring Unit" | |
#if [ "$UNIT_VER" != "" ]; then | |
CC_OPT=$(unitd --version 2>&1 | grep ^configured | sed -e 's/ \-\-/\n--/g' | grep ^--cc-opt | cut -f2- -d= | tr " '" "\n" | grep ^-I) | |
LD_OPT=$(unitd --version 2>&1 | grep ^configured | sed -e 's/ \-\-/\n--/g' | grep ^--ld-opt | cut -f2- -d= | tr " '" "\n" | grep ^-L) | |
#fi | |
if [ "$NJS_VER" != "off" ]; then | |
CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --njs" | |
CC_OPT="$CC_OPT -Injs/src -Injs/build" | |
LD_OPT="$LD_OPT -Lnjs/build" | |
fi | |
cd $WORKDIR/unit | |
CPPFLAGS=$CC_OPT ./configure $CONFIGURE_OPTIONS \ | |
$(unitd --version 2>&1 | grep ^configured | sed -e 's/ \-\-/\n--/g' | grep ^-- | grep -ve ^--njs -e ^--..-opt=) \ | |
--cc-opt="$CC_OPT" --ld-opt="$LD_OPT" 2>&1 > configure.out | |
if [ $? -ne 0 ]; then | |
echo "${0##*/}: ERROR: Failed to configure Unit" | |
cat configure.out | |
exit 1 | |
fi | |
echo "${0##*/}: INFO: Compiling Unit" | |
make 2>&1 > make.out | |
if [ $? -ne 0 ]; then | |
echo "${0##*/}: ERROR: Failed to build Unit" | |
tail make.out | |
exit 1 | |
fi | |
echo "${0##*/}: INFO: Done" | |
if [ "$UNITD_FILENAME" = "" ]; then | |
UNITD_FILENAME=$STARTDIR/unitd-$SUFFIX | |
fi | |
if [ -f build/unitd ]; then | |
cp build/unitd $UNITD_FILENAME | |
else | |
cp build/sbin/unitd $UNITD_FILENAME | |
fi | |
cd .. && rm -fr $WORKDIR | |
ls -l $UNITD_FILENAME |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment