
I do not use prototype anymore; it is therefore not anymore maintained. If something breaks (ie, due to compiler changes) then feel free to tell me and I'll fix it. For my own projects I now use a project generator, which generates a full-blown cwautomacros/cdeh/automake/autoconf/libtool/doxygen/etc project; this is still work IN PROGRESS, but you can see a preview here. The generator itself is not online yet, mail me if you're interested.
Prototype Makefiles allows very fast project start ups: often no editing of Makefiles is needed at ALL.
Prototype Makefiles is a collection of shared Makefiles which are installed globally, and Makefile templates that can be copied into project directories using a simple script. The shared Makefiles contain the rules for building a project, cleaning it and making dependencies etc. The Makefile templates contain the data that is specific for each project. This separation avoids duplication of code in Makefiles and is therefore extremely easy to maintain and extend.
Download the tar ball below.
Unpack it with:
tar xzf prototype-1.10.tar.gz
This creates a subdirectory called prototype-1.10 in the current directory.
cd into prototype-1.10:
cd prototype-1.10
Pick a directory where you want to install the shared stuff:
./configure --prefix=/usr --datadir=/usr/share
See the INSTALL file for the meaning of the options.
If you are upgrading
./configure
and it will determine the prefix and datadir that you used before. |
Install the package:
make install
(Or gmake install if you are using FreeBSD)
The environment variable PROTODIR should point to the prototype installation directory ($(datadir)/prototype, where $(datadir) is set with --datadir while running ./configure, see the INSTALL file).
As an example, if you use bash as your shell, you could add to your ~/.profile the following line,
export PROTODIR=/usr/share/prototype
Edit $PROTODIR/Makedefs.h to set your own prefered default values for
CFLAGS and CXXFLAGS. Please note that this file is overwritten
the next time you upgrade (I'll fix that some day).
To test the successful installation (all of the above), run the command:
make test
Now you are ready to use the prototype Makefiles.
Create a new project directory and change directory into it:
mkdir myProject
cd myProject
Generate the base (project) Makefile:
makeproto
Note that you can not put sources in this directory, it wouldn't belong to anything.
Instead create a `main', `lib' or `sub' directory. For instance:
Create a directory and Makefile for the (or a) main executable:
mkdir aProgram
cd aProgram
makeproto main
Write code and just type make when you want to compile it!
Please, also read the README file that comes with the package.
Below is given a Real Life (tm) project Makefile for a large and complex
shared library which is divided up over several sub directories
(the Makefiles in each of these subdirectories are not given, but look
similar - with only data specific for that directory).
This file is everything that needs maintenance for this sub directory.
Everything that was added manually is made bold, the rest was
generated by typing `makeproto lib':
# Directory where the base Makefile resides:
BASEDIR=../..
# Library name, for example: "LIB=foo" -> libfoo.so and libfoo.a
# The version of the library is read from .$(LIB).version (which is
# automatically incremented 1 Minor Version every time you (re)install.
LIB=cw
# List of subdirectories:
SUBDIRS:=$(shell list=`/bin/ls -1 -t | egrep -v '^(CVS|include)$$'`; for i in $$list; do if test -d $$i; then echo $$i; fi; done)
# List of source files:
CXXSRC:=$(shell /bin/ls -1 -t -F *$(CPPEXT) 2>/dev/null | grep '\$(CPPEXT)$$')
# Library specific include flags, for example: -I$(BASEDIR)/include or -I.
INCLUDEFLAGS=
# Extra static libraries to link with:
STATICLIBS=
# Extra shared libraries to link with:
SHAREDLIBS=-lcwd
# Put here extra -L... flags
LIBFLAGS=
#-----------------------------------------------------------------------------
include $(PROTODIR)/lib/PTMakefile
#clean::
#depend::
#build::
version.cc: Makefile .cw.version
echo "char const* libcw_version = \"$(VERSION)\";" > version.cc
real-clean::
$(RM) -f version.cc
include .cw.version
CW_MAJOR:=$(VERSION_MAJOR)
CW_MINOR:=$(VERSION_MINOR)
CW_PATCH:=$(VERSION_PATCH)
CW_VERSION:=$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
install:
@( if [ -f $(BASEDIR)/lib/libcw.so.$(CW_VERSION) ]; then \
make .cw.install.timestamp; \
else \
echo "libcw.so.$(CW_VERSION) wasn't compiled yet"; \
fi )
.cw.install.timestamp: $(BASEDIR)/lib/libcw.so.$(CW_VERSION)
$(INSTALL) -g $(INSTALL_GROUP) -m 755 -o $(INSTALL_OWNER) $(BASEDIR)/lib/libcw.so.$(CW_VERSION) $(LIB_DIR)
touch .cw.install.timestamp
/sbin/ldconfig
ln -sf $(LIB_DIR)/libcw.so.$(CW_MAJOR) $(LIB_DIR)/libcw.so
$(INSTALL) -d $(PREFIX)/include/libcw
$(INSTALL) -g $(INSTALL_GROUP) -m 644 -o $(INSTALL_OWNER) include/libcw/*.h $(PREFIX)/include/libcw
@echo "VERSION_MAJOR=$(CW_MAJOR)" > .cw.version
@echo "VERSION_MINOR=$(CW_MINOR)" >> .cw.version
@echo "$(CW_PATCH)" | awk -- '{ printf ("VERSION_PATCH=%d\n", $$0 + 1) }' >> .cw.version
The use of the gcc commandline option -I- had been
deprecated for a while now. I just removed it from the PTMakefile's.
The test (make test) was fixed to work with modern C++ compilers that demand that std::cout is used instead of just cout.
Fixed the default Makedefs.h: the given example cause
CPPEXT to end on a space which then resulted in a total
failure of everything else (It must be: CPPEXT=.cc on it own
on a line, not CPPEXT=".cc" with or without a comment
behind it).
The test (make test) was fixed to work around a bug in the
libstdc++ that comes with for instance RedHat-7.0
(_G_CLOG_CONFLICT needs to be defined).
Support for FreeBSD: The path to make is now better
propagated so things work when you are using gmake for
instance. FreeBSDs find does not support
-mindepth -maxdepth or -printf,
therefore find has been replaced with a construction
using ls and grep.
All UNIX programs that used to be set in $PROTODIR/Makedefs.h
are now determined, including path, by ./configure.
During installation /bin/sh is used (bash is
still needed to use prototype makefiles).
./configure now tries to extract --prefix
and --datadir automatically from a previous install.
Fixed all Makefiles with a loop like
"for i in $(SUBDIRS); do".
The behaviour of for in bash-2 changed from bash-1.14
and prototype would not work with bash-2.
Only remove ELF executable files, not scripts, in target
real-clean.
Added CPPEXT to $PROTODIR/Makedefs.h.
Bug fixes for target real-clean: .cvsignore
files were wrongly deleted and recursion into sub directories was broken.
Target shared didn't create the $BASEDIR/lib directory, if it doesn't exist, before copying the shared library there.
A few minor bug fixes:
typing make in a subdirectory
caused the target .depend to be build while checking the
Makefile target.
This can fail since INCLUDEFLAGS is set by the
Makefile(s) in the parent directories now.
Also, it was possible that the dependency on subdirectory objects caused these object files to be rebuild with the rules of the parent Makefile. Both bugs have been fixed.
The INCLUDEFLAGS variable is now correctly
propagated to sub directories by replacing each occurance of
"-I" by "-I../".
$PROTODIR/Makedefs.h was corrected to include a
DFLAGS variable which can be set to -MM or
-M to produce respectively dependencies of only local
header files (between double quotes) or also system header files
(between angle brackets)
Of course you can change the default per project in your
$BASEDIR/Makedefs.h file.
If you upgrade from version 1.0, then please note that
you will have to set a new environment variable (CPPEXT)
and that the variable SRC has been spliced into two:
CSRC and CXXSRC, for C sources and
C++ sources respectively.
You will have to edit all your projects Makefiles and change
SRC into CXXSRC (assuming it's a
C++ project), sorry about that.
Also, CFLAGS is now only used for C sources,
you'll have to change CXXFLAGS for C++ projects.
Warning: Upgrading prototype will overwrite
$PROTODIR/Makedefs.h. If you made changes to that file
(most likely setting a different default CFLAGS), then you'll
have to redo that by hand after installing. You might
want to backup $PROTODIR/Makedefs.h before installing.