#!/bin/bash

# Wrapper script to build a DLL with gcc.

# In addition to just build the DLL with gcc -shared, it also links in
# a resource file, if such exists. The resource source file is
# supposed to contain a version info section, that uses the string
# BUILDNUMBER as the least significant part of the version
# numbers. This script replaces that string with a "build number"
# before compiling the binary resource file. The build number is kept
# between builds in a "stamp" file, and incremented each time. (If
# there is no stamp file, build number 0 is used.) The intention is
# that only the "official" maintainer of a DLL keeps such a stamp
# file, and thus the DLLs he releases have increasing version number
# resources, which can be used by an installer program to decide
# whether to replace an existing DLL with the same name.

# This is just my (tml@iki.fi) idea, if somebody comes up with a
# better way to generate version number resources, don't hesitate to
# suggest.

# If a version number is passed to this script, the generated DLL's
# name is suffixed with the version number. Note that this version
# number only is used in forming the name of the DLL, it is not
# related (from Windows's point of view) with the version resource in
# the DLL.

# In addition to the DLL, also an import library is generated. The
# import library name does not contain the version number. This is
# intended to be similar in spirit to symlinking libfoo.so to
# libfoo.so.4.2 on Unix, and then when building some app, just
# specifying -lfoo.

# In addition to the gcc import library, if a .def file is passed on
# the command line, and the Microsoft linker is available, also a
# Microsoft import library (foo.lib) is generated.

# This script is usable at least with Cygwin 1.3.2 (the Cygwin bash is
# used to interpret this script, plus it calls at least m4), and
# gcc-2.95.3 and binutils-2.11.90 for Mingw (see www.mingw.org). For
# other combinations, no idea.

# The command line arguments are:
# $1: library base name, for instance foo
# $2: version number, to be appended to the DLL basename. If no version number,
#	pass a dash '-'. For example 4.2
# $3 ...: def file (if used), object files, libraries and other switches

# This script would then generate foo-4.2.dll, libfoo.a, and foo.lib
# (if the Microsoft linker is available).

library=$1; shift
version=$1; shift;
ldargs="$*"

[ -z "$CC" ] && CC=gcc

case "$CC" in
    gcc*)
	;;
    *)
	echo build-dll only works with gcc
	exit 1
	;;
esac

deffile=
for F in $ldargs; do
    case $F in
	*.def)	deffile=$F
    esac
done

dllfile=$library
[ $version != '-' ] && dllfile=$library-$version
dllfile=$dllfile.dll

# Check if we have a resource file for this DLL.
resfile=""
if [ -f $library.rc ]; then
    resfile=$library-win32res.o
    ldargs="$ldargs $resfile"

    # Check if we have a build number stamp file.
    if [ -f $library-build.stamp ]; then
	read number <$library-build.stamp
	buildnumber=$[number+1]
	echo Build number is $buildnumber
	echo $buildnumber >$library-build.stamp
    else
	echo Using zero as build number
        buildnumber=0
    fi

    m4 -DBUILDNUMBER=$buildnumber <$library.rc >$library-win32res.rc
    windres $library-win32res.rc $library-win32res.o
    rm $library-win32res.rc
fi

# Build the DLL.

$CC -shared -o $dllfile $ldargs -Wl,--out-implib,lib$library.a

# Finally, also build import libraries for the Microsoft linker. You
# will either need to have some decent version of MSVC, or get lib.exe
# (and link.exe) from the (freely downloadable) Microsoft Platform SDK.

if type -p lib.exe && [ -n "$deffile" ]; then
    lib -name:$dllfile -def:$deffile -out:$library.lib
fi

exit 0
