= autotools.txt =

After checking out this directory, both of the following SHOULD work:

(1) for users:
  ./configure whatever_options
  make

(2) for developers changing Makefile.am and configure.ac

  autoreconf
  ./configure whatever_options
  make

for which you need autotools (version requirement?).

autoreconf generates (among others) Makefile.in from Makefile.am
and configure from configure.ac, but in order to avoid hassling 
ordinary users, files generated by autoreconf are also committed
into the repository, so (1) SHOULD just work.

= after you change Makefile.am or configure.ac =

Currently, however, even if you follow the path (1), make may start
regenerating Makefile.in from Makefile.am using automake, which will
fail in environments that lack it.  A typical error message is this

     $ make 
      cd . && /bin/bash /home/tau/parallel2/sys/src/mth/massivethreads/missing --run automake-1.11 --foreign
      configure.ac:23: required file `./compile' not found
      configure.ac:23:   `automake --add-missing' can install `compile'

This happens because, essentially, the automatically generated
Makefile has the following rules

  Makefile.in : ... Makefile.am ...

         ...missing --run automake-1.11

and, after you check out from the repository, there is no guarantee
Makefile.in happens to be newer than those prerequisites.

To avoid this, 

(a) you could simply 

   touch Makefile.in
   touch config.h.in

right after you check out.

(b) but this requires a user's work. I resorted to 
including the "compile" script into the respository.
(when you run "automake --add-missing", it adds a 
_symlink_ to /usr/share/automake-1.11/compile. I
replaced it to a copy of it)

I don't know if there is a smarter way to avoid this...

= info about autotools.txt =

As far as I could found
http://www.lrde.epita.fr/~adl/dl/autotools-handout-4.pdf
(available from http://www.lrde.epita.fr/~adl/autotools.html )
is the best tutorial about GNU autotools.

= some tips to remember =

== add test programs ==

(1) make a folder under tests (e.g., tests/c/hoge)
(2) make a Makefile.am there (tests/c/hoge/Makefile.am)
(3) (DON'T FORGET) add the new folder in SUBDIRS definition in Makefile.am in 
    the parent one directory. for example, edit 
    tests/c/Makefile.am and add
(4) (DON'T FORGET) add tests/c/hoge/Makefile to the list
    of AC_CONFIG_FILES at the end of configure.ac

SUBDIRS += hoge 

(5) add the following in the new Makefile.am

--------------
check_PROGRAMS = ...

...

TESTS = $(check_PROGRAMS)
--------------

see Makefile.am of sibling directories.

Then, 

- autoreconf will generate Makefile.in as usual
- ./configure will generate Makefile as usual
- make check will try to build and run programs listed in TESTS

== make some part of the test/libraries optional ==

MassiveThreads is primarily a C library.  
Under mtbb, we have TBB-like C++ classes, 
task_group, parallel_for, and parallel_reduce.
Under tests/mtbb, we have test programs for them.

We like to build and test these programs only when
users have C++ compiler, so that those who don't
won't be annoyed by configure-time errors. 

Here is how to write such cases in configure.ac and Makefile.am

(1) in configure.ac

write a test case checking if C++ compilers and certain features
are available.  Here is a snipet checking if lambda closures
are supported by the C++ compiler.

AC_MSG_CHECKING([C++ lambda expression support])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ [=] { }(); ]])], 
                  [AC_MSG_RESULT([yes]); cxx_lambda_available=yes],
		  [AC_MSG_RESULT([no]); cxx_lambda_available=no])

(2) in configure.ac

you use AM_CONDITIONAL to make test results avaiable in Makefile.am.
you write something like this.

AM_CONDITIONAL([CXX_AVAILABLE], [test "x$ac_cv_prog_cxx_g" = "xyes"])
AM_CONDITIONAL([CXX_LAMBDA_AVAILABLE], [test "x$cxx_lambda_available" = "xyes"])


(3) in Makefile.am

you can write something like:

if CXX_LAMBDA_AVAILABLE
  ...
endif

to conditionally execute things.  in MassiveThreads, we write

if CXX_LAMBDA_AVAILABLE
SUBDIRS += lambda
endif

to run check programs relying on lambda expressions only when
lambda is available.
