1#!/usr/bin/env bash
2
3# compile ldns for windows
4cdir="$(echo ldns.win.$$)"
5tmpdir=$(pwd)
6mkdir "$cdir"
7cd "$cdir"
8#configure="mingw32-configure"
9#strip="i686-w64-mingw32-strip"
10#warch="i686"
11configure="mingw64-configure"
12strip="x86_64-w64-mingw32-strip"
13warch="x86_64"
14WINSSL="$HOME/Downloads/openssl-1.1.0h.tar.gz"
15cross_flag=""
16cross_flag_nonstatic=""
17RC="no"
18SNAPSHOT="no"
19CHECKOUT=""
20# the destination is a zipfile in the start directory ldns-a.b.c.zip
21# the start directory is a git repository, and it is copied to build from.
22
23info () {
24	echo "info: $1"
25}
26
27error_cleanup () {
28	echo "$1"
29	cd "$tmpdir"
30	rm -rf "$cdir"
31	exit 1
32}
33
34replace_text () {
35    (cp "$1" "$1".orig && \
36        sed -e "s/$2/$3/g" < "$1".orig > "$1" && \
37        rm "$1".orig) || error_cleanup "Replacement for $1 failed."
38}
39
40# Parse command line arguments
41while [ "$1" ]; do
42    case "$1" in
43	"-h")
44		echo "Compile a zip file with static executables, and"
45		echo "dynamic library, static library, include dir and"
46		echo "manual pages."
47		echo ""
48		echo "	-h		This usage information."
49		echo "	-s		snapshot, current date appended to version"
50		echo "	-rc <nr>	release candidate, the number is added to version"
51		echo "			ldns-<version>rc<nr>."
52		echo "	-c <tag/br>	Checkout this tag or branch, (defaults to current"
53		echo "			branch)."
54		echo "	-wssl <file>	Pass openssl.tar.gz file, use absolute path."
55		echo ""
56		exit 1
57		;;
58	"-c")
59		CHECKOUT="$2"
60		shift
61		;;
62	"-s")
63		SNAPSHOT="yes"
64		;;
65	"-rc")
66		RC="$2"
67		shift
68		;;
69	"-wssl")
70		WINSSL="$2"
71		shift
72		;;
73	*)
74		error_cleanup "Unrecognized argument -- $1"
75		;;
76    esac
77    shift
78done
79if [ -z "$CHECKOUT" ]
80then
81        if [ "$RC" = "no" ]
82        then
83                CHECKOUT=$( (git status | head -n 1 | awk '{print$3}') || echo master)
84        else
85                CHECKOUT=$( (git status | head -n 1 | awk '{print$3}') || echo develop)
86        fi
87fi
88
89# this script creates a temp directory $cdir.
90# this directory contains subdirectories:
91# ldns/ : ldns source compiled
92# openssl-a.b.c/ : the openSSL source compiled
93# ldnsinstall/ : install of ldns here.
94# sslinstall/ : install of ssl here.
95# file/ : directory to gather the components of the zipfile distribution
96# ldns-nonstatic/ : ldns source compiled nonstatic
97# ldnsinstall-nonstatic/ : install of ldns nonstatic compile
98# openssl-nonstatic/ : nonstatic openssl source compiled
99# sslinstall-nonstatic/ : install of nonstatic openssl compile
100
101info "exporting source into $cdir/ldns"
102git clone git://git.nlnetlabs.nl/ldns/ ldns || error_cleanup "git command failed"
103(cd ldns; git checkout "$CHECKOUT") || error_cleanup "Could not checkout $CHECKOUT"
104#svn export . $cdir/ldns
105info "exporting source into $cdir/ldns-nonstatic"
106git clone git://git.nlnetlabs.nl/ldns/ ldns-nonstatic || error_cleanup "git command failed"
107(cd ldns-nonstatic; git checkout "$CHECKOUT") || error_cleanup "Could not checkout $CHECKOUT"
108#svn export . $cdir/ldns-nonstatic
109
110# Fix up the version number if necessary
111(cd ldns; if test ! -f install-sh -a -f ../../install-sh; then cp ../../install-sh . ; fi; libtoolize -ci; autoreconf -fi)
112version=$(./ldns/configure --version | head -1 | awk '{ print $3 }') || \
113    error_cleanup "Cannot determine version number."
114info "LDNS version: $version"
115if [ "$RC" != "no" ]; then
116	info "Building LDNS release candidate $RC."
117	version2="${version}-rc$RC"
118	info "Version number: $version2"
119	replace_text "ldns/configure.ac" "AC_INIT(ldns, $version" "AC_INIT(ldns, $version2"
120	replace_text "ldns-nonstatic/configure.ac" "AC_INIT(ldns, $version" "AC_INIT(ldns, $version2"
121	version="$version2"
122fi
123if [ "$SNAPSHOT" = "yes" ]; then
124	info "Building LDNS snapshot."
125	version2="${version}_$(date +%Y%m%d)"
126	info "Snapshot version number: $version2"
127	replace_text "ldns/configure.ac" "AC_INIT(ldns, $version" "AC_INIT(ldns, $version2"
128	replace_text "ldns-nonstatic/configure.ac" "AC_INIT(ldns, $version" "AC_INIT(ldns, $version2"
129	version="$version2"
130fi
131
132# Build OpenSSL
133gzip -cd "$WINSSL" | tar xf - || error_cleanup "tar unpack of $WINSSL failed"
134sslinstall="$(pwd)/sslinstall"
135cd openssl-* || error_cleanup "no openssl-X dir in tarball"
136if test $configure = "mingw64-configure"; then
137	sslflags="no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64"
138else
139	sslflags="no-shared no-asm -DOPENSSL_NO_CAPIENG mingw"
140fi
141info "winssl: Configure $sslflags"
142CC="${warch}-w64-mingw32-gcc" AR="${warch}-w64-mingw32-ar" RANLIB="${warch}-w64-mingw32-ranlib" WINDRES="${warch}-w64-mingw32-windres" ./Configure --prefix="$sslinstall" "$sslflags" || error_cleanup "OpenSSL Configure failed"
143info "winssl: make"
144make || error_cleanup "make failed for $WINSSL"
145info "winssl: make install_sw"
146make install_sw || error_cleanup "OpenSSL install failed"
147cross_flag="$cross_flag --with-ssl=$sslinstall"
148cd ..
149
150# Build ldns
151ldnsinstall="$(pwd)/ldnsinstall"
152cd ldns
153info "ldns: autoconf"
154# cp install-sh because one at ../.. means libtoolize won't install it for us.
155if test ! -f install-sh -a -f ../../install-sh; then cp ../../install-sh . ; fi
156libtoolize -ci
157autoreconf -fi
158ldns_flag="--with-examples --with-drill"
159info "ldns: Configure $cross_flag $ldns_flag"
160$configure "$cross_flag" "$ldns_flag" || error_cleanup "ldns configure failed"
161info "ldns: make"
162make || error_cleanup "ldns make failed"
163# do not strip debug symbols, could be useful for stack traces
164# $strip lib/*.dll || error_cleanup "cannot strip ldns dll"
165make doc || error_cleanup "ldns make doc failed"
166DESTDIR=$ldnsinstall make install || error_cleanup "ldns make install failed"
167cd ..
168
169# Build OpenSSL nonstatic
170sslinstallnonstatic="$(pwd)/sslinstallnonstatic"
171mkdir openssl-nonstatic
172cd openssl-nonstatic
173# remove openssl-a.b.c/ and put in openssl-nonstatic directory
174gzip -cd "$WINSSL" | tar xf - --strip-components=1 || error_cleanup "tar unpack of $WINSSL failed"
175if test "$configure" = "mingw64-configure"; then
176	sslflags_nonstatic="shared no-asm -DOPENSSL_NO_CAPIENG mingw64"
177else
178	sslflags_nonstatic="shared no-asm -DOPENSSL_NO_CAPIENG mingw"
179fi
180info "winsslnonstatic: Configure $sslflags_nonstatic"
181CC="${warch}-w64-mingw32-gcc" AR="${warch}-w64-mingw32-ar" RANLIB="${warch}-w64-mingw32-ranlib" WINDRES="${warch}-w64-mingw32-windres" ./Configure --prefix="$sslinstallnonstatic" "$sslflags_nonstatic" || error_cleanup "OpenSSL Configure failed"
182info "winsslnonstatic: make"
183make || error_cleanup "make failed for $WINSSL"
184info "winsslnonstatic: make install_sw"
185make install_sw || error_cleanup "OpenSSL install failed"
186cross_flag_nonstatic="$cross_flag_nonstatic --with-ssl=$sslinstallnonstatic"
187cd ..
188
189# Build ldns nonstatic
190ldnsinstallnonstatic="$(pwd)/ldnsinstall-nonstatic"
191cd ldns-nonstatic
192info "ldnsnonstatic: autoconf"
193# cp install-sh because one at ../.. means libtoolize won't install it for us.
194if test ! -f install-sh -a -f ../../install-sh; then cp ../../install-sh . ; fi
195libtoolize -ci
196autoreconf -fi
197ldns_flag_nonstatic="--with-examples --with-drill"
198info "ldnsnonstatic: Configure $cross_flag_nonstatic $ldns_flag_nonstatic"
199$configure "$cross_flag_nonstatic" "$ldns_flag_nonstatic" || error_cleanup "ldns configure failed"
200info "ldnsnonstatic: make"
201make || error_cleanup "ldns make failed"
202# do not strip debug symbols, could be useful for stack traces
203# $strip lib/*.dll || error_cleanup "cannot strip ldns dll"
204make doc || error_cleanup "ldns make doc failed"
205DESTDIR=$ldnsinstallnonstatic make install || error_cleanup "ldns make install failed"
206cd ..
207
208# create zipfile
209file="ldns-$version.zip"
210rm -f "$file"
211info "Creating $file"
212mkdir file
213cd file
214installplace="$ldnsinstall/usr/$warch-w64-mingw32/sys-root/mingw"
215installplacenonstatic="$ldnsinstallnonstatic/usr/$warch-w64-mingw32/sys-root/mingw"
216cp "$installplace"/lib/libldns.a .
217cp "$installplacenonstatic"/lib/libldns.dll.a .
218cp "$installplacenonstatic"/bin/*.dll .
219cp "$sslinstallnonstatic"/lib/*.dll.a .
220cp "$sslinstallnonstatic"/bin/*.dll .
221cp "$sslinstallnonstatic"/lib/engines-*/*.dll .
222cp ../ldns/LICENSE .
223cp ../ldns/README .
224cp ../ldns/Changelog .
225info "copy static exe"
226for x in "$installplace"/bin/* ; do
227	cp "$x" "$(basename "$x").exe"
228done
229# but the shell script stays a script file
230mv ldns-config.exe ldns-config
231info "copy include"
232mkdir include
233mkdir include/ldns
234cp "$installplace"/include/ldns/*.h include/ldns/.
235info "copy man1"
236mkdir man1
237cp "$installplace"/share/man/man1/* man1/.
238info "copy man3"
239mkdir man3
240cp "$installplace"/share/man/man3/* man3/.
241info "create cat1"
242mkdir cat1
243for x in man1/*.1; do groff -man -Tascii -Z "$x" | grotty -cbu > cat1/"$(basename "$x" .1).txt"; done
244info "create cat3"
245mkdir cat3
246for x in man3/*.3; do groff -man -Tascii -Z "$x" | grotty -cbu > cat3/"$(basename "$x" .3).txt"; done
247rm -f "../../$file"
248info "$file contents"
249# show contents of directory we are zipping up.
250du -s ./*
251# zip it
252info "zip $file"
253zip -r ../../"$file" LICENSE README libldns.a *.dll *.dll.a Changelog *.exe include man1 man3 cat1 cat3
254info "Testing $file"
255(cd ../.. ; zip -T "$file" ) || error_cleanup "errors in zipfile $file"
256cd ..
257
258# cleanup before exit
259cd "$tmpdir"
260rm -rf "$cdir"
261echo "done"
262# display
263ls -lG "$file"
264