summaryrefslogtreecommitdiff
path: root/buildlib
diff options
context:
space:
mode:
Diffstat (limited to 'buildlib')
-rw-r--r--buildlib/defaults.mak101
-rw-r--r--buildlib/library.mak61
2 files changed, 162 insertions, 0 deletions
diff --git a/buildlib/defaults.mak b/buildlib/defaults.mak
new file mode 100644
index 000000000..b268c4b9b
--- /dev/null
+++ b/buildlib/defaults.mak
@@ -0,0 +1,101 @@
+# -*- make -*-
+
+# This file configures the default environment for the make system
+# The way it works is fairly simple, each module is defined in it's
+# own *.mak file. It expects a set of variables to be set to values
+# for it to operate as expected. When included the module generates
+# the requested rules based on the contents of its control variables.
+
+# This works out very well and allows a good degree of flexability.
+# To accomidate some of the features we introduce the concept of
+# local variables. To do this we use the 'Computed Names' feature of
+# gmake. Each module declares a LOCAL scope and access it with,
+# $($(LOCAL)-VAR)
+# This works very well but it is important to rembember that within
+# a rule the LOCAL var is unavailble, it will have to be constructed
+# from the information in the rule invokation. For stock rules like
+# clean this is simple, we use a local clean rule called clean/$(LOCAL)
+# and then within the rule $(@F) gets back $(LOCAL)! Other rules will
+# have to use some other mechanism (filter perhaps?) The reason such
+# lengths are used is so that each directory can contain several 'instances'
+# of any given module
+
+# A build directory is used by default, all generated items get put into
+# there. However unlike automake this is not done with a VPATH build
+# (vpath builds break the distinction between #include "" and #include <>)
+# but by explicly setting the BUILD variable. Make is invoked from
+# within the source itself which is much more compatible with compilation
+# environments.
+
+ifndef BUILD
+BUILD=$(BASE)/build
+endif
+
+# Base definitions
+INCLUDE := $(BUILD)/include
+BIN := $(BUILD)/bin
+LIB := $(BIN)
+OBJ := $(BUILD)/obj
+DEP := $(OBJ)
+
+# Module types
+LIBRARY_H=$(BASE)/buildlib/library.mak
+
+# Source location control
+# SUBDIRS specifies sub components of the module that
+# may be located in subdrictories of the source dir.
+# This should be declared before including this file
+SUBDIRS+=
+
+# Header file control.
+# TARGETDIRS indicitates all of the locations that public headers
+# will be published to.
+# This should be declared before including this file
+HEADER_TARGETDIRS+=
+
+# Options
+CXX = c++
+CC = cc
+CPPFLAGS+= -I$(INCLUDE)
+CXXFLAGS+= -Wall -g -fno-implicit-templates -fno-exceptions
+PICFLAGS+= -fPIC -DPIC
+LFLAGS+=
+INLINEDEPFLAG = -MD
+
+# Phony rules. Other things hook these by appending to the dependency
+# list
+.PHONY: headers library clean veryclean all binary program
+all: binary
+binary: library program
+headers library clean veryclean program:
+
+# Header file control. We want all published interface headers to go
+# into the build directory from thier source dirs. We setup some
+# search paths here
+vpath %.h $(SUBDIRS)
+$(INCLUDE)/%.h $(addprefix $(INCLUDE)/,$(addsuffix /%.h,$(HEADER_TARGETDIRS))) : %.h
+ cp $< $@
+
+# Dependency generation. We want to generate a .d file using gnu cpp.
+# For GNU systems the compiler can spit out a .d file while it is compiling,
+# this is specified with the INLINEDEPFLAG. Other systems might have a
+# makedep program that can be called after compiling, that's illistrated
+# by the DEPFLAG case.
+# Compile rules are expected to call this macro after calling the compiler
+ ifdef INLINEDEPFLAG
+ define DoDep
+ sed -e "1s/.*:/$(subst /,\\/,$@):/" $(basename $(@F)).d > $(DEP)/$(basename $(@F)).d
+ -rm -f $(basename $(@F)).d
+ endef
+else
+ ifdef DEPFLAG
+ define DoDep
+ $(CXX) $(DEPFLAG) $(CPPFLAGS) -o $@ $<
+ sed -e "1s/.*:/$(subst /,\\/,$@):/" $(basename $(@F)).d > $(DEP)/$(basename $(@F)).d
+ -rm -f $(basename $(@F)).d
+ endef
+ else
+ define DoDep
+ endef
+ endif
+endif
diff --git a/buildlib/library.mak b/buildlib/library.mak
new file mode 100644
index 000000000..1b814875f
--- /dev/null
+++ b/buildlib/library.mak
@@ -0,0 +1,61 @@
+# -*- make -*-
+
+# This creates a shared library.
+
+# Input
+# $(SOURCE) - The source code to use
+# $(HEADERS) - Exported header files and private header files
+# $(LIBRARY) - The name of the library without lib or .so
+# $(MAJOR) - The major version number of this library
+# $(MINOR) - The minor version number of this library
+
+# All output is writtin to .opic files in the build directory to
+# signify the PIC output.
+
+# See defaults.mak for information about LOCAL
+
+# Some local definitions
+LOCAL := lib$(LIBRARY).so.$(MAJOR).$(MINOR)
+$(LOCAL)-OBJS := $(addprefix $(OBJ)/,$(addsuffix .opic,$(notdir $(basename $(SOURCE)))))
+$(LOCAL)-DEP := $(addprefix $(DEP)/,$(addsuffix .d,$(notdir $(basename $(SOURCE)))))
+$(LOCAL)-HEADERS := $(addprefix $(INCLUDE)/,$(HEADERS))
+$(LOCAL)-SONAME := lib$(LIBRARY).so.$(MAJOR)
+
+# Install the command hooks
+headers: $($(LOCAL)-HEADERS)
+library: $(LIB)/lib$(LIBRARY).so $(LIB)/lib$(LIBRARY).so.$(MAJOR)
+clean: clean/$(LOCAL)
+veryclean: veryclean/$(LOCAL)
+
+# The clean rules
+.PHONY: clean/$(LOCAL) veryclean/$(LOCAL)
+clean/$(LOCAL):
+ -rm -f $($(@F)-OBJS) $($(@F)-DEP)
+veryclean/$(LOCAL): clean/$(LOCAL)
+ -rm -f $($(@F)-HEADERS) $(LIB)/lib$(LIBRARY).so*
+
+# Build rules for the two symlinks
+.PHONY: $(LIB)/lib$(LIBRARY).so.$(MAJOR) $(LIB)/lib$(LIBRARY).so
+$(LIB)/lib$(LIBRARY).so.$(MAJOR): $(LIB)/lib$(LIBRARY).so.$(MAJOR).$(MINOR)
+ ln -sf $(<F) $@
+$(LIB)/lib$(LIBRARY).so: $(LIB)/lib$(LIBRARY).so.$(MAJOR).$(MINOR)
+ ln -sf $(<F) $@
+
+# The binary build rule
+$(LIB)/lib$(LIBRARY).so.$(MAJOR).$(MINOR): $($(LOCAL)-HEADERS) $($(LOCAL)-OBJS)
+ echo Building shared library $@
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) $(PICFLAGS) $(LFLAGS) -o $@ \
+ -Wl,-soname -Wl,$($(@F)-SONAME) -shared $(filter %.opic,$^)
+
+# Compilation rules
+vpath %.cc $(SUBDIRS)
+$(OBJ)/%.opic: %.cc
+ echo Compiling $< to $@
+ $(CXX) -c $(INLINEDEPFLAG) $(CPPFLAGS) $(CXXFLAGS) $(PICFLAGS) -o $@ $<
+ $(DoDep)
+
+# Include the dependencies that are available
+The_DFiles = $(wildcard $($(LOCAL)-DEP))
+ifneq ($(words $(The_DFiles)),0)
+include $(The_DFiles)
+endif