Skip to content

Instantly share code, notes, and snippets.

@lcrilly
Created August 28, 2018 12:59
Show Gist options
  • Select an option

  • Save lcrilly/380782c5524e98d7413b72684200ca2c to your computer and use it in GitHub Desktop.

Select an option

Save lcrilly/380782c5524e98d7413b72684200ca2c to your computer and use it in GitHub Desktop.
#!/bin/sh
#
# compile_module.sh (c) NGINX, Inc. [v0.6 28-Aug-2018] Liam Crilly <[email protected]>
#
# This script supports Ubuntu, RedHat and CentOS package managers
# Installs the minimum necessary prerequisite packages to build 3rd party modules for NGINX Plus
# Obtains source for module and NGINX OSS, compiles the module .so and cleans up.
# Inspects module configuration and attempts to rewrite for dynamic build if necessary.
#
# CHANGELOG
# v0.6 Now using https://demo.nginx.com/api for NGINX Plus-OSS versions
# v0.5 Fixed build from dir when using relative path (e.g. ./my_src)
# Module binaries are stripped
# v0.4 git clone is now recursive to obtain all dependencies (e.g. brotli)
# Module binary is produced with OSS version number as filename suffix
# v0.3 Improved error handling
# v0.2 Detects and converts static modules to dynamic module configuration (experimental)
# Now works with yum(1)
# v0.1 Initial version, for apt/Ubuntu
#
# Check command line parameters
#
ME=`basename $0`
if [ $# -lt 1 ]; then
echo "USAGE: $ME <module github URL | path to module source> [NGINX version]"
exit 1
fi
MODULE=$1
NGX_VER=$2
#
# Check dependencies (wget, git)
#
if [ `whereis wget | grep -c "^wget: /"` -ne 1 ]; then
echo "$ME: ERROR: missing dependency 'wget'"
wget --version
exit 1
fi
if [ `whereis git | grep -c "^git: /"` -ne 1 ]; then
echo "$ME: ERROR: missing dependency 'git'"
git --version
exit 1
fi
#
# Check sudo
#
echo "$ME: INFO: testing sudo"
sudo pwd > /dev/null
if [ $? -ne 0 ]; then
echo "ERROR: sudo failed - quitting"
exit 1
fi
#
# Locate/select package manager
#
if [ `whereis yum | grep -c "^yum: /"` -eq 1 ]; then
PKG_MGR=yum
DEV_PACKAGES="pcre-devel zlib-devel"
elif [ `whereis apt-get | grep -c "^apt-get: /"` -eq 1 ]; then
PKG_MGR=apt-get
DEV_PACKAGES="libpcre3-dev zlib1g-dev"
else
echo "$ME: ERROR: Could not locate a supported package manager - quitting"
exit 1
fi
#
# Check/install dependent packages (PCRE and zlib for NGINX configure)
#
echo "$ME: INFO: checking for dependent packages"
sudo $PKG_MGR -y install jq gcc make $DEV_PACKAGES
#
# Create temporary build area
#
BUILD_DIR=/tmp/$ME.$$
mkdir $BUILD_DIR
echo "$ME: INFO: Created $BUILD_DIR build area"
#
# Get/check module source
#
if [ -d $MODULE ]; then
#MODULE_DIR=$MODULE
cd $MODULE
MODULE_DIR=$PWD
cd -
else
echo "$ME: INFO: Cloning module source"
MODULE_DIR=$BUILD_DIR/`basename $MODULE`
git clone --recursive $MODULE $MODULE_DIR
fi
if [ `grep -c "\.[[:space:]]auto/module" $MODULE_DIR/config` -eq 0 ]; then
echo "$ME: WARNING: This is a static module, attempting to convert to dynamic (experimental)"
grep -ve HTTP_MODULES -e STREAM_MODULES -e NGX_ADDON_SRCS $MODULE_DIR/config > $MODULE_DIR/config.dynamic
echo "ngx_module_name=`grep ngx_addon_name= $MODULE_DIR/config | cut -f2 -d=`" >> $MODULE_DIR/config.dynamic
if [ `grep -c "HTTP_AUX_FILTER_MODULES=" $MODULE_DIR/config` -gt 0 ]; then
echo "ngx_module_type=HTTP_AUX_FILTER" >> $MODULE_DIR/config.dynamic
elif [ `grep -c "STREAM_MODULES=" $MODULE_DIR/config` -gt 0 ]; then
echo "ngx_module_type=Stream" >> $MODULE_DIR/config.dynamic
else
echo "ngx_module_type=HTTP" >> $MODULE_DIR/config.dynamic
fi
echo "ngx_module_srcs=\"`grep NGX_ADDON_SRCS= $MODULE_DIR/config | cut -f2 -d\\" | sed -e 's/^\$NGX_ADDON_SRCS \(\$ngx_addon_dir\/.*$\)/\1/'`\"" >> $MODULE_DIR/config.dynamic
echo ". auto/module" >> $MODULE_DIR/config.dynamic
mv $MODULE_DIR/config $MODULE_DIR/config.static
cp $MODULE_DIR/config.dynamic $MODULE_DIR/config
fi
#
# Get NGINX OSS sources
#
if [ -z $NGX_VER ]; then
#
# Get most recent OSS build from NGINX Plus release notes (this is a hack!)
#
echo "$ME: INFO Lookung up latest NGINX Plus release"
NGX_VER=R`curl -s https://demo.nginx.com/api/3/http/keyvals/nginx_plus_versions | jq -r 'keys[]' | cut -c2- | sort -rn | head -1`
if [ "$NGX_VER" = "R" ]; then
echo "$ME: ERROR: Unable to determine latest NGINX Plus release, try specifiying manually, quitting"
exit 1
fi
fi
if [ "`echo $NGX_VER | cut -c1`" = "R" ]; then
echo "$ME: INFO: Looking up NGINX OSS version for NGINX Plus $NGX_VER"
OSS_VER=`curl -s https://demo.nginx.com/api/3/http/keyvals/nginx_plus_versions | jq -r .$NGX_VER`
if [ -z $OSS_VER ]; then
echo "$ME: ERROR: Unable to determine NGINX OSS version, try specifiying manually, quitting"
exit 1
fi
else
OSS_VER=$NGX_VER
fi
echo "$ME: INFO: Downloading NGINX OSS source (version $OSS_VER)"
cd $BUILD_DIR
wget -O - http://nginx.org/download/nginx-$OSS_VER.tar.gz | tar xfz -
if [ $? -ne 0 ]; then
echo "$ME: ERROR: Failed to download NGINX $OSS_VER, quitting"
echo "$ME: INFO: Build directory preserved at $BUILD_DIR"
exit 1
fi
#
# Compile the module
#
echo "$ME: INFO: Configuring build"
cd - > /dev/null
cd $BUILD_DIR/nginx-$OSS_VER
./configure --with-compat --add-dynamic-module=$MODULE_DIR > $BUILD_DIR/configure.out
if [ $? -ne 0 ]; then
echo "$ME: ERROR: Configure failed, quitting"
cat $BUILD_DIR/configure.out
echo "$ME: INFO: Do you have missing dependencies?"
echo "$ME: INFO: Build directory preserved at $BUILD_DIR"
exit 1
fi
echo "$ME: INFO: Compiling module"
make modules
if [ $? -ne 0 ]; then
echo "$ME: ERROR: make failed, quitting"
echo "$ME: INFO: Do you have missing dependencies?"
echo "$ME: INFO: Build directory preserved at $BUILD_DIR"
exit 1
fi
#
# All done, copy the module .so file to cwd and clean up
#
echo "$ME: INFO: copying module to current directory"
cd - > /dev/null
for obj in $( ls -1 $BUILD_DIR/nginx-$OSS_VER/objs/*.so ); do
OBJFILE=`basename $obj`
RENAMED=`echo $OBJFILE | sed -e "s/\(.*\)\.so/\1_$OSS_VER.so/"`
cp -vi $obj ./$RENAMED
strip ./$RENAMED
done
if [ "$obj" = "" ]; then
echo "$ME: ERROR: Something went wrong, please check $BUILD_DIR"
else
echo "$ME: INFO: Success"
rm -fr $BUILD_DIR
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment