#!/bin/sh

set -e

mkdir -p foo
cd foo
cat > configure.ac <<EOF
AC_INIT([foo], [1.0])
AC_PROG_CC
AC_PROG_CXX
AC_PROG_RANLIB
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
EOF

cat > Makefile.am <<EOF
lib_LIBRARIES = libfoo.a
libfoo_a_SOURCES = foo.c
EOF

cat > foo.h <<EOF
#ifndef theplu_foo
#define theplu_foo
#ifdef __cplusplus
extern "C" {
#endif
int foo_version(void);
#ifdef __cplusplus
}
#endif
#endif
EOF

cat > foo.c <<EOF
#include "foo.h"

int foo_version(void)
{ return 1; }
EOF

autoreconf -isvf
./configure
make
cd ..

#####################################
# bar a library with templates that uses libfoo
mkdir -p bar
cd bar
cat > configure.ac <<EOF
AC_INIT([bar], [1.0])
AC_PROG_CC
AC_PROG_CXX
LT_INIT
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
EOF

cat > Makefile.am <<EOF
lib_LTLIBRARIES = libbar.la
libbar_la_SOURCES = bar.cc
EOF

cat > bar.h <<EOF
#ifndef theplu_bar
#define theplu_bar

namespace theplu {

template<class T>
class Base
{
virtual const char* hello(int) { return "hello";}
};

class Bar : public Base<int>
{
public:
double version(void) const;
};

} // end namespace theplu
#endif
EOF

cat > bar.cc <<EOF
#include "bar.h"
#include "../foo/foo.h"

namespace theplu {

double Bar::version(void) const
{
if (foo_version() == 1)
  return 3.14;
return 0;
}

}
EOF

autoreconf -isvf
./configure
make
cd ..



# baz an app that uses bar
mkdir -p baz
cd baz

cat > configure.ac <<EOF
AC_INIT([baz], [1.0])
AC_PROG_CC
AC_PROG_CXX
LT_INIT
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
EOF

cat > Makefile.am <<EOF
bin_PROGRAMS = baz
baz_SOURCES = baz.cc
LDADD = ../bar/libbar.la ../foo/libfoo.a
EOF

cat > baz.cc <<EOF
#include "../foo/foo.h"
#include "../bar/bar.h"
#include <iostream>
int main()
{
theplu::Bar b;
std::cout << b.version() << "\n";
//std::cout << foo_version() << "\n";
return 0;
}
EOF

autoreconf -isvf
./configure
make
./baz
echo OK
cd ..
