How to compile the latest Nginx + brotli + http2 on HP-UX 11i v3 (11.31 IA64 Itanium 64)

If your web server has to be on a server running HP-UX 11.31 IA64, you would think that you are stuck with HP’s outdated Apache server (2.0.58 on my server).

That was the case for me a few weeks ago.

But what if you could run the latest Nginx web server with brotli and http/2 support ? Wouldn’t that be awesome? So let’s just do that!

Prerequisites

You will need the following:

I did not have the HP ANSI C compiler so it is not required.

I have the following depots installed:

GNU_C_C++ 4.7.1
autoconf 2.69 autoconf
automake 1.15 automake
bash 4.4.23 bash
binutils 2.30 binutils
bison 3.0.5 bison
bzip2 1.0.6 bzip2
curl 7.55.0 curl
cyrus_sasl 2.1.26 cyrus_sasl
db 6.2.32 db
depothelper 2.10 depothelper
editline 2.9 editline
expat 2.2.3 expat
expect 5.45 expect
file 5.31 file
flex 2.6.4 flex
fontconfig 2.12.4 fontconfig
freetype 2.8 freetype
gawk 4.1.2 gawk
gdbm 1.13 gdbm
gettext 0.19.8.1 gettext
git 2.14.0 git
glib2 2.34.3 glib2
gmp 6.1.2 gmp
heimdal 1.5.2 heimdal
hpuxclnt 7.4.101-58 Avamar client
libXft 2.3.2 libXft
libXrender 0.9.10 libXrender
libevent 2.1.8 libevent
libgcc 4.2.3 libgcc
libiconv 1.15 libiconv
libidn 1.33 libidn
libpng 1.6.30 libpng
libtool 2.4.6 libtool
libunistring 0.9.7 libunistring
m4 1.4.18 m4
make 4.1 make
mpc 1.1.0 mpc
mpfr 4.0.1 mpfr
nano 2.8.6 nano
ncurses 6.0 ncurses
openldap 2.4.45 openldap
openssl 1.0.2l openssl
p7zip 9.20.1 p7zip
perl 5.10.1 perl
pkgconfig 0.29.2 pkgconfig
popt 1.16 popt
readline 7.0.003 readline
regex 0.12 regex
rsync 3.0.9 rsync
sed 4.5 sed
tar 1.26 tar
tcltk 8.5.19 tcltk
termcap 1.3.1 termcap
texinfo 5.2 texinfo
zip 3.0 zip
zlib 1.2.11 zlib

I think the important ones for building are GNU_C_C++ 4.7.1, autoconf, automake, binutils, bison, db, flex, m4, gettext, libiconv, libidn, libtool, libunistring, pkgconfig, readline, sed, tar, termcap, zlib. If anything important is missing in this list, then install it and send me a comment so that I can update it.

Environment

$ indicates a command run by your user and # indicates a command run as root (dont type those characters in the terminal).

Create the following directory and cd into it:

$ mkdir ~/dev && cd ~/dev

And place inside all the prerequisites archives you downloaded.

OpenSSL

Extract the OpenSSL archive and cd into the created directory (for example ~/dev/openssl-1.0.2o/), then:

$ ./Configure hpux64-ia64-gcc shared
$ gmake depend
$ gmake
# gmake install

It should compile without any issue. If not, look at the error messages and try to guess what happened. If OpenSSL does not compile, you will not be able to compile Nginx with SSL support, and SSL is required for HTTP/2! So that’s a very important step, be sure that OpenSSL compiles before continuing anything else.

Zlib

Extract the Zlib archive and cd into the created directory (for example ~/dev/zlib-1.2.11/), then:

$ nano configure

Find this section:

if [ "`uname -s`" = "HP-UX" ]
then
    export prefix="/usr/local"
    export PATH="$prefix/bin:$PATH"
    if [ "`uname -m`" = "ia64" ]
    then
        export libdir="$prefix/lib/hpux32"
        export libext=".so"
    else
        export libext=".sl"
    fi
    export CC="cc"
    export CFLAGS="+z -O -I."

And replace it with:

if [ "`uname -s`" = "HP-UX" ]
then
    export prefix="/usr/local"
    export PATH="$prefix/bin:$PATH"
    if [ "`uname -m`" = "ia64" ]
    then
        export libdir="$prefix/lib/hpux64"
        export libext=".so"
    else
        export libext=".sl"
    fi
    export CC="gcc"
    export CFLAGS="-mlp64 -O -I."

Then type the following:

$ ./configure
$ gmake
# gmake install

PCRE

Extract the PCRE archive and cd into the created directory (for example ~/dev/pcre-8.42/), then:

$ nano configure

Find the following section:

if [ "`uname -s`" = "HP-UX" ]
then
    export prefix="/usr/local"
    export PATH="$prefix/bin:$PATH"
    if [ "`uname -m`" = "ia64" ]
    then
        export libdir="$prefix/lib/hpux64"
        flags64="+DD64"
    else
        export libdir="$prefix/lib"
        flags64=""
    fi
    export CC="cc"
    export CFLAGS="-O $flags64 +Z -I$prefix/include"
    export CXX="/opt/aCC/bin/aCC"
    export CPPFLAGS="$CFLAGS"
    export CXXFLAGS="$CFLAGS -AA"
    export LDFLAGS="$flags64 +Z -Wl,+b -Wl,$libdir -L$libdir"

And replace it with the following:

if [ "`uname -s`" = "HP-UX" ]
then
    export prefix="/usr/local"
    export PATH="$prefix/bin:$PATH"
    if [ "`uname -m`" = "ia64" ]
    then
        export libdir="$prefix/lib/hpux64"
        flags64="-mlp64"
    else
        export libdir="$prefix/lib"
        flags64=""
    fi
    export CC="gcc"
    export CFLAGS="-O $flags64 -I$prefix/include"
    export CXX="g++"
    export CPPFLAGS="$CFLAGS"
    export CXXFLAGS="$CFLAGS"
    export LDFLAGS="$flags64 -Wl,+b -Wl,$libdir -L$libdir"

Then type the following:

$ ./configure --enable-shared
$ gmake
# gmake install

LibBrotli

Extract the Libbrotli archive and cd into the created directory (for example ~/dev/libbrotli/), then:

$ ./configure CC="gcc" CFLAGS="-mlp64" CPP="gcc -E" CXX="g++" CXXFLAGS="-mlp64" CXXCPP="g++ -E"
$ gmake
# gmake install

Nginx

We’re almost there!

  • Extract the Nginx brotli module archive (for example in ~/dev/ngx_brotli/)
  • Extract the Nginx archive and cd into the created directory (for example ~/dev/nginx-1.15/)

Then:

$ nano auto/lib/pcre/make

Find and replace the following line:

./configure --disable-shared $PCRE_CONF_OPT

With:

./configure --disable-cpp --disable-shared $PCRE_CONF_OPT

Then:

$ nano auto/lib/openssl/make

Find and replace the following line:

&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\

With:

&& ./Configure --prefix=$ngx_prefix hpux64-ia64-gcc no-shared no-threads $OPENSSL_OPT

Then:

$ CFLAGS="-mlp64" ./configure \
--with-pcre=/home/your_user/dev/pcre-8.42 \
--with-zlib=/home/your_user/dev/zlib-1.2.11 \
--with-openssl=/home/your_user/dev/openssl-1.0.2o \
--add-module=/home/your_user/dev/ngx_brotli \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_auth_request_module \
--with-http_gzip_static_module \
--with-http_gunzip_module \
--with-ld-opt="-mlp64 -L /usr/local/ssl/lib -L /usr/local/lib" \
--with-cc-opt="-mlp64 -I /usr/local/ssl/include -I /usr/local/include -Wno-sign-compare" \
--with-cc=/opt/hp-gcc/bin/gcc \
--user=www \
--group=www \
--build=GabSoftware \
--with-threads \
--with-stream=dynamic \
--with-debug \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-stream_ssl_module \
--with-http_stub_status_module
$ gmake

It should build without errors (it will take a while because it has to recompile OpenSSL…). Then check the output of

$ objs/nginx -V

If everything is okay, you should get something like:

nginx version: nginx/1.15.0 (GabSoftware)
built with OpenSSL 1.0.2o 27 Mar 2018
TLS SNI support enabled
configure arguments: --with-pcre=/home/your_user/dev/pcre-8.42 --with-zlib=/home/your_user/dev/zlib-1.2.11 --with-openssl=/home/your_user/dev/openssl-1.0.2o --add-module=/home/your_user/dev/ngx_brotli --with-http_v2_module --with-http_ssl_module --with-http_auth_request_module --with-http_gzip_static_module --with-http_gunzip_module --with-ld-opt='-mlp64 -L /usr/local/ssl/lib -L /usr/local/lib' --with-cc-opt='-mlp64 -I /usr/local/ssl/include -I /usr/local/include -Wno-sign-compare' --with-cc=/opt/hp-gcc/bin/gcc --user=www --group=www --build=GabSoftware --with-threads --with-stream=dynamic --with-debug --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-stream_ssl_module --with-http_stub_status_module

Finally, install your freshly built Nginx:

# gmake install

Running Nginx

Don’t forget to create the www user and the associated www group with home directory /home/www.

As a courtesy, I give you the following script to manage your Nginx instance:

#!/usr/bin/bash

# This script must be run as root for every action except "status"
NGINX_HOME="/usr/local/nginx"

nginx="$NGINX_HOME/sbin/nginx"

function check_root {
  if [ "$(id -u)" != "0" ]; then
    echo "This action must be run as root!" 1>&2
    exit 1
  fi
}

case $1 in
"status")
  nbnginx="$(pgrep -f nginx | wc -l)"
  if [ "$nbnginx" -eq "0" ]; then
    echo "Nginx is not running"
  else
    echo "Nginx OK! ($nbnginx processes)"
  fi
  ;;
"start")
  check_root
  echo "Starting Nginx..."
  $nginx
  echo "Done!"
  ;;
"stop")
  check_root
  echo "Stopping Nginx..."
  $nginx -s stop
  echo "Done!"
  ;;
"restart")
  check_root
  echo "Restarting Nginx..."
  $nginx -s stop
  $nginx
  echo "Done!"
  ;;
"reload")
  check_root
  echo "Reloading Nginx config..."
  $nginx -s reload
  echo "Done!"
  ;;
*)
  echo "Usage: webserver [status | start | stop | restart | reload]"
  echo " status = Nginx status"
  echo " start = Start Nginx (root required)"
  echo " stop = Stop Nginx (root required)"
  echo " restart = Stop Nginx, then Start Nginx (root required)"
  echo " reload = Reload Nginx config (root required)"
  ;;
esac

You are free to use and modify this script as you want. I use Bash but maybe you use Ksh or Zsh.

Save this script as /home/www/webserver and chmod +x it so that it can be executed.

Then you just need to type the following, as root:

# /home/www/webserver start
Starting Nginx...
Done!

Check that Nginx is running:

$ /home/www/webserver status
Nginx OK! (2 processes)
$ ps -ef | grep nginx
root 1259 1 0 15:26:01 ? 0:00 /usr/local/nginx/sbin/nginx
your_user 4553 21205 0 17:44:40 pts/2 0:00 grep nginx
www 1260 1259 0 15:26:01 ? 0:01 /usr/local/nginx/sbin/nginx

You now have the latest Nginx with Brotli and HTTP/2 support! Good job 🙂

Note: if Nginx complains about ports already in use, check that your Apache server is stopped or not listening to the 80 and 443 ports!