#!/bin/sh

test -z "$LIBTOOL" && LIBTOOL=libtool
test -z "$CC" && CC=gcc
test -z "$CFLAGS" && CFLAGS=-g
test -z "$CPPFLAGS" && CPPFLAGS=
test -z "$LDFLAGS" && LDFLAGS=

instdir="`pwd`/inst"

# First, source for the dummy dependency library "libdep.la"

cat << EOF > dep-helper.c
/* non-static helper function that isn't exported */
const char *helper(void)
{
#ifdef PIC
	return "shared module1 dependency";
#else
	return "static module1 dependency";
#endif
}
EOF

cat << EOF > dep.c
const char *helper(void);
const char *dep(void)
{
	return helper();
}
EOF

cat << EOF > dep.expsym
dep
EOF

# Then, the source for module1.la depending on "libdep.la".

cat << EOF > module1.c
const char *dep(void);
const char *module1_LTX_entry_point(void)
{
	return dep();
}
EOF

cat << EOF > module1.expsym
module1_LTX_entry_point
EOF

# Source for the simplistic module2.la w/o dependencies.

cat << EOF > module2.c
const char *module2_LTX_entry_point(void)
{
#ifdef PIC
	return "shared module2";
#else
	return "static module2";
#endif
}
EOF

cat << EOF > module2.expsym
module2_LTX_entry_point
EOF

# Source for libfoo.la, the module consumer.

cat << EOF > foo.c
#include <stdio.h>
#include <string.h>
#include <ltdl.h>

typedef const char *(module_entry)(void);

static module_entry *module1;
static module_entry *module2;

static module_entry *open_module(const char *module)
{
	lt_dlhandle dlh = lt_dlopenext(module);
	if (!dlh)
		return NULL;
	return (module_entry *)lt_dlsym(dlh, "entry_point");
}

extern lt_dlsymlist lt_libfoo_LTX_preloaded_symbols[];

int foo_init(void);
void foo_exit(void);
void foo_doit(void);

int foo_init(void)
{
	printf("foo_init\n");
	/* Futile attempt to make libfoo self contained */
	lt_dlpreload(lt_libfoo_LTX_preloaded_symbols);
	lt_dlinit();
	module1 = open_module("module1");
	module2 = open_module("module2");
	if (!module1 || !module2) {
		printf("Failed to open modules.\n");
		return 1;
	}
	return 0;
}

void foo_exit(void)
{
	lt_dlexit();
	printf("foo_exit\n");
}

void foo_doit(void)
{
	printf("%s\n", module1());
	printf("%s\n", module2());
}
EOF

cat << EOF > foo.expsym
foo_init
foo_doit
foo_exit
EOF

# Source for a simple test program.

cat << EOF > bar.c
#include <ltdl.h>

int foo_init(void);
void foo_exit(void);
void foo_doit(void);

int main(void)
{
	/* libfoo isn't self-contained. It needs a little help
	   with preloading... */
	LTDL_SET_PRELOADED_SYMBOLS();
	if (foo_init())
		return 1;
	foo_doit();
	foo_exit();
	return 0;
}
EOF



# Build the dummy dependency library libdep.la
$LIBTOOL --mode=compile --tag=CC \
 $CC $CPPFLAGS $CFLAGS -c -o dep-helper.lo dep-helper.c
$LIBTOOL --mode=compile --tag=CC \
 $CC $CPPFLAGS $CFLAGS -c -o dep.lo dep.c
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS -o libdep.la dep-helper.lo dep.lo \
 -rpath $instdir -export-symbols dep.expsym \
 -version-info 2:0:0 -no-undefined

# Install the dummy dependency library
mkdir $instdir
$LIBTOOL --mode=install --tag=CC \
 cp libdep.la $instdir/libdep.la
# And remove some key files from the build, forcing libtool to
# pick up libdep.la from the installed location.
rm -rf libdep.la .libs/libdep*


# Build module1.la
$LIBTOOL --mode=compile --tag=CC \
 $CC $CPPFLAGS $CFLAGS -c -o module1.lo module1.c
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS -o module1.la module1.lo \
 -L$instdir -ldep \
 -rpath /usr/local/lib/example -export-symbols module1.expsym \
 -avoid-version -no-undefined -module

# Build module2.la
$LIBTOOL --mode=compile --tag=CC \
 $CC $CPPFLAGS $CFLAGS -c -o module2.lo module2.c
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS -o module2.la module2.lo \
 -rpath /usr/local/lib/example -export-symbols module2.expsym \
 -avoid-version -no-undefined -module

# Build libfoo.la
$LIBTOOL --mode=compile --tag=CC \
 $CC $CPPFLAGS $CFLAGS -c -o foo.lo foo.c
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS -o libfoo.la foo.lo -lltdl \
 -rpath /usr/local/lib -export-symbols foo.expsym \
 -version-info 3:0:0 -no-undefined \
 -dlopen module1.la -dlopen module2.la

# Compile simple test program
$LIBTOOL --mode=compile --tag=CC \
 $CC $CPPFLAGS $CFLAGS -c -o bar.lo bar.c

# Link a couple of different versions of the test program.
# First, a standard link, prefer shared libs across the board.
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS \
 -o bar bar.lo libfoo.la

# Now a static link, prefer static libs of the locally
# built libs (i.e. all but libdep.la).
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS -static \
 -o bar-static bar.lo libfoo.la

# Only accept static libs.
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS -all-static \
 -o bar-all-static bar.lo libfoo.la

# Another variant of prefer static libs.
$LIBTOOL --mode=link --tag=CC \
 $CC $CFLAGS $LDFLAGS -static-libtool-libs \
 -o bar-static-libtool-libs bar.lo libfoo.la
