diff options
Diffstat (limited to 'buildlib')
-rw-r--r-- | buildlib/defaults.mak | 101 | ||||
-rw-r--r-- | buildlib/library.mak | 61 |
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 |