# Top level makefile for pvfs2

###############################################################
# LIST OF TARGETS WHICH MAY BE USED WHEN RUNNING MAKE:
#
# all            default rule; builds libs, server, and test programs
# clean          cleans up files
# distclean      _really_ cleans up; returns to pristine tree
# docs           builds documentation in docs subdirectory
# docsclean      cleans up documentation files
# publish        copy over documents to the PVFS.org web pags
# admintools     builds admin tools
# kernapps       builds userland helper programs for kernel driver 
# statecomp      builds only the statecomp component
# cscope         generates information for cscope utility
# tags           generates tags file for use by editors
# codecheck      checks source code for nonconformance to our std.
# kmod           builds 2.6.x kernel module
# kmod24         builds 2.4.x kernel module
# kmod_install   installs 2.6.x module in default module location
# kmod24_install installs 2.4.x module in default module location
# 
# NOTE: you can also specify any single object or executable to
#    build by providing its name (including the relative path) as the
#    make target
#

###############################################################
# General documentation
#
# This is a single makefile that runs the entire pvfs2 build
# process.  There are no makefiles in subdirectories.  For a
# general introduction to this approach, please read this document
# by Peter Miller:
#
# http://www.tip.net.au/~millerp/rmch/recu-make-cons-harm.html
#
# Each subdirectory contains a module.mk file that gets included
# when make is executed.  These module.mk files tell make about the
# files in each subdirectory that must be built, including any
# special case rules.  Make uses this information to generate a
# sinle dependency graph and orchestrate the build process from this
# top level directory.
#
# We categorize our source depending on what it will be used for.
# For example, there are lists of source files for building the
# server, building the library, building documentation, etc.
#

###############################################################
# Generic makefile setup 

# define a few generic variables that we need to use
srcdir = .
prefix = /usr/local/bin/pvfs2-layout/
mandir = ${prefix}/man
exec_prefix = ${prefix}


SHELL = /bin/sh
INSTALL = /usr/bin/install -c
# TODO: should probably check for bison and flex in configure
BISON = bison
FLEX = flex
BUILD_GM = 
BUILD_IB = 
BUILD_VIS = 
BUILD_KARMA = 
BUILD_EPOLL = 
BUILD_SERVER = 
NEEDS_LIBRT = 
TARGET_OS_DARWIN = 
TARGET_OS_LINUX = 1
GNUC = 1
INTELC = 
# configure default is silent, unless --enable-verbose-build in
# which case QUIET_COMPILE will _not_ be defined.  Further allow
# silence to be overriden with "make V=1".
QUIET_COMPILE = 1
ifdef V
    QUIET_COMPILE = 0
endif
LINUX_KERNEL_SRC = /mnt/home/dhildebz/src/pnfspvfs2/kernels/cvs/pnfs-2.6.16-iota/
LINUX24_KERNEL_SRC = 

ifeq ($(QUIET_COMPILE),1)
  # say a one-line description of the action, do not echo the command
  Q=@echo
  E=@
else
  # do not say the short Q lines, but do echo the entire command
  Q=@echo >/dev/null
  E=
endif

# build which client libs
build_shared = no
build_static = yes

# Eliminate all default suffixes.  We want explicit control.
.SUFFIXES:

# PHONEY targets are targets that do not result in the generation
#    of a file that has the same name as the target.  Listing them
#    here keeps make from accidentally doing too much work (see GNU
#    make manual).
.PHONY: all clean dist distclean docs docsclean publish cscope tags codecheck statecomp admintools kernapps

################################################################
# Find project subdirectories

# MODULES is a list of subdirectories that we wish to operate on.
#    They are identified by the presence of module.mk files (makefile
#    includes).
MODULES := $(shell find . -name "*.mk" | sed -e 's/^.\///;s/module.mk//')

# List of directories to search for headers.
INCLUDES := \
    src/client/sysint \
    src/common/misc \
    src/common/quickhash \
    src/common/quicklist \
    src/common/dotconf \
    src/common/id-generator \
    src/common/gossip \
    src/common/gen-locks \
    src/io/trove \
    src/io/bmi \
    src/io/description \
    src/io/buffer \
    src/io/job \
    src/io/dev \
    src/proto

#################################################################
# Setup global flags

# These should all be self explanatory; they are standard flags
# for compiling and linking unless otherwise noted
CC = gcc
LD = gcc
BUILD_CC = gcc
BUILD_LD = gcc
CFLAGS =  -DNDEBUG -O3 -DGOSSIP_DISABLE_DEBUG -DGOSSIP_ENABLE_BACKTRACE
LDFLAGS =  -rdynamic
SERVER_LDFLAGS =  -rdynamic
LDSHARED = $(CC) -shared
PICFLAGS = -fPIC
LDFLAGS += -Llib 
SERVER_LDFLAGS += -Llib
LIBS += -lpvfs2  
MMAP_RA_CACHE = 
TRUSTED_CONNECTIONS = 
REDHAT_RELEASE = 
NPTL_WORKAROUND = 
# for Solaris:
# LIBS += -lsocket -lnsl

  # enable BMI TCP module
CFLAGS += -D__STATIC_METHOD_BMI_TCP__
  # enable Flow debugging protocol
#CFLAGS += -D__STATIC_FLOWPROTO_DUMP_OFFSETS__
  # enable new style Flow BMI/Trove protocol
CFLAGS += -D__STATIC_FLOWPROTO_MULTIQUEUE__
  # turn on large file support by default
CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
  # include current directory (for pvfs2-config.h)
CFLAGS += -I .
  # setup general warning levels and gcc options
CFLAGS += -I $(srcdir)/include -I include -I $(srcdir)
  # add selected include directories
CFLAGS += $(patsubst %,-I$(srcdir)/%,$(INCLUDES))
  # add package version information
CFLAGS += -DPVFS2_VERSION="\"1.4.1pre1-2006-05-12-160950\""
  # special Intel cc options, all warnings, but disable:
  # remark #279: controlling expression is constant
  #   shows up in ifdefs such as "do { ... } while (0)" construct
INTEL_CFLAGS := -Wall -wd279
  # special gcc options
GCC_CFLAGS := -Wall -Wstrict-prototypes -pipe

################################################################
# Setup component specific flags

# the server can use a threaded trove and job configuration.
# Working combinations of trove/job thread configurations
# are as follows:
#
# NOTE: __PVFS2_TROVE_SUPPORT__, and __GEN_POSIX_LOCKING__
# are required for all server configurations 
#
# config 1)
# =========
# __PVFS2_TROVE_THREADED__
# __PVFS2_JOB_THREADED__
# __PVFS2_TROVE_AIO_THREADED__ (auto detected MISC_TROVE_FLAGS)
# e.g.
#
#SERVERCFLAGS = -D__GEN_POSIX_LOCKING__ -D__PVFS2_JOB_THREADED__ \
#-D__PVFS2_TROVE_THREADED__ -D__PVFS2_TROVE_AIO_THREADED__ \
#-D__PVFS2_TROVE_SUPPORT__
#
# config 2)
# =========
# __PVFS2_TROVE_THREADED__
# __PVFS2_JOB_THREADED__
# e.g.
#
#SERVERCFLAGS = -D__GEN_POSIX_LOCKING__ -D__PVFS2_JOB_THREADED__ \
#-D__PVFS2_TROVE_THREADED__ -D__PVFS2_TROVE_SUPPORT__
#
# config 3)
# =========
# none (non-threaded)
# e.g.
#
#SERVERCFLAGS = -D__GEN_POSIX_LOCKING__ -D__PVFS2_TROVE_SUPPORT__

SERVERCFLAGS = -D__GEN_POSIX_LOCKING__ -D__PVFS2_JOB_THREADED__ \
-D__PVFS2_TROVE_THREADED__ -D__PVFS2_TROVE_AIO_THREADED__  \
-D__PVFS2_TROVE_SUPPORT__ -D__PVFS2_SERVER__

# server side flow protocol connecting BMI with NCAC cache
SERVERCFLAGS += -D__STATIC_FLOWPROTO_BMI_CACHE__

SERVERLIBS = -lpvfs2-server   -lpthread 

ifdef NEEDS_LIBRT 
	SERVERLIBS += -lrt
endif

# you can optionally disable thread safety support in the client
# though it's not recommended unless *required*.
#
# run ./configure --help for information on how to do this cleanly.
LIBCFLAGS= -D__GEN_POSIX_LOCKING__ -D__PVFS2_CLIENT__
LIBTHREADEDCFLAGS=-D__GEN_POSIX_LOCKING__ -D__PVFS2_JOB_THREADED__
LIBS += -lpthread

################################################################
# enable GM if configure detected it

ifdef BUILD_GM
	CFLAGS += -I /include -I /include/gm
	CFLAGS += -D__STATIC_METHOD_BMI_GM__
	# TODO: later on we will want the ability to modify this at configure
	# time
	CFLAGS += -DENABLE_GM_BUFPOOL
	LDFLAGS += -L /lib
	SERVER_LDFLAGS += -L /lib
	LIBS += -lgm
	SERVERLIBS += -lgm
endif

#####################################
# enable IB if configure requested it

ifdef BUILD_IB
    # other settings in bmi_ib/module.mk.in
    CFLAGS += -D__STATIC_METHOD_BMI_IB__
    IBLIBS := -L \
	      -lvapi -lmtl_common -lmosal -lmpga -lpthread -ldl
    LIBS += $(IBLIBS)
    SERVERLIBS += $(IBLIBS)
endif

# enable mmap-readahead cache (unless disabled by configure)
ifdef MMAP_RA_CACHE
CFLAGS += 
endif

# enable trusted connections (unless disabled by configure)
ifdef TRUSTED_CONNECTIONS
CFLAGS += 
endif

# enable redhat-release patches (if detected and if any)
ifdef REDHAT_RELEASE
CFLAGS += 
endif

# Add gcc-specific flags if we know it is a gnu compiler.
ifdef GNUC
CFLAGS += $(GCC_CFLAGS)
endif
ifdef INTELC
CFLAGS += $(INTEL_CFLAGS)
endif

#################################################################
# Starter variables 

# NOTES: These variables are used to categorize the various source
#    files.  We let the makefile includes append to them so that we
#    gradually build up a list of source files without having to
#    list them all at the top level.

# ADMINSRC is source code for administrative programs
ADMINSRC :=
# ADMINSRC_SERVER special version of ADMINSRC for tools that need server 
# library
ADMINSRC_SERVER :=
# LIBSRC is source code for libpvfs2
LIBSRC :=
# SERVERSRC is souce code for the pvfs2 server
SERVERSRC :=
# DOCSRC is source code for documentation
DOCSRC :=
# VISSRC is the source code for visualization tools
VISSRC :=
# VISMISCSRC is a collection of sources that must be built into objects for 
#    visualization tools
VISMISCSRC :=
# KARMASRC is source for the karma gui
KARMASRC :=
# userland helper programs for kernel drivers
KERNAPPSRC :=
# MISCSRC are sources that don't fall into the other categories
MISCSRC := 
# c files generated from state machines
SMCGEN :=

################################################################
# Top level (default) targets

ifdef BUILD_SERVER
# SERVER_STUB is a wrapper script that export the LD_ASSUME_KERNEL variable for
#    systems with buggy NPTL/Pthread implementations, such as early RedHat
#    EL 3 distributions
SERVER_STUB := src/server/pvfs2-server-stub
# SERVER is the pvfs2 server
SERVER := src/server/pvfs2-server
endif

# LIBRARIES is a list of the pvfs2 client libraries
LIBRARIES :=
ifeq ($(build_shared),yes)
LIBRARIES_SHARED = lib/libpvfs2.so
LIBRARIES += $(LIBRARIES_SHARED)
endif
ifeq ($(build_static),yes)
LIBRARIES_STATIC = lib/libpvfs2.a
LIBRARIES += $(LIBRARIES_STATIC)
endif

################################################################
# Default target forward pointer, to avoid other targets in make stubs
all::

################################################################
# Makefile includes

# this is how we pull build information from all of the project
#    subdirectories, make sure to catch top level module.mk as well
include module.mk
include $(patsubst %, %/module.mk, $(MODULES))

################################################################
# Derived file lists

# NOTES: At this point, the subdirectory makefile includes have informed
#    us what the source files are.  Now we want to generate some
#    other lists (such as objects, executables, and dependency files)
#    by manipulating the lists of source files

# LIBOBJS is a list of objects to put in the client lib
LIBOBJS := $(patsubst %.c,%.o, $(filter %.c,$(LIBSRC)))
# LIBPICOBJS are the same, but compiled for use in a shared library
LIBPICOBJS := $(patsubst %.c,%.po, $(filter %.c,$(LIBSRC)))
# LIBDEPENDS is a list of dependency files for the client lib
LIBDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(LIBSRC)))

# LIBTHREADEDOBJS is a list of objects to put in the multithreaded client lib
LIBTHREADEDOBJS := $(patsubst %.c,%-threaded.o, $(filter %.c,$(LIBSRC)))
# LIBTHREADEDPICOBJS are the same, but compiled for use in a shared library
LIBTHREADEDPICOBJS := $(patsubst %.c,%-threaded.po, $(filter %.c,$(LIBSRC)))
# LIBTHREADEDDEPENDS is a list of dependency files for the multithreaded client lib
LIBTHREADEDDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(LIBSRC)))
# ADMINOBJS is a list of admin program objects
ADMINOBJS := $(patsubst %.c,%.o, $(filter %.c,$(ADMINSRC)))
# ADMINTOOLS is a list of admin program executables
ADMINTOOLS := $(patsubst %.c,%, $(filter %.c, $(ADMINSRC)))
# ADMINDEPENDS is a list of dependency files for admin programs
ADMINDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(ADMINSRC)))

ifdef BUILD_SERVER
    ADMINOBJS_SERVER := $(patsubst %.c,%.o, $(filter %.c,$(ADMINSRC_SERVER)))
    ADMINTOOLS_SERVER := $(patsubst %.c,%, $(filter %.c, $(ADMINSRC_SERVER)))
    ADMINDEPENDS_SERVER := $(patsubst %.c,%.d, $(filter %.c,$(ADMINSRC_SERVER)))
    # SERVEROBJS is a list of objects to put into the server
    SERVEROBJS := $(patsubst %.c,%-server.o, $(filter %.c,$(SERVERSRC)))
    # SERVERDEPENDS is a list of dependency files for the server
    SERVERDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(SERVERSRC)))
endif

# MISCOBJS is a list of misc. objects not in the above categories
MISCOBJS := $(patsubst %.c,%.o, $(filter %.c,$(MISCSRC)))
# MISCDEPENDS is a list of dependency files for misc. objects
MISCDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(MISCSRC)))

# KERNAPPOBJS is a list of kernel driver userland objects
KERNAPPOBJS := $(patsubst %.c,%.o, $(filter %.c,$(KERNAPPSRC)))
# KERNAPPS is a list of kernel driver userland executables
KERNAPPS := $(patsubst %.c,%, $(filter %.c, $(KERNAPPSRC)))
# KERNAPPDEPENDS is a list of dependency files for kernel driver userland
# objects
KERNAPPDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(KERNAPPSRC)))

# VISOBJS is a list of visualization program objects
VISOBJS := $(patsubst %.c,%.o, $(filter %.c,$(VISSRC)))
# VISS is a list of visualization program executables
VISS := $(patsubst %.c,%, $(filter %.c, $(VISSRC)))
# VISDEPENDS is a list of dependency files for visualization programs
VISDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(VISSRC)))
# VISMISCOBJS is a list of misc. vis objects not in the above categories
VISMISCOBJS := $(patsubst %.c,%.o, $(filter %.c,$(VISMISCSRC)))
# VISMISCDEPENDS is a list of dependency files for vis misc. objects
VISMISCDEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(VISMISCSRC)))

# KARMAOBJS, KARMADEPENDS for the karma gui (requires gtk2.0)
KARMAOBJS := $(patsubst %.c,%.o, $(filter %.c,$(KARMASRC)))
KARMADEPENDS := $(patsubst %.c,%.d, $(filter %.c,$(KARMASRC)))

# state machine generation tool
# cannot build statecomp objects with the cross compiler, as we 
# build and run the tool on the build host at compile-time
#STATECOMPOBJS := $(patsubst %.c,%.o,$(STATECOMPSRC))
#STATECOMPDEPS := $(patsubst %.c,%.d,$(STATECOMPSRC))

# DOCSPDF, DOCSPS, and DOCSHTML are lists of documentation files generated 
#   from latex
DOCSPDF := $(patsubst %.tex,%.pdf, $(filter %.tex,$(DOCSRC)))
DOCSPS := $(patsubst %.tex,%.ps, $(filter %.tex,$(DOCSRC)))
DOCSHTML := $(patsubst %.tex,%.html, $(filter %.tex,$(DOCSRC)))

# DOCSCRUFT is a list of intermediate files generated by latex
DOCSCRUFT := $(patsubst %.tex,%.aux, $(filter %.tex,$(DOCSRC)))
DOCSCRUFT += $(patsubst %.tex,%.dvi, $(filter %.tex,$(DOCSRC)))
DOCSCRUFT += $(patsubst %.tex,%.log, $(filter %.tex,$(DOCSRC)))
DOCSCRUFT += $(patsubst %.tex,%.toc, $(filter %.tex,$(DOCSRC)))

# DEPENDS is a global list of all of our dependency files.  
# NOTE: sort is just a trick to remove duplicates; the order
#   doesn't matter at all.
DEPENDS := $(sort $(LIBDEPENDS) $(SERVERDEPENDS) $(MISCDEPENDS) \
    $(ADMINDEPENDS) $(ADMINDEPENDS_SERVER) $(KERNAPPDEPENDS) $(VISDEPENDS) \
    $(VISMISCDEPENDS) $(KARMADEPENDS) $(STATECOMPDEPS))

####################################################################
# Rules and dependencies

# default rule builds server, library, and applications
all:: $(SERVER) $(KARMA) $(LIBRARIES) admintools $(VISS) $(KARMA)

# target for building admin tools
admintools: $(ADMINTOOLS) $(ADMINTOOLS_SERVER)

# target for building kernel driver userland programs
kernapps: $(KERNAPPS)

# Build linux-2.6 kernel module if requested.
# Can't use the actual file target since we don't know how to figure out
# dependencies---only the kernel source tree can do that.
ifneq (,$(LINUX_KERNEL_SRC))
.PHONY: kmod
kmod: just_kmod kernapps
just_kmod:
	@$(MAKE) --no-print-directory -C src/kernel/linux-2.6
endif

# Build linux-2.4 kernel module if requested.
ifneq (,$(LINUX24_KERNEL_SRC))
.PHONY: kmod24
kmod24: just_kmod24 kernapps
just_kmod24: 
	@$(MAKE) --no-print-directory -C src/kernel/linux-2.4
endif

# Just like dir, but strip the slash off the end, to be pretty.
dirname = $(patsubst %/,%,$(dir $(1)))

# Generate the canonical in-tree location of a file, given a possibly
# out-of-tree reference.
canonname = $(patsubst $(srcdir)/%,%,$(call dirname,$(1)))

# Grab any CFLAGS defined by the make stub for a particular file, and
# for the directory in which the source resides.
# Always add the source directory in question for "local" includes.
# Similar for ldflags.
modcflags = $(MODCFLAGS_$(call canonname,$(1))) \
            $(MODCFLAGS_$(patsubst $(srcdir)/%,%,$(1))) \
	    -I$(srcdir)/$(call dirname,$(1))
modldflags = $(MODLDFLAGS_$(call canonname,$(1))) \
             $(MODLDFLAGS_$(patsubst $(srcdir)/%,%,$(1)))

# note: this will look better if you use two tabs instead of spaces between
# SHORT_NAME and the object

# rule for building the pvfs2 server
$(SERVER): src/server/pvfs2-server-server.o lib/libpvfs2-server.a 
	$(Q) "  LD		$@"
	$(E)$(LD) $^ -o $@ $(SERVER_LDFLAGS) $(SERVERLIBS)

# special rules for admin tool objects which also require server components
$(ADMINOBJS_SERVER): %.o: %.c
	$(Q) "  CC		$@"
	$(E) $(CC) $(SERVERCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -c -o $@

# special rules for admin tools which also require server components
$(ADMINTOOLS_SERVER): %: %.o
	$(Q) "  LD		$@"
	$(E)$(LD) $< $(LDFLAGS) $(SERVER_LDFLAGS) $(SERVERLIBS) -o $@

# rule for building the pvfs2 library
lib/libpvfs2.a: $(LIBOBJS)
	$(Q) "  RANLIB	$@"
	$(E)$(INSTALL) -d lib
	$(E)ar rcs $@ $(LIBOBJS)

# rule for building the _multithreaded_ pvfs2 library
lib/libpvfs2-threaded.a: $(LIBTHREADEDOBJS)
	$(Q) "  RANLIBTHREADED	$@"
	$(E)$(INSTALL) -d lib
	$(E)ar rcs $@ $(LIBTHREADEDOBJS)

# rule for building the pvfs2 library
lib/libpvfs2.so: $(LIBPICOBJS)
	$(Q) "  LDSO		$@"
	$(E)$(INSTALL) -d lib
	$(E)$(LDSHARED) -o $@ $(LIBPICOBJS)

# rule for building the pvfs2 _multithreaded_ library
lib/libpvfs2-threaded.so: $(LIBTHREADEDPICOBJS)
	$(Q) "  LDSO		$@"
	$(E)$(INSTALL) -d lib
	$(E)$(LDSHARED) -o $@ $(LIBTHREADEDPICOBJS)

# rule for building the pvfs2 server library
lib/libpvfs2-server.a: $(SERVEROBJS)
	$(Q) "  RANLIB	$@"
	$(E)$(INSTALL) -d lib
	$(E)ar rcs $@ $(SERVEROBJS)

# rule for building karma gui and its objects
$(KARMA): $(KARMAOBJS) $(LIBRARIES)
	$(Q) "  LD		$@"
	$(E)$(LD) -o $@ $(LDFLAGS) $(KARMAOBJS) $(LIBS) $(call modldflags,$<)

# rule for building vis executables from object files
$(VISS): %: %.o $(VISMISCOBJS) $(LIBRARIES)
	$(Q) "  LD		$@"
	$(E)$(LD) -o $@ $(LDFLAGS) $< $(VISMISCOBJS) $(LIBS) $(call modldflags,$<)

# default rule for building executables from object files
%: %.o $(LIBRARIES)
	$(Q) "  LD		$@"
	$(E)$(LD) -o $@ $(LDFLAGS) $< $(LIBS) $(call modldflags,$<)

# rule for building server objects
%-server.o: %.c
	$(Q) "  CC		$@"
	$(E)$(CC) $(SERVERCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -c -o $@

# default rule for building objects for threaded library
%-threaded.o: %.c
	$(Q) "  CC		$@"
	$(E)$(CC) $(LIBTHREADEDCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -c -o $@

# rule for building shared objects for threaded library
%-threaded.po: %.c
	$(Q) "  CCPIC		$@"
	$(E)$(CC) $(LIBTHREADEDCFLAGS) $(CFLAGS) $(PICFLAGS) $(call modcflags,$<) $< -c -o $@

# default rule for building objects 
%.o: %.c
	$(Q) "  CC		$@"
	$(E)$(CC) $(LIBCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -c -o $@

# rule for building shared objects 
%.po: %.c
	$(Q) "  CCPIC		$@"
	$(E)$(CC) $(LIBCFLAGS) $(CFLAGS) $(PICFLAGS) $(call modcflags,$<) $< -c -o $@

# bison and yacc
%.c: %.y
	$(Q) "  BISON		$@"
	$(E)$(BISON) -d $< -o $@

%.c: %.l
	$(Q) "  FLEX		$@"
	$(E)$(FLEX) -o$@ $<

# handy rule to generate cpp-output file, for debugging
.PHONY: FORCE
%-server.i: %.c FORCE
	$(Q) "  CPP		$@"
	$(E)$(CC) $(SERVERCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -E -o $@

%.i: %.c FORCE
	$(Q) "  CPP		$@"
	$(E)$(CC) $(LIBCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -E -o $@

%-threaded.i: %.c FORCE
	$(Q) "  CPP		$@"
	$(E)$(CC) $(LIBTHREADEDCFLAGS) $(CFLAGS) $(call modcflags,$<) $< -E -o $@

# all applications depend on the pvfs2 library
$(ADMINTOOLS): %: %.o $(LIBRARIES)
$(ADMINTOOLS_SERVER): %: %.o $(LIBRARIES) lib/libpvfs2-server.a
$(KERNAPPS): %: %.o $(LIBRARIES)

# target for building _just_ the statecomp tool
#statecomp: $(STATECOMP)
#$(STATECOMP): $(STATECOMPOBJS)
#	$(Q) "  LD		$@"
#	$(E)$(LD) -o $@ $(LDFLAGS) $(STATECOMPOBJS)

# rule for generating cscope information
cscope:
	find /mnt/home/dhildebz/src/pnfspvfs2/pvfs2/pvfs2cvs-layoutdriver -iname "*.[ch]" -o -iname "*.sm" \
		 > $(srcdir)/cscope.files
	( cd /mnt/home/dhildebz/src/pnfspvfs2/pvfs2/pvfs2cvs-layoutdriver; cscope -be -i /mnt/home/dhildebz/src/pnfspvfs2/pvfs2/pvfs2cvs-layoutdriver/cscope.files )

# build editor tags file over all source files *.[ch] *.sm and
# some known scripts
tags:
	( find $(addprefix $(srcdir)/,$(MODULES)) $(srcdir)/include . \
	    $(srcdir)/src/kernel/linux-2.6 \
	    -maxdepth 1 -name '*.[ch]' -o -name '*.sm' ;\
	  echo $(srcdir)/src/apps/admin/pvfs2-genconfig \
	) | ctags --excmd=pattern -B --langmap=c:+.sm -I __hidden,DOTCONF_CB -L-

# rule for running code check
codecheck:
	find $(srcdir) -iname "*.[ch]" | xargs -n 1 $(srcdir)/maint/pvfs2codecheck.pl

# target for building documentation
docs: $(DOCSPS) $(DOCSPDF) $(DOCSHTML)

publish: docs
	$(srcdir)/maint/pvfs2-publish-pages `pwd`/doc

# rule for cleaning up documentation
# latex2html puts all its output in a directory
docsclean: 
	rm -f $(DOCSPS) $(DOCSPDF) $(DOCSCRUFT)
	rm -rf $(basename $(DOCSHTML))

# top rule for cleaning up tree
clean:: 
	$(Q) "  CLEAN"
	$(E)rm -f $(LIBOBJS) $(SERVEROBJS) $(MISCOBJS) \
		$(LIBRARIES) $(DEPENDS) $(SERVER) \
		$(ADMINOBJS) $(ADMINOBJS_SERVER) $(ADMINTOOLS)\
		$(ADMINTOOLS_SERVER) lib/libpvfs2-server.a\
		$(KERNAPPOBJS) $(KERNAPPS) \
		$(VISS) $(VISMISCOBJS) $(VISOBJS) $(VISDEPENDS)\
		$(VISMISCDEPENDS) $(KARMAOBJS) $(LIBPICOBJS) \
		$(STATECOMP) $(STATECOMPOBJS) \
		src/server/pvfs2-server-server.o \
		src/apps/karma/karma 
ifndef DIST_RELEASE
	$(E)rm -f $(STATECOMPGEN) 
endif

ifneq (,$(LINUX_KERNEL_SRC))
clean::
	@$(MAKE) --no-print-directory -C src/kernel/linux-2.6 clean
endif

ifneq (,$(LINUX24_KERNEL_SRC))
clean::
	@$(MAKE) --no-print-directory -C src/kernel/linux-2.4 clean
endif

# builds a tarball of the source tree suitable for distribution
dist: $(SMCGEN) cleaner
	@sh $(srcdir)/maint/make-dist.sh $(srcdir) 1.4.1pre1-2006-05-12-160950

# some stuff that is cleaned in both distclean and dist targets
cleaner: clean
	rm -f tags
	rm -f src/kernel/linux-2.6/Makefile
	rm -f src/kernel/linux-2.4/Makefile
	rm -f maint/mpi-depend.sh
	rm -f examples/pvfs2-server.rc
	rm -f examples/fs.conf examples/server.conf-localhost
	rm -rf autom4te*.cache
	rm -f $(srcdir)/cscope.out $(srcdir)/cscope.files
	rm -f config.log config.status config.cache 
	rm -f pvfs2-1.4.1pre1-2006-05-12-160950.tar.gz

# _really_ clean the tree; should go back to pristine state
# except, don't remove generated .c files if this is a distributed release
distclean: cleaner docsclean
	find . -name "module.mk" -exec rm \{\} \;
	rm -f Makefile pvfs2-config.h
	rm -f src/server/simple.conf
	rm -f src/server/server.conf-localhost
	rm -f src/apps/admin/pvfs2-config
ifndef DIST_RELEASE
	rm -f $(SMCGEN)
endif

# this is where we include all of our automatic dependencies.
# NOTE: we wrap this in ifneq's in order to prevent the
#    dependencies from being generated for special targets that don't 
#    require them
ifeq (,$(filter statecomp clean distclean dist docs cscope tags nodep,$(MAKECMDGOALS)))
-include $(DEPENDS)
endif
# add this as a make goal to disable rebuilding dependencies
.PHONY: nodep
nodep:; @:

# default rule for generating dependency files
%.d: %.c
	$(Q) "  DEP		$@"
	$(E)$(srcdir)/maint/depend.sh $(call dirname,$*) $(CFLAGS) $(call modcflags,$<) $< > $@

# default rules for building documents in .tex format:
# TODO: these documentation rules are a big hack!
%.dvi: %.tex
	$(srcdir)/maint/pvfs2latexwrapper.pl -i $< -o $@
%.ps: %.dvi
	( cd $(@D); dvips -t letter $(<F) -o $(@F) )
%.pdf: %.dvi
	( cd $(@D); dvipdf $(<F) $(@F) )
%.html: %.tex
	$(srcdir)/maint/pvfs2latexwrapper.pl -html -i $(basename $<).tex -o $@
	$(srcdir)/maint/pvfs2htmlfixup.sh $(@D)/*/$(@F)

# rule for automatically generated source files
# NOTE: this rule is disabled in release snapshots
%.c: %.sm src/common/statecomp/statecomp
	$(Q) "  SMC		$@"
	$(E)src/common/statecomp/statecomp $< $@

# if this is not a distribution tarball, then drop some example
# config files in the server build directory with good defaults for
# debugging
ifndef DIST_RELEASE
all:: src/server/simple.conf src/server/server.conf-localhost
endif
src/server/simple.conf src/server/server.conf-localhost: src/apps/admin/pvfs2-genconfig
	$(Q) "  GENCONFIG     $@"
	$(E)$(srcdir)/src/apps/admin/pvfs2-genconfig --protocol tcp --port 3334 \
 --ioservers localhost --metaservers localhost --logfile /tmp/pvfs2-server.log \
 --storage /tmp/pvfs2-test-space --logging "server,network,storage,flow" \
 --quiet src/server/simple.conf src/server/server.conf

# whether this is a distribution tarball or not, drop some config files
# into the "examples" subdir of the build dir
all:: examples/fs.conf examples/server.conf-localhost
examples/fs.conf examples/server.conf-localhost: src/apps/admin/pvfs2-genconfig
	$(Q) "  GENCONFIG     $@"
	$(E)$(srcdir)/src/apps/admin/pvfs2-genconfig --protocol tcp --port 3334 \
 --ioservers localhost --metaservers localhost --logfile /tmp/pvfs2-server.log \
 --storage /tmp/pvfs2-test-space \
 --quiet examples/fs.conf examples/server.conf

install_doc:
	install -d $(mandir)/man1
	install -d $(mandir)/man5
	install -m 644 $(srcdir)/doc/man/*.1 $(mandir)/man1
	install -m 644 $(srcdir)/doc/man/*.5 $(mandir)/man5

install:: all install_doc
	install -d $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-request.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-debug.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-sysint.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-mgmt.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-types.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-util.h $(prefix)/include
	install -m 644 $(srcdir)/include/pvfs2-encode-stubs.h $(prefix)/include

	install -d $(prefix)/lib
	install -m 755 $(LIBRARIES) $(prefix)/lib

ifdef TARGET_OS_DARWIN
#       TOC needs to be regenerated in libs after they get moved
	ranlib $(patsubst %,$(prefix)/%,$(LIBRARIES))
endif

	install -d $(prefix)/bin
	install -m 755 $(ADMINTOOLS) $(prefix)/bin
	install -m 755 src/apps/admin/pvfs2-config $(prefix)/bin
	@# if we ever auto-generate genconfig, remove the $(srcdir)
	install -m 755 $(srcdir)/src/apps/admin/pvfs2-genconfig $(prefix)/bin
ifdef BUILD_KARMA
	install -m 755 $(KARMA) $(prefix)/bin
endif

	install -d $(prefix)/sbin

ifdef BUILD_SERVER
	install -m 755 $(ADMINTOOLS_SERVER) $(prefix)/bin
    ifeq ($(NPTL_WORKAROUND),)
	install -m 755 $(SERVER) $(prefix)/sbin
    else
	install -m 755 $(srcdir)/$(SERVER_STUB) $(prefix)/sbin/pvfs2-server
	install -m 755 $(SERVER) $(prefix)/sbin/pvfs2-server.bin
    endif
endif

ifneq (,$(LINUX_KERNEL_SRC))

NUM_UTS_LINES := $(shell grep -c UTS_RELEASE $(LINUX_KERNEL_SRC)/include/linux/version.h)
ifeq ($(NUM_UTS_LINES),1)
    KERNEL_VERS := $(shell grep UTS_RELEASE $(LINUX_KERNEL_SRC)/include/linux/version.h | cut -d\" -f2)
else
    KERNEL_VERS := $(shell uname -r)
endif
KMOD_DIR ?= $(kmod_prefix)/lib/modules/$(KERNEL_VERS)/kernel/fs/pvfs2

.PHONY: just_kmod_install
just_kmod_install: just_kmod
	install -d $(KMOD_DIR)
	install -m 755 src/kernel/linux-2.6/pvfs2-pnfs.ko $(KMOD_DIR)

.PHONY: kmod_install
kmod_install: kmod kernapps just_kmod_install
	install -d $(prefix)/sbin
	install -m 755 $(KERNAPPS) $(prefix)/sbin
endif

ifneq (,$(LINUX24_KERNEL_SRC))

NUM_UTS_LINES := $(shell grep -c UTS_RELEASE $(LINUX24_KERNEL_SRC)/include/linux/version.h)
ifeq ($(NUM_UTS_LINES),1)
    KERNEL_VERS := $(shell grep UTS_RELEASE $(LINUX24_KERNEL_SRC)/include/linux/version.h | cut -d\" -f2)
else
    KERNEL_VERS := $(shell uname -r)
endif
KMOD_DIR := $(kmod_prefix)/lib/modules/$(KERNEL_VERS)/kernel/fs/pvfs2

.PHONY: just_kmod24_install
just_kmod24_install: just_kmod24
	install -d $(KMOD_DIR)
	install -m 755 src/kernel/linux-2.4/pvfs2.o $(KMOD_DIR)

.PHONY: kmod24_install
kmod24_install: kmod24 kernapps just_kmod24_install
	install -d $(prefix)/sbin
	install -m 755 $(KERNAPPS) $(prefix)/sbin
	install -m 755 src/apps/kernel/linux/mount.pvfs2 $(prefix)/sbin
	@echo ""
	@echo "For improved linux-2.4 support,"
	@echo "install $(prefix)/sbin/mount.pvfs2 to /sbin/mount.pvfs2"
	@echo ""
endif
