1# template.at -- test C++ templates with libtool              -*- Autotest -*-
2#
3#   Copyright (C) 2005, 2007-2008, 2011-2015 Free Software Foundation,
4#   Inc.
5#   Written by Markus Christen, 2005
6#
7#   This file is part of GNU Libtool.
8#
9# GNU Libtool is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; either version 2 of
12# the License, or (at your option) any later version.
13#
14# GNU Libtool is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with GNU Libtool; see the file COPYING.  If not, a copy
21# can be downloaded from  http://www.gnu.org/licenses/gpl.html,
22# or obtained by writing to the Free Software Foundation, Inc.,
23# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24####
25
26AT_BANNER([C++ template tests.])
27
28AT_SETUP([simple template test])
29LT_AT_TAG([CXX])
30AT_KEYWORDS([libtool])
31
32AT_DATA(aclib.h,
33[[int cf(int);
34]])
35
36AT_DATA(aclib.cpp,
37[[#include "aclib.h"
38template<typename T>
39
40T cq(T b)
41{
42  return b * 3;
43}
44
45int cf(int i)
46{
47  return cq(i);
48}
49]])
50
51AT_DATA(alib.h,
52[[int f(int);
53]])
54
55AT_DATA(alib.cpp,
56[[#include "alib.h"
57
58template<typename T>
59T q(T b)
60{
61  return b * 2;
62}
63
64int f(int i)
65{
66  return q(i);
67}
68]])
69
70AT_DATA(prog.cpp,
71[[#include "alib.h"
72#include "aclib.h"
73
74int main()
75{
76  return f(3) + 3 - cf(3) != 0;
77}
78]])
79
80AT_CHECK([$LIBTOOL --tag=CXX --mode=compile $CXX -I. $CPPFLAGS $CXXFLAGS -c -o alib.lo alib.cpp],
81	 [0], [ignore], [ignore])
82AT_CHECK([$LIBTOOL --tag=CXX --mode=compile $CXX -I. $CPPFLAGS $CXXFLAGS -c -o aclib.lo aclib.cpp],
83	 [0], [ignore], [ignore])
84AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CPPFLAGS $CXXFLAGS $LDFLAGS -o libaclib.la aclib.lo],
85	 [0], [ignore], [ignore])
86AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CPPFLAGS $CXXFLAGS $LDFLAGS -o libalib.la -rpath /nonexistent alib.lo libaclib.la],
87	 [0], [ignore], [ignore])
88AT_CHECK([$CXX -I. $CPPFLAGS $CXXFLAGS -c prog.cpp],
89	 [0], [ignore], [ignore])
90AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CPPFLAGS $CXXFLAGS $LDFLAGS -o prog$EXEEXT prog.$OBJEXT libalib.la],
91	 [0], [ignore], [ignore])
92
93LT_AT_EXEC_CHECK([./prog], [0], [ignore], [ignore])
94
95
96dnl with autoreconf, use:
97
98dnl AT_DATA(configure.ac,
99dnl [[AC_INIT([template_1], ]]AT_PACKAGE_VERSION[[, ]]AT_PACKAGE_BUGREPORT[[)
100dnl AC_CONFIG_HEADERS([config.h:config-h.in])
101dnl AC_CONFIG_MACRO_DIRS([m4])
102dnl AC_CONFIG_AUX_DIR([config])
103dnl AM_INIT_AUTOMAKE([foreign])
104dnl AC_LANG([C++])
105dnl AC_PROG_CXX
106dnl AC_PROG_LIBTOOL
107dnl AC_CONFIG_FILES([Makefile])
108dnl AC_OUTPUT
109dnl ]])
110
111dnl AT_DATA(Makefile.am,
112dnl [[ACLOCAL_AMFLAGS = -I m4
113dnl noinst_LTLIBRARIES = libaclib.la
114dnl libaclib_la_SOURCES = aclib.cpp aclib.h
115dnl lib_LTLIBRARIES = libalib.la
116dnl include_HEADERS = alib.h
117dnl libalib_la_SOURCES = alib.cpp
118dnl libalib_la_LIBADD = libaclib.la
119dnl bin_PROGRAMS = prog
120dnl prog_SOURCES = prog.cpp
121dnl LDADD = libalib.la
122dnl ]])
123
124AT_CLEANUP
125
126
127AT_SETUP([template test with subdirs])
128LT_AT_TAG([CXX])
129AT_KEYWORDS([libtool])
130
131noskip=:
132withundef=:
133# Mac OS X.
134# The linker has issues with this test.
135case $host in
136*-darwin*) noskip=false ;;
137*-aix*) withundef=false ;;
138esac
139
140
141CPPFLAGS="$CPPFLAGS -I../src/lib -I../src/lib2"
142
143mkdir src obj
144( cd src; mkdir lib lib2 sub )
145( cd obj; mkdir lib lib2 sub )
146
147AT_DATA(src/lib/a.hh,
148[[template <class T>
149unsigned int a(const T&);
150
151template <class T>
152unsigned int a(const T& t)
153{
154  return sizeof t;
155}
156
157extern int a2(char t);
158
159inline int a3(const double* t)
160{
161  return a(t);
162}
163]])
164
165AT_DATA(src/lib/a.cpp,
166[[#include "a.hh"
167
168int a2(char t)
169{
170  return a(t);
171}
172]])
173
174AT_DATA(src/lib2/b.hh,
175[[#include "a.hh"
176
177template <class T>
178unsigned int b(T& t)
179{
180  return a(t);
181}
182extern int b2(char* t);
183struct bs { int bi; };
184extern int b3(bs t);
185]])
186
187AT_DATA(src/lib2/b.cpp,
188[[#include "b.hh"
189
190int b2(char* t)
191{
192  return a2(t[0]);
193}
194
195int b3(bs t)
196{
197  return b(t);
198}
199]])
200
201AT_DATA(src/sub/main.cpp,
202[[#include "b.hh"
203
204int main()
205{
206  double foo;
207  const char s = ' ';
208  char d;
209  char *t = &d;
210  return b(foo) + a3(&foo) + b2(t) - a(s)
211         - (sizeof(double) + sizeof(double*));
212}
213]])
214
215cd obj
216
217# If the compiler supports -c -o, we want to use it:
218# it may make a difference for templates
219eval `$LIBTOOL --tag=CXX --config | $GREP ^compiler_c_o=`
220case $compiler_c_o in
221yes)
222  main_o=sub/main.$OBJEXT
223  AT_CHECK([$CXX $CPPFLAGS $CXXFLAGS -c -o $main_o ../src/sub/main.cpp],
224	   [0], [ignore], [ignore])
225  ;;
226*)
227  main_o=main.$OBJEXT
228  AT_CHECK([$CXX $CPPFLAGS $CXXFLAGS -c ../src/sub/main.cpp],
229	   [0], [ignore], [ignore])
230  ;;
231esac
232
233AT_CHECK([$LIBTOOL --tag=CXX --mode=compile $CXX $CPPFLAGS $CXXFLAGS -c -o lib/a.lo ../src/lib/a.cpp],
234	 [0], [ignore], [ignore])
235AT_CHECK([$LIBTOOL --tag=CXX --mode=compile $CXX $CPPFLAGS $CXXFLAGS -c -o lib2/b.lo ../src/lib2/b.cpp],
236	 [0], [ignore], [ignore])
237AT_CHECK([$CXX $CPPFLAGS $CXXFLAGS -c ../src/sub/main.cpp],
238	 [0], [ignore], [ignore])
239# both convenience
240AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib/liba.la lib/a.lo],
241	 [0], [ignore], [ignore])
242AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib2/libb.la lib2/b.lo],
243	 [0], [ignore], [ignore])
244AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o sub/main$EXEEXT $main_o lib2/libb.la lib/liba.la],
245	 [0], [ignore], [ignore])
246LT_AT_EXEC_CHECK([./sub/main], [ignore])
247# lib convenience
248if $noskip && $withundef; then
249  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib2/libb.la lib2/b.lo -rpath /foo],
250	   [0], [ignore], [ignore])
251  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o sub/main$EXEEXT $main_o lib2/libb.la lib/liba.la],
252	   [0], [ignore], [ignore])
253  LT_AT_EXEC_CHECK([./sub/main])
254fi
255
256# both installed
257AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib/liba.la lib/a.lo -rpath /foo],
258	 [0], [ignore], [ignore])
259if $withundef; then
260  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib2/libb.la lib2/b.lo -rpath /bar],
261	   [0], [ignore], [ignore])
262  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o sub/main$EXEEXT $main_o lib2/libb.la lib/liba.la],
263	   [0], [ignore], [ignore])
264  LT_AT_EXEC_CHECK([./sub/main])
265fi
266
267# both convenience, libb depending on liba
268AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib/liba.la lib/a.lo],
269	 [0], [ignore], [ignore])
270AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib2/libb.la lib2/b.lo lib/liba.la],
271	 [0], [ignore], [ignore])
272AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o sub/main$EXEEXT $main_o lib2/libb.la],
273	 [0], [ignore], [ignore])
274LT_AT_EXEC_CHECK([./sub/main])
275# lib convenience
276if $noskip; then
277
278  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib2/libb.la lib2/b.lo lib/liba.la -rpath /foo],
279	 [0], [ignore], [ignore])
280  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o sub/main$EXEEXT $main_o lib2/libb.la],
281	 [0], [ignore], [ignore])
282  LT_AT_EXEC_CHECK([./sub/main])
283fi
284# both installed
285if $noskip; then
286  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o lib2/libb.la lib2/b.lo lib/liba.la -rpath /bar],
287	 [0], [ignore], [ignore])
288  AT_CHECK([$LIBTOOL --tag=CXX --mode=link $CXX $CXXFLAGS $LDFLAGS -o sub/main$EXEEXT $main_o lib2/libb.la],
289	 [0], [ignore], [ignore])
290  LT_AT_EXEC_CHECK([./sub/main])
291fi
292
293cd ..
294
295AT_CHECK([$noskip || (exit 77)])
296
297dnl with autoreconf use:
298dnl
299dnl AT_DATA(src/configure.ac,
300dnl [[AC_INIT([template_2], ]]AT_PACKAGE_VERSION[[, ]]AT_PACKAGE_BUGREPORT[[)
301dnl AC_CONFIG_HEADERS([config.h:config-h.in])
302dnl AC_CONFIG_MACRO_DIRS([m4])
303dnl AC_CONFIG_AUX_DIR([config])
304dnl AM_INIT_AUTOMAKE([foreign subdir-objects])
305dnl AC_LANG([C++])
306dnl AC_PROG_CXX
307dnl AC_PROG_LIBTOOL
308dnl AC_CONFIG_FILES([Makefile])
309dnl AC_OUTPUT
310dnl ]])
311dnl
312dnl AT_DATA(src/Makefile.am,
313dnl [[ACLOCAL_AMFLAGS = -I m4
314dnl INCLUDES = -I$(srcdir)/lib -I$(srcdir)/lib2
315dnl bin_PROGRAMS = sub/main
316dnl noinst_LTLIBRARIES = lib/liba.la lib2/libb.la
317dnl lib_liba_la_SOURCES = lib/a.cpp lib/a.hh
318dnl lib2_libb_la_SOURCES = lib2/b.cpp lib2/b.hh
319dnl #lib2_libb_la_LIBADD = lib/liba.la
320dnl sub_main_SOURCES = sub/main.cpp
321dnl sub_main_LDADD = lib2/libb.la lib/liba.la
322dnl ]])
323
324AT_CLEANUP
325