summaryrefslogtreecommitdiff
path: root/makefiles/Makefile.top
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2009-03-24 12:18:16 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2009-03-24 12:18:16 +0000
commit527c18b061466a7d0ebde53e761d94775ebc8324 (patch)
treeccb277c2caa98ac0e8235823609fe0ed26a1d229 /makefiles/Makefile.top
downloadbuildsystem-527c18b061466a7d0ebde53e761d94775ebc8324.tar.gz
buildsystem-527c18b061466a7d0ebde53e761d94775ebc8324.tar.bz2
Split common makefiles out of {hubbub,libcss,lpu,libdom,iconv} trees
svn path=/trunk/tools/buildsystem/; revision=6831
Diffstat (limited to 'makefiles/Makefile.top')
-rw-r--r--makefiles/Makefile.top378
1 files changed, 378 insertions, 0 deletions
diff --git a/makefiles/Makefile.top b/makefiles/Makefile.top
new file mode 100644
index 0000000..aa8bf6f
--- /dev/null
+++ b/makefiles/Makefile.top
@@ -0,0 +1,378 @@
+# Top-level Makefile fragment
+#
+# Expected inputs:
+#
+# BUILD Type of build to perform:
+# release - Release build
+# debug - Debug build (default)
+# COMPONENT Name of the component (sans leading "lib" iff a library)
+# COMPONENT_TYPE Type of component:
+# binary - Executable binary
+# lib-static - Static library
+# lib-shared - Shared library
+# TARGET Target platform identifier
+#
+# Optional inputs:
+#
+# BUILDDIR Directory to build into
+# (defaults to build-$(HOST)-$(TARGET)-$(BUILD))
+# CC_CAN_BUILD_AND_DEP Flag whether $(CC) is capable of calculating dependency
+# information at the same time as compiling sources.
+# Set to "yes" if it can.
+# DESTDIR Sandboxed FS root (e.g. for packaging)
+# HOST Host platform identifier
+# PREFIX Absolute installation path prefix
+# (defaults to /usr/local)
+#
+# The client may also override all toolchain settings, including:
+#
+# ARFLAGS Archiver flags for the current compilation
+# CFLAGS C compiler flags for the current compilation
+# LDFLAGS Linker flags for the current compilation
+#
+# TESTCFLAGS Any test-specific CFLAGS
+# TESTLDFLAGS Any test-specific LDFLAGS
+#
+# TESTRUNNER Test runner invocation command
+# The test runner takes a command line in the form
+# <build dir> <test dir> <exeext>
+#
+# Targets provided:
+#
+# all Default target. Builds component using current settings
+# test Build and run test suite, using current settings.
+# coverage Determine test suite coverage (requires lcov)
+# profile Build with profiling support enabled (requires gprof)
+# docs Produce documentation (requires doxygen)
+# clean Clean the build
+# distclean Remove distribution files, too
+# install Install component into prefix.
+# uninstall Remove component from prefix.
+
+###############################################################################
+# Sanity checks
+###############################################################################
+
+# Name of component must be defined by client
+ifeq ($(COMPONENT),)
+ $(error COMPONENT not defined)
+endif
+
+# As must the component type
+ifeq ($(COMPONENT_TYPE),)
+ $(error COMPONENT_TYPE not defined)
+endif
+
+# Target platform must be defined by the client
+ifeq ($(TARGET),)
+ $(error TARGET not defined)
+endif
+
+# Default build type
+ifeq ($(BUILD),)
+ BUILD := debug
+endif
+
+##############################################################################
+# Tool defaults
+##############################################################################
+
+ifeq ($(BUILD),release)
+ CFLAGS ?= -O2
+else
+ CFLAGS ?= -g -O0
+ LDFLAGS ?= -g
+endif
+
+ECHO ?= echo
+
+GENHTML ?= genhtml
+
+INSTALL ?= install
+
+LCOV ?= lcov
+
+MKDIR ?= mkdir
+MKDIRFLAGS ?= -p
+
+PKGCONFIG ?= pkg-config
+
+SED ?= sed
+
+TOUCH ?= touch
+
+##############################################################################
+# Makefile variables
+##############################################################################
+
+Q ?= @
+VQ ?= @
+
+##############################################################################
+# Build environment
+##############################################################################
+
+# Build directory
+BUILDDIR ?= build-$(HOST)-$(TARGET)-$(BUILD)
+
+# Build tree subdirs
+COVERAGEDIR := $(BUILDDIR)/coverage
+DOCDIR := $(BUILDDIR)/docs
+
+# Default prefix
+PREFIX ?= /usr/local
+
+# List of items to delete on clean
+CLEAN_ITEMS :=
+# List of items to delete on distclean
+DISTCLEAN_ITEMS :=
+
+# List of sources to build for testing
+TEST_SOURCES :=
+# List of targets to run for testing
+TEST_TARGETS :=
+
+# List of items to (un)install
+INSTALL_ITEMS :=
+
+# Source files
+SOURCES :=
+
+# Include configuration Makefile fragment
+-include Makefile.config
+
+# Include Makefile fragments in subdirectories
+
+define do_include
+DIR := $$(dir $(1))
+include $(1)
+
+endef
+
+MAKE_INCLUDES := $(wildcard */Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
+
+# Calculate objects to build
+OBJECTS := $(addprefix $(BUILDDIR)/,$(subst /,_,$(subst .c,.o,$(SOURCES))))
+
+TEST_OBJECTS := $(addprefix $(BUILDDIR)/,$(subst /,_, \
+ $(subst .c,.o,$(TEST_SOURCES))))
+TEST_BINARIES := $(addprefix $(BUILDDIR)/,$(subst /,_, \
+ $(basename $(TEST_SOURCES))))
+
+# And the output filename
+ifeq ($(findstring lib,$(COMPONENT_TYPE)),lib)
+ OUTPUT := $(BUILDDIR)/lib$(COMPONENT)$(LIBEXT)
+else
+ OUTPUT := $(BUILDDIR)/$(COMPONENT)$(EXEEXT)
+endif
+
+###############################################################################
+# Build targets
+###############################################################################
+
+.PHONY: all test coverage profile docs clean distclean install uninstall
+
+# Default target
+all: $(OUTPUT)
+
+# Build and execute testsuite
+test: $(OUTPUT) $(TEST_BINARIES) $(TEST_TARGETS)
+ $(VQ)$(ECHO) $(ECHOFLAGS) " TEST: Testing complete"
+
+# Compute coverage
+coverage: clean
+ $(Q)$(LCOV) --directory . --zerocounters
+ $(Q)$(MAKE) test CFLAGS="$(CFLAGS) -fprofile-arcs -ftest-coverage" \
+ LDFLAGS="$(LDFLAGS) -lgcov"
+ $(Q)$(LCOV) --directory $(BUILDDIR) --base-directory $(CURDIR) \
+ --capture --output-file $(COVERAGEDIR)/$(COMPONENT)_tmp.info
+ $(Q)$(LCOV) --extract $(COVERAGEDIR)/$(COMPONENT)_tmp.info \
+ "$(CURDIR)/src*" -o $(COVERAGEDIR)/$(COMPONENT).info
+ $(Q)$(RM) $(RMFLAGS) $(COVERAGEDIR)/$(COMPONENT)_tmp.info
+ $(Q)$(GENHTML) -o $(COVERAGEDIR) --num-spaces 2 \
+ $(COVERAGEDIR)/$(COMPONENT).info
+
+# Build for profiling
+profile: clean
+ $(Q)$(MAKE) test CFLAGS="$(CFLAGS) -pg" LDFLAGS="-pg $(LDFLAGS)"
+
+# Compile documentation
+docs: $(BUILDDIR)/stamp
+ $(Q)$(DOXYGEN) build/Doxyfile
+
+# Clean build tree
+clean:
+ -$(Q)$(RM) $(RMFLAGS) $(CLEAN_ITEMS)
+ -$(Q)$(RM) $(RMFLAGS) gmon.out
+ -$(Q)$(RM) $(RMFLAGS) -r $(BUILDDIR)
+
+# Remove auto-generated non-build-tree items
+distclean: clean
+ -$(Q)$(RM) $(RMFLAGS) $(DISTCLEAN_ITEMS)
+
+# The installation target, and associated canned command sequences.
+# For reference, the syntax of INSTALL_ITEMS is:
+#
+# <destination>:<file>[';'<file>]*
+#
+# We also permit a trailing ';' in the file list.
+
+# Install a pkg-config control file ($1) to the specified location ($2)
+define install_pkgconfig
+ $(Q)$(SED) -e 's#PREFIX#$(PREFIX)#' $1 >$(BUILDDIR)/$(1:.in=)
+ $(INSTALL) $(INSTALLFLAGS) -m 644 $(BUILDDIR)/$(1:.in=) $2
+
+endef
+
+# Install a file ($1) to the specified location ($2)
+define install_file
+ $(if $1, \
+ $(if $(findstring .pc.in,$1), \
+ $(call install_pkgconfig,$1,$2), \
+ $(INSTALL) $(INSTALLFLAGS) -m 644 $1 $2))
+
+endef
+
+# Install a list of files ($2) to the specified location ($1)
+# We create the installation location if it doesn't already exist
+define install_to_dest
+ $(Q)$(MKDIR) $(MKDIRFLAGS) $(DESTDIR)$(PREFIX)$1
+ $(foreach FILE,$(strip $(subst ;, ,$2)), \
+ $(call install_file,$(FILE),$(DESTDIR)$(PREFIX)$1))
+
+endef
+
+install: $(OUTPUT)
+ $(foreach ITEM,$(INSTALL_ITEMS), \
+ $(call install_to_dest,$(firstword $(subst :, ,$(ITEM))), \
+ $(lastword $(subst :, ,$(ITEM)))))
+
+# Uninstallation
+
+# Uninstall a file ($1) from the specified location ($2)
+define uninstall_file
+ $(if $1, \
+ $(if $(findstring .pc.in,$1), \
+ $(RM) $(RMFLAGS) $2/$(notdir $(1:.in=)), \
+ $(RM) $(RMFLAGS) $2/$(notdir $1)))
+
+endef
+
+# Uninstall a list of files ($2) from the specified location ($1)
+# TODO: Come up with a safe way of removing directories, too
+define uninstall_from_dest
+ $(foreach FILE,$(strip $(subst ;, ,$2)), \
+ $(call uninstall_file,$(FILE),$(DESTDIR)$(PREFIX)$1))
+
+endef
+
+uninstall:
+ $(foreach ITEM,$(INSTALL_ITEMS), \
+ $(call uninstall_from_dest,$(firstword $(subst :, ,$(ITEM))), \
+ $(lastword $(subst :, ,$(ITEM)))))
+
+###############################################################################
+# Actual rules
+###############################################################################
+
+$(BUILDDIR)/stamp:
+ $(Q)$(MKDIR) $(MKDIRFLAGS) $(BUILDDIR)
+ $(Q)$(MKDIR) $(MKDIRFLAGS) $(COVERAGEDIR)
+ $(Q)$(MKDIR) $(MKDIRFLAGS) $(DOCDIR)
+ $(Q)$(TOUCH) $(BUILDDIR)/stamp
+
+$(OUTPUT): $(BUILDDIR)/stamp $(OBJECTS)
+ifeq ($(COMPONENT_TYPE),lib-static)
+ $(VQ)$(ECHO) $(ECHOFLAGS) " AR: $@"
+ $(Q)$(AR) $(ARFLAGS) $@ $(OBJECTS)
+else
+ $(VQ)$(ECHO) $(ECHOFLAGS) " LINK: $@"
+ $(Q)$(LD) -o $@ $(OBJECTS) $(LDFLAGS)
+endif
+
+###############################################################################
+# Autogenerated, implied rules
+###############################################################################
+
+DEPFILES :=
+
+ifeq ($(CC_CAN_BUILD_AND_DEP),yes)
+ # C compiler can compile and dep simultaneously
+
+ define dep_c
+ $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1
+
+ DEPFILES += $$(BUILDDIR)/$2
+
+ endef
+
+ define build_c
+ $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1
+ $$(VQ)$$(ECHO) $$(ECHOFLAGS) " COMPILE: $1"
+ $$(Q)$$(CC) -MMD -MP $($3) -o $$@ -c $1
+
+ endef
+else
+ # C compiler must calculate dependencies first, then compile (default)
+
+ define dep_c
+ $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1
+ $$(VQ)$$(ECHO) $$(ECHOFLAGS) " DEP: $1"
+ $$(Q)$$(RM)$($@)
+ $$(Q)$$(CC) $($3) -MM $1 > $$@
+ $$(Q)$$(SED) $$(SEDFLAGS) -i 's,^.*:,$$@ $$(@:.d=.o):,' $$@
+
+ DEPFILES += $$(BUILDDIR)/$2
+
+ endef
+
+ define build_c
+ $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1
+ $$(VQ)$$(ECHO) $$(ECHOFLAGS) " COMPILE: $1"
+ $$(Q)$$(CC) $($3) -o $$@ -c $1
+
+ endef
+endif
+
+# Generate dependency rules
+$(eval $(foreach SOURCE,$(filter %.c,$(SOURCES)), \
+ $(call dep_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.d)),CFLAGS)))
+
+# Generate compilation rules
+$(eval $(foreach SOURCE,$(filter %.c,$(SOURCES)), \
+ $(call build_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.o)),CFLAGS)))
+
+# Similarly for test sources
+ifeq ($(MAKECMDGOALS),test)
+ TESTCFLAGS := $(TESTCFLAGS) $(CFLAGS)
+ TESTLDFLAGS := $(TESTLDFLAGS) $(LDFLAGS)
+
+ ifeq ($(findstring lib,$(COMPONENT_TYPE)),lib)
+ TESTLIB := $(OUTPUT)
+ TESTLDFLAGS := $(TESTLDFLAGS) -L$(BUILDDIR)/ -l$(COMPONENT)
+ endif
+
+ define link_test
+ $2: $($3) $1
+ $$(VQ)$$(ECHO) $$(ECHOFLAGS) " LINK: $2"
+ $$(Q)$$(CC) -o $$@ $1 $($4)
+
+ endef
+
+$(eval $(foreach SOURCE,$(filter %.c,$(TEST_SOURCES)), \
+ $(call dep_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.d)),TESTCFLAGS)))
+
+$(eval $(foreach SOURCE,$(filter %.c,$(TEST_SOURCES)), \
+ $(call build_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.o)),TESTCFLAGS)))
+
+$(eval $(foreach BINARY,$(TEST_BINARIES), \
+ $(call link_test, \
+ $(addsuffix .o,$(BINARY)),$(BINARY),TESTLIB,TESTLDFLAGS)))
+endif
+
+# Include dependency makefiles
+ifneq ($(findstring clean,$(MAKECMDGOALS)),clean)
+-include $(sort $(DEPFILES))
+endif
+