// $Id: README,v 1.13 2000/02/01 00:43:32 carlo Exp $
//
// Description of the contents of this package.
//
// Copyright (C) 1999-2000, by
//
//   Carlo Wood, Run on IRC <carlo@alinoe.com>
//   RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
//   Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
//
// All rights reserved.
//
// See the file LICENSE for copyright information.
//
// This file may be distributed under the terms of the Q Public License 1.0
// as defined by Troll Tech AS of Norway and appearing in the file LICENSE.QPL
// included in the packaging of this file.
//

Description
-----------

The prototype Makefiles are intended for extremely flexible and fast
creation and expansion of projects (in C and C++).

You will not need to spend any significant time anymore on creating or
editing Makefiles.

These Makefiles are the result of many years of tweaking and tuning, using
Makefiles in practise in a large C++ project. As a result they are also a
valuable source for those who want examples, to learn how to write and use
Makefiles with GNU make.

The following targets are fully and automatically supported:

make [all]	:	Builds the whole project, works from every
			(sub) directory.
make build	:	Builds the current directory (and everything in
			it, except test directories).  By default, only
			shared libraries will be build (not static).
make clean	:	Clear executables, compiled libraries, object files
			and dependency information.
make depend	:	Create dependency information (is also updated
			automatically when needed).
make real-clean :	Uses `find' to make 100% sure you end up with
			a clean tree.
make static	:	In a 'lib' directory: Build and link static
			library only.

The common target `make install' needs to be added manually to the
base Makefile.

The package currently has only extensively been tested with large C++ projects
(using over 50 Makefiles).  The C++ source files should end on whatever is
set in the environment variable CPPEXT. C source files must end on ".c".

Installation of `prototype' includes editing of $PROTODIR/Makedefs.h' once,
when adjusting for a different Operating System (the default should work
for linux).

After that, nothing should need changing in any file of this package, but
when necessary - like in the case of a bug fix - then the major advantage
will be that it will immedeately effect all projects that use the prototype
Makefiles, without the need to change more then one file.

In order to use this package, simply type `makeproto' in every new
directory of your project that you want to create a new Makefile in.

The generated Makefiles contain only project specific data like extra
CFLAGS that are needed for the project.  Under normal circumstances you
don't need to edit these Makefiles when adding or deleting source files
or sub directories to the project.  The Makefile _rules_ are all included
directly from the $PROTODIR tree, using the "include" command.

There are five different types of Makefiles, for five different types of
directories:

- The 'Base' directory, which contains the 'Base Makefile'.

  The Base directory is the root of your projects' source tree.  Within this
  root you can have any number of directories with their own Makefile.

- The 'Main' directories, which contain the 'Main Makefile'

  Main directories contain the sources of one executable, and may contain
  any number of subdirectories.

- The 'Lib' directories, which contain the 'Library Makefile'

  Lib directories contain the sources of one library, and may contain any
  number of subdirectories.

- The 'Sub' directories, which contain the 'Subdirectory Makefile'

  A Subdirectory can contain more subdirectories and/or source files,
  which will all go into the executable or library that the sub-tree
  belongs to.

- The 'Test' directories, which contain the 'Test Makefile'

  Test directories (can) contain multiple, Single Source File test executables,
  with common libraries.  The test directories are not automatically descended
  and re-made when you do a 'make [all]'.

Example directory structure
---------------------------

An example directory structure looks like this:

base/
  |
  |--lib/
  |
  |--main/
  |     |--test/
  |     |--sub1/
  |     `--sub2/
  |
  |--lib1/
  |    |--test/
  |    `--sub/
  |
  `--lib2/
       `--sub/
            |--test/
            `--sub/
                 `--test

base/lib/ is used to put all static and shared libraries in that are produced
by Lib1 and Lib2.

The optional test/ directories contain test executables that test the sources
(libs) in the subdirectories where they reside.

sub/ directories contain source files that also go into their respective
executable or library.

main/ will contain one executable produced from all source files in main/,
sub1/ and sub2/.

Contents
--------

The five different Makefiles reside in the directories prototype/base,
prototype/main, prototype/lib, prototype/sub and prototype/test.

The prototype/scripts directory contains scripts to easily create new
directories with Makefiles in your project.

Finally, prototype/ itself contains this README file, LICENSE, LICENSE.sig,
LICENSE.QPL, INSTALL and the Makedefs.h.dist file.

The prototype/templ-inst directory contains yet undocumented stuff (you
could use it to automatically generate template instantiations, when using
-fno-implicit-templates).

Example project
---------------

Here follows an example, of setting up a small "Hello World" project.

Goal: We want to create a shared libary called "libhello.so.0.1.0".
      We want to create an executable that links with this library.
      It should call the library function hello(), which should print
      "Hello world".

After installation of `prototype', cut&paste the following in
an empty directory:

mkdir hello
cd hello
makeproto
mkdir hello
mkdir libhello
# Of course, you should normally use an editor for this one:
mv Makedefs.h Makedefs.h.tmp
sed s%'^#LDFLAGS+=.*$'%LDFLAGS+=-L../lib% Makedefs.h.tmp > Makedefs.h
rm Makedefs.h.tmp
cd hello
makeproto main
# Another "editor" session:
mv Makefile Makefile.tmp
sed s%'^SHAREDLIBS=$'%SHAREDLIBS=-lhello% Makefile.tmp > Makefile
rm Makefile.tmp
echo 'extern void hello(void);' > hello.cc
echo 'int main(void) { hello(); return 0; }' >> hello.cc
cd ../libhello
makeproto lib
echo '#include <iostream>' > hello.cc
echo 'void hello(void) { cout << "Hello World" << endl; }' >> hello.cc
cd ../hello
make
LD_LIBRARY_PATH=../lib hello

The result of the last two commands:

~/tmp/hello/hello>make
make[1]: Entering directory `/home/carlo/tmp/hello'
make[2]: Entering directory `/home/carlo/tmp/hello/libhello'
g++ -MM -g -Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Winline -Wwrite-strings -Werror -pipe -fno-exceptions  -I-  hello.cc >> .depend
g++ -g -Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Winline -Wwrite-strings -Werror -pipe -fno-exceptions -fpic  -I-  -c hello.cc -o hello.o
g++ -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.1.0 -fpic hello.o
/bin/rm -f ../lib/libhello.so*
mv libhello.so.0.1.0 ../lib
( cd ../lib; \
  ln -s libhello.so.0.1.0 libhello.so.0; \
  ln -s libhello.so.0 libhello.so )
make[2]: Leaving directory `/home/carlo/tmp/hello/libhello'
make[2]: Entering directory `/home/carlo/tmp/hello/hello'
g++ -MM -g -Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Winline -Wwrite-strings -Werror -pipe -fno-exceptions  -I-  hello.cc >> .depend
g++ -g -Wall -Woverloaded-virtual -Wundef -Wpointer-arith -Winline -Wwrite-strings -Werror -pipe -fno-exceptions  -I-  -c hello.cc
g++  -L../lib hello.o    -lhello -o hello
chmod 750 hello
make[2]: Leaving directory `/home/carlo/tmp/hello/hello'
make[1]: Leaving directory `/home/carlo/tmp/hello'
~/tmp/hello/hello>LD_LIBRARY_PATH=../lib hello
Hello World
