summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2008-04-07 02:11:49 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2008-04-07 02:11:49 +0000
commit90b089d7fd6454771b23fdcebb78d3b1a469c3f5 (patch)
tree7f77600a8b22333d7e8bd9a94446ebd446345409
parent427ce60a0cf055347b2fd7ac4a37bec59d65c3ac (diff)
downloadlibhubbub-90b089d7fd6454771b23fdcebb78d3b1a469c3f5.tar.gz
libhubbub-90b089d7fd6454771b23fdcebb78d3b1a469c3f5.tar.bz2
Rework buildsystem so that it no longer calls make recursively and rebuilds the testcases when the library changes.
svn path=/trunk/hubbub/; revision=4077
-rw-r--r--Makefile53
-rw-r--r--Makefile-riscos52
-rw-r--r--build/Makefile.common100
-rw-r--r--libhubbub.pc.in10
-rw-r--r--src/Makefile109
-rw-r--r--src/charset/Makefile79
-rw-r--r--src/input/Makefile79
-rw-r--r--src/tokeniser/Makefile79
-rw-r--r--src/utils/Makefile79
-rw-r--r--test/Makefile111
-rw-r--r--test/data/html/INDEX5
-rw-r--r--test/testrunner.pl32
12 files changed, 421 insertions, 367 deletions
diff --git a/Makefile b/Makefile
index db5a35b..cdac442 100644
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,41 @@
# Toolchain definitions for building on the destination platform
-export CC = gcc
-export AR = ar
-export LD = gcc
+CC := gcc
+AR := ar
+LD := gcc
-export CP = cp
-export RM = rm
-export MKDIR = mkdir
-export MV = mv
-export ECHO = echo
-export MAKE = make
-export PERL = perl
-export PKGCONFIG = pkg-config
+CP := cp
+RM := rm
+MKDIR := mkdir
+MV := mv
+ECHO := echo
+MAKE := make
+PERL := perl
+PKGCONFIG := pkg-config
+INSTALL := install
+SED := sed
# Toolchain flags
-WARNFLAGS = -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align \
+WARNFLAGS := -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align \
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wnested-externs -Werror -pedantic
-export CFLAGS = -std=c99 -D_BSD_SOURCE -I$(TOP)/include/ $(WARNFLAGS)
-export ARFLAGS = -cru
-export LDFLAGS = -L$(TOP)/
+CFLAGS += -std=c99 -D_BSD_SOURCE -I$(TOP)/include/ $(WARNFLAGS)
+RELEASECFLAGS = $(CFLAGS) -DNDEBUG -O2
+DEBUGCFLAGS = $(CFLAGS) -O0 -g
+ARFLAGS := -cru
+LDFLAGS = -L$(TOP)/
-export CPFLAGS =
-export RMFLAGS =
-export MKDIRFLAGS = -p
-export MVFLAGS =
-export ECHOFLAGS =
-export MAKEFLAGS =
-export PKGCONFIGFLAGS =
+CPFLAGS :=
+RMFLAGS := -f
+MKDIRFLAGS := -p
+MVFLAGS :=
+ECHOFLAGS :=
+MAKEFLAGS :=
+PKGCONFIGFLAGS :=
-export EXEEXT =
+EXEEXT :=
+
+# Default installation prefix
+PREFIX ?= /usr/local
include build/Makefile.common
diff --git a/Makefile-riscos b/Makefile-riscos
index f1d8cf0..f05dff2 100644
--- a/Makefile-riscos
+++ b/Makefile-riscos
@@ -2,37 +2,43 @@
GCCSDK_INSTALL_CROSSBIN ?= /home/riscos/cross/bin
GCCSDK_INSTALL_ENV ?= /home/riscos/env
-export CC = $(GCCSDK_INSTALL_CROSSBIN)/gcc
-export AR = $(GCCSDK_INSTALL_CROSSBIN)/ar
-export LD = $(GCCSDK_INSTALL_CROSSBIN)/gcc
+CC := $(GCCSDK_INSTALL_CROSSBIN)/gcc
+AR := $(GCCSDK_INSTALL_CROSSBIN)/ar
+LD := $(GCCSDK_INSTALL_CROSSBIN)/gcc
-export CP = cp
-export RM = rm
-export MKDIR = mkdir
-export MV = mv
-export ECHO = echo
-export MAKE = make
-export PERL = perl
-export PKGCONFIG = pkg-config
+CP := cp
+RM := rm
+MKDIR := mkdir
+MV := mv
+ECHO := echo
+MAKE := make
+PERL := perl
+PKGCONFIG := pkg-config
+INSTALL := install
+SED := sed
# Toolchain flags
-WARNFLAGS = -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align \
+WARNFLAGS := -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align \
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wnested-externs -Werror -pedantic
-export CFLAGS = -std=c99 -D_BSD_SOURCE -I$(TOP)/include/ $(WARNFLAGS) \
+CFLAGS += -std=c99 -D_BSD_SOURCE -I$(TOP)/include/ $(WARNFLAGS) \
-mpoke-function-name
-export ARFLAGS = -cru
-export LDFLAGS = -L$(TOP)/
+RELEASECFLAGS = $(CFLAGS) -DNDEBUG -O2
+DEBUGCFLAGS = $(CFLAGS) -O0 -g
+ARFLAGS := -cru
+LDFLAGS = -L$(TOP)/
-export CPFLAGS =
-export RMFLAGS =
-export MKDIRFLAGS = -p
-export MVFLAGS =
-export ECHOFLAGS =
-export MAKEFLAGS =
-export PKGCONFIGFLAGS =
+CPFLAGS :=
+RMFLAGS := -f
+MKDIRFLAGS := -p
+MVFLAGS :=
+ECHOFLAGS :=
+MAKEFLAGS :=
+PKGCONFIGFLAGS :=
-export EXEEXT = ,ff8
+EXEEXT := ,ff8
+# Default installation prefix
+PREFIX ?= $(GCCSDK_INSTALL_ENV)
include build/Makefile.common
diff --git a/build/Makefile.common b/build/Makefile.common
index 21c319a..bc79ff5 100644
--- a/build/Makefile.common
+++ b/build/Makefile.common
@@ -1,39 +1,99 @@
# Top-level Makefile fragment for Hubbub
+# Default target
+all: release
+
# Name of component
-export COMPONENT = libhubbub
+COMPONENT := libhubbub
# Environment
-export EXPORT = $(CURDIR)/dist
-export TOP = $(CURDIR)
+EXPORT := $(CURDIR)/dist
+TOP := $(CURDIR)
+RELEASEDIR := build/Release
+DEBUGDIR := build/Debug
+
+# List of items to delete on clean
+ITEMS_CLEAN :=
+# List of items to delete on distclean
+ITEMS_DISTCLEAN :=
+
+# List of targets to run for testing
+TARGET_TESTS :=
+
+# Source files
+SOURCES :=
+
+# Include Makefile fragments in subdirectories
-.PHONY: release debug test clean setup export distclean
+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 := $(subst /,_,$(subst .c,.o,$(SOURCES)))
+
+.PHONY: release debug test clean distclean setup export install uninstall
# Rules
-release: setup
- @$(MAKE) $(MAKEFLAGS) -C src release
+release: setup $(addprefix $(RELEASEDIR)/,$(OBJECTS))
+ @$(AR) $(ARFLAGS) $(COMPONENT).a $(RELEASEDIR)/*
-debug: setup
- @$(MAKE) $(MAKEFLAGS) -C src debug
+debug: setup $(addprefix $(DEBUGDIR)/,$(OBJECTS))
+ @$(AR) $(ARFLAGS) $(COMPONENT)-debug.a $(DEBUGDIR)/*
-test: debug
- @$(MAKE) $(MAKEFLAGS) -C test test
+test: debug $(TARGET_TESTS)
clean:
- @$(MAKE) $(MAKEFLAGS) -C src clean
- @$(MAKE) $(MAKEFLAGS) -C test clean
+ -@$(RM) $(RMFLAGS) $(ITEMS_CLEAN)
+ -@$(RM) $(RMFLAGS) -r $(RELEASEDIR)
+ -@$(RM) $(RMFLAGS) -r $(DEBUGDIR)
+ -@$(RM) $(RMFLAGS) $(COMPONENT).a
+ -@$(RM) $(RMFLAGS) $(COMPONENT)-debug.a
+ -@$(RM) $(RMFLAGS) $(COMPONENT).pc
+
+distclean: clean
+ -@$(RM) $(RMFLAGS) $(ITEMS_DISTCLEAN)
+ -@$(RM) $(RMFLAGS) -r $(TOP)/dist
setup:
- @$(MAKE) $(MAKEFLAGS) -C src setup
- @$(MAKE) $(MAKEFLAGS) -C test setup
+ @$(MKDIR) $(MKDIRFLAGS) $(RELEASEDIR)
+ @$(MKDIR) $(MKDIRFLAGS) $(DEBUGDIR)
export: release
@$(MKDIR) $(MKDIRFLAGS) $(TOP)/dist/lib
@$(CP) $(CPFLAGS) -r include $(EXPORT)/
- @$(MAKE) $(MAKEFLAGS) -C src export
- @$(MAKE) $(MAKEFLAGS) -C test export
+ @${CP} ${CPFLAGS} $(COMPONENT).a ${EXPORT}/lib/
+
+install: release
+ @$(MKDIR) $(MKDIRFLAGS) -p $(PREFIX)/lib/pkgconfig
+ @$(MKDIR) $(MKDIRFLAGS) -p $(PREFIX)/include/hubbub
+ @$(SED) -e 's#PREFIX#$(PREFIX)#' $(COMPONENT).pc.in >$(COMPONENT).pc
+ @$(INSTALL) --mode=644 -t $(PREFIX)/lib $(COMPONENT).a
+ @$(INSTALL) --mode=644 -t $(PREFIX)/lib/pkgconfig $(COMPONENT).pc
+ @$(INSTALL) --mode=644 -t $(PREFIX)/include/hubbub $(filter %.h, $(wildcard include/hubbub/*))
+
+uninstall:
+ @$(RM) $(RMFLAGS) $(PREFIX)/lib/$(COMPONENT).a
+ @$(RM) $(RMFLAGS) $(PREFIX)/lib/pkgconfig/$(COMPONENT).pc
+ @$(RM) $(RMFLAGS) -r $(PREFIX)/include/hubbub
+
+# Finally, build rules for compilation
+define do_compile
+$$(RELEASEDIR)/$(2): $(1)
+ @$$(ECHO) $$(ECHOFLAGS) "==> $(1)"
+ @$$(CC) -c $$(RELEASECFLAGS) -o $$@ $(1)
+
+$$(DEBUGDIR)/$(2): $(1)
+ @$$(ECHO) $$(ECHOFLAGS) "==> $(1)"
+ @$$(CC) -c $$(DEBUGCFLAGS) -o $$@ $(1)
+
+endef
+
+$(eval $(foreach SOURCE,$(filter %.c,$(SOURCES)), \
+ $(call do_compile,$(SOURCE),$(subst /,_,$(SOURCE:.c=.o)))))
-distclean: clean
- -@$(RM) $(RMFLAGS) -r $(TOP)/dist
- @$(MAKE) $(MAKEFLAGS) -C src distclean
- @$(MAKE) $(MAKEFLAGS) -C test distclean
diff --git a/libhubbub.pc.in b/libhubbub.pc.in
new file mode 100644
index 0000000..88f56ab
--- /dev/null
+++ b/libhubbub.pc.in
@@ -0,0 +1,10 @@
+prefix=PREFIX
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libhubbub
+Description: HTML5 parsing library
+Version: 0.0.1
+Libs: -L${libdir} -lhubbub
+Cflags: -I${includedir}
diff --git a/src/Makefile b/src/Makefile
index 7af11a4..1c733f7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,82 +1,49 @@
-# Makefile for libhubbub
+# Child makefile fragment for libhubbub
#
-# Toolchain is exported by top-level makefile
+# Toolchain is provided by top-level makefile
#
-# Top-level makefile also exports the following variables:
+# Variables provided by top-level makefile
#
-# COMPONENT Name of component
-# EXPORT Absolute path of export directory
-# TOP Absolute path of source tree root
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
#
-# The top-level makefile requires the following targets to exist:
+# do_include Canned command sequence to include a child makefile
#
-# clean Clean source tree
-# debug Create a debug binary
-# distclean Fully clean source tree, back to pristine condition
-# export Export distributable components to ${EXPORT}
-# release Create a release binary
-# setup Perform any setup required prior to compilation
-# test Execute any test cases
-
-# Manipulate include paths
-CFLAGS += -I$(CURDIR)
-
-# Release output
-RELEASE = ${TOP}/${COMPONENT}.a
-
-# Debug output
-DEBUG = ${TOP}/${COMPONENT}-debug.a
-
-# Objects
-OBJS = hubbub parser
-
-.PHONY: clean debug distclean export release setup test
-
-# Targets
-release: $(addprefix Release/, $(addsuffix .o, $(OBJS)))
- @${MAKE} -C charset release
- @${MAKE} -C input release
- @${MAKE} -C tokeniser release
- @${MAKE} -C treebuilder release
- @${MAKE} -C utils release
- @${AR} ${ARFLAGS} $(RELEASE) Release/*
-
-debug: $(addprefix Debug/, $(addsuffix .o, $(OBJS)))
- @${MAKE} -C charset debug
- @${MAKE} -C input debug
- @${MAKE} -C tokeniser debug
- @${MAKE} -C treebuilder debug
- @${MAKE} -C utils debug
- @${AR} ${ARFLAGS} $(DEBUG) Debug/*
-
-clean:
- @${MAKE} -C charset clean
- @${MAKE} -C input clean
- @${MAKE} -C tokeniser clean
- @${MAKE} -C treebuilder clean
- @${MAKE} -C utils clean
- -@${RM} ${RMFLAGS} $(addprefix Release/, $(addsuffix .o, ${OBJS}))
- -@${RM} ${RMFLAGS} $(addprefix Debug/, $(addsuffix .o, ${OBJS}))
- -@${RM} ${RMFLAGS} $(RELEASE) $(DEBUG)
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
-distclean:
- -@${RM} ${RMFLAGS} -r Release
- -@${RM} ${RMFLAGS} -r Debug
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
-setup:
- @${MKDIR} ${MKDIRFLAGS} Release
- @${MKDIR} ${MKDIRFLAGS} Debug
+# Manipulate include paths
+CFLAGS := $(CFLAGS) -I$(d)
-export:
- @${CP} ${CPFLAGS} $(RELEASE) ${EXPORT}/lib/
+# Sources
+SRCS_$(d) := hubbub.c parser.c
-test:
+# Append to sources for component
+SOURCES += $(addprefix $(d), $(SRCS_$(d)))
-# Pattern rules
-Release/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c ${CFLAGS} -DNDEBUG -o $@ $<
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
-Debug/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c -g ${CFLAGS} -o $@ $<
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/src/charset/Makefile b/src/charset/Makefile
index c0a00b3..2e76730 100644
--- a/src/charset/Makefile
+++ b/src/charset/Makefile
@@ -1,53 +1,46 @@
-# Makefile for libhubbub
+# Child makefile fragment for libhubbub
#
-# Toolchain is exported by top-level makefile
+# Toolchain is provided by top-level makefile
#
-# Top-level makefile also exports the following variables:
+# Variables provided by top-level makefile
#
-# COMPONENT Name of component
-# EXPORT Absolute path of export directory
-# TOP Absolute path of source tree root
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
#
-# The top-level makefile requires the following targets to exist:
+# do_include Canned command sequence to include a child makefile
#
-# clean Clean source tree
-# debug Create a debug binary
-# distclean Fully clean source tree, back to pristine condition
-# export Export distributable components to ${EXPORT}
-# release Create a release binary
-# setup Perform any setup required prior to compilation
-# test Execute any test cases
-
-# Manipulate include paths
-CFLAGS += -I$(CURDIR)
-
-# Objects
-OBJS = aliases codec codec_iconv codec_utf8 codec_utf16 detect
-
-.PHONY: clean debug distclean export release setup test
-
-# Targets
-release: $(addprefix ../Release/, $(addsuffix .o, $(OBJS)))
-
-debug: $(addprefix ../Debug/, $(addsuffix .o, $(OBJS)))
-
-clean:
- -@${RM} ${RMFLAGS} $(addprefix ../Release/, $(addsuffix .o, ${OBJS}))
- -@${RM} ${RMFLAGS} $(addprefix ../Debug/, $(addsuffix .o, ${OBJS}))
-
-distclean:
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
-setup:
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
-export:
+# Sources
+SRCS_$(d) := aliases.c codec.c codec_iconv.c codec_utf8.c codec_utf16.c detect.c
-test:
+# Append to sources for component
+SOURCES += $(addprefix $(d), $(SRCS_$(d)))
-# Pattern rules
-../Release/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c ${CFLAGS} -DNDEBUG -o $@ $<
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
-../Debug/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c -g ${CFLAGS} -o $@ $<
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/src/input/Makefile b/src/input/Makefile
index 06f8ee4..3b9206f 100644
--- a/src/input/Makefile
+++ b/src/input/Makefile
@@ -1,53 +1,46 @@
-# Makefile for libhubbub
+# Child makefile fragment for libhubbub
#
-# Toolchain is exported by top-level makefile
+# Toolchain is provided by top-level makefile
#
-# Top-level makefile also exports the following variables:
+# Variables provided by top-level makefile
#
-# COMPONENT Name of component
-# EXPORT Absolute path of export directory
-# TOP Absolute path of source tree root
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
#
-# The top-level makefile requires the following targets to exist:
+# do_include Canned command sequence to include a child makefile
#
-# clean Clean source tree
-# debug Create a debug binary
-# distclean Fully clean source tree, back to pristine condition
-# export Export distributable components to ${EXPORT}
-# release Create a release binary
-# setup Perform any setup required prior to compilation
-# test Execute any test cases
-
-# Manipulate include paths
-CFLAGS += -I$(CURDIR)
-
-# Objects
-OBJS = filter inputstream utf8_stream utf16_stream
-
-.PHONY: clean debug distclean export release setup test
-
-# Targets
-release: $(addprefix ../Release/, $(addsuffix .o, $(OBJS)))
-
-debug: $(addprefix ../Debug/, $(addsuffix .o, $(OBJS)))
-
-clean:
- -@${RM} ${RMFLAGS} $(addprefix ../Release/, $(addsuffix .o, ${OBJS}))
- -@${RM} ${RMFLAGS} $(addprefix ../Debug/, $(addsuffix .o, ${OBJS}))
-
-distclean:
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
-setup:
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
-export:
+# Sources
+SRCS_$(d) := filter.c inputstream.c utf8_stream.c utf16_stream.c
-test:
+# Append to sources for component
+SOURCES += $(addprefix $(d), $(SRCS_$(d)))
-# Pattern rules
-../Release/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c ${CFLAGS} -DNDEBUG -o $@ $<
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
-../Debug/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c -g ${CFLAGS} -o $@ $<
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/src/tokeniser/Makefile b/src/tokeniser/Makefile
index 539625f..be0699c 100644
--- a/src/tokeniser/Makefile
+++ b/src/tokeniser/Makefile
@@ -1,53 +1,46 @@
-# Makefile for libhubbub
+# Child makefile fragment for libhubbub
#
-# Toolchain is exported by top-level makefile
+# Toolchain is provided by top-level makefile
#
-# Top-level makefile also exports the following variables:
+# Variables provided by top-level makefile
#
-# COMPONENT Name of component
-# EXPORT Absolute path of export directory
-# TOP Absolute path of source tree root
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
#
-# The top-level makefile requires the following targets to exist:
+# do_include Canned command sequence to include a child makefile
#
-# clean Clean source tree
-# debug Create a debug binary
-# distclean Fully clean source tree, back to pristine condition
-# export Export distributable components to ${EXPORT}
-# release Create a release binary
-# setup Perform any setup required prior to compilation
-# test Execute any test cases
-
-# Manipulate include paths
-CFLAGS += -I$(CURDIR)
-
-# Objects
-OBJS = entities tokeniser
-
-.PHONY: clean debug distclean export release setup test
-
-# Targets
-release: $(addprefix ../Release/, $(addsuffix .o, $(OBJS)))
-
-debug: $(addprefix ../Debug/, $(addsuffix .o, $(OBJS)))
-
-clean:
- -@${RM} ${RMFLAGS} $(addprefix ../Release/, $(addsuffix .o, ${OBJS}))
- -@${RM} ${RMFLAGS} $(addprefix ../Debug/, $(addsuffix .o, ${OBJS}))
-
-distclean:
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
-setup:
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
-export:
+# Sources
+SRCS_$(d) := entities.c tokeniser.c
-test:
+# Append to sources for component
+SOURCES += $(addprefix $(d), $(SRCS_$(d)))
-# Pattern rules
-../Release/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c ${CFLAGS} -DNDEBUG -o $@ $<
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
-../Debug/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c -g ${CFLAGS} -o $@ $<
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/src/utils/Makefile b/src/utils/Makefile
index 53341cf..c9cd076 100644
--- a/src/utils/Makefile
+++ b/src/utils/Makefile
@@ -1,53 +1,46 @@
-# Makefile for libhubbub
+# Child makefile fragment for libhubbub
#
-# Toolchain is exported by top-level makefile
+# Toolchain is provided by top-level makefile
#
-# Top-level makefile also exports the following variables:
+# Variables provided by top-level makefile
#
-# COMPONENT Name of component
-# EXPORT Absolute path of export directory
-# TOP Absolute path of source tree root
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
#
-# The top-level makefile requires the following targets to exist:
+# do_include Canned command sequence to include a child makefile
#
-# clean Clean source tree
-# debug Create a debug binary
-# distclean Fully clean source tree, back to pristine condition
-# export Export distributable components to ${EXPORT}
-# release Create a release binary
-# setup Perform any setup required prior to compilation
-# test Execute any test cases
-
-# Manipulate include paths
-CFLAGS += -I$(CURDIR)
-
-# Objects
-OBJS = dict errors utf8 utf16
-
-.PHONY: clean debug distclean export release setup test
-
-# Targets
-release: $(addprefix ../Release/, $(addsuffix .o, $(OBJS)))
-
-debug: $(addprefix ../Debug/, $(addsuffix .o, $(OBJS)))
-
-clean:
- -@${RM} ${RMFLAGS} $(addprefix ../Release/, $(addsuffix .o, ${OBJS}))
- -@${RM} ${RMFLAGS} $(addprefix ../Debug/, $(addsuffix .o, ${OBJS}))
-
-distclean:
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
-setup:
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
-export:
+# Sources
+SRCS_$(d) := dict.c errors.c utf8.c utf16.c
-test:
+# Append to sources for component
+SOURCES += $(addprefix $(d), $(SRCS_$(d)))
-# Pattern rules
-../Release/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c ${CFLAGS} -DNDEBUG -o $@ $<
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
-../Debug/%.o: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c -g ${CFLAGS} -o $@ $<
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/test/Makefile b/test/Makefile
index 675b043..3d5788c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,64 +1,85 @@
-# Makefile for Hubbub testcases
+# Child makefile fragment for libhubbub
#
-# Toolchain is exported by top-level makefile
+# Toolchain is provided by top-level makefile
#
-# Top-level makefile also exports the following variables:
+# Variables provided by top-level makefile
#
-# COMPONENT Name of component
-# EXPORT Absolute path of export directory
-# TOP Absolute path of source tree root
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
#
-# The top-level makefile requires the following targets to exist:
+# do_include Canned command sequence to include a child makefile
#
-# clean Clean source tree
-# debug Create a debug binary
-# distclean Fully clean source tree, back to pristine condition
-# export Export distributable components to ${EXPORT}
-# release Create a release binary
-# setup Perform any setup required prior to compilation
-# test Execute any test cases
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
+
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
# Extend toolchain settings
# We require the presence of libjson -- http://oss.metaparadigm.com/json-c/
-CFLAGS += -I${TOP}/src/ -I$(CURDIR) \
- `${PKGCONFIG} ${PKGCONFIGFLAGS} --cflags json`
-LDFLAGS += `${PKGCONFIG} ${PKGCONFIGFLAGS} --libs json`
-
-# Release output
-RELEASE =
+CFLAGS := $(CFLAGS) -I$(TOP)/src/ -I$(d) \
+ `$(PKGCONFIG) $(PKGCONFIGFLAGS) --cflags json`
+LDFLAGS := $(LDFLAGS) `$(PKGCONFIG) $(PKGCONFIGFLAGS) --libs json`
-# Debug output
-DEBUG =
-
-# Objects
-OBJS = aliases cscodec csdetect dict entities filter hubbub \
+# Tests
+TESTS_$(d) := aliases cscodec csdetect dict entities filter hubbub \
inputstream parser parser-utf16 tokeniser tokeniser2 \
tree
-OBJS += regression/cscodec-segv regression/filter-segv regression/stream-nomem
-
-.PHONY: clean debug export release setup test
+TESTS_$(d) := $(TESTS_$(d)) regression/cscodec-segv regression/filter-segv \
+ regression/stream-nomem
-# Targets
-release:
+# Items for top-level makefile to use
+ITEMS_CLEAN := $(ITEMS_CLEAN) \
+ $(addprefix $(d), $(addsuffix $(EXEEXT), $(TESTS_$(d)))) \
+ $(addprefix $(d), $(addsuffix .gcda, $(TESTS_$(d)))) \
+ $(addprefix $(d), $(addsuffix .gcno, $(TESTS_$(d))))
+ITEMS_DISTCLEAN := $(ITEMS_DISTCLEAN) $(d)log
-debug:
+# Targets for top-level makefile to run
+TARGET_TESTS := $(TARGET_TESTS) test_$(d)
-clean:
- -@${RM} ${RMFLAGS} $(addsuffix ${EXEEXT}, $(OBJS))
+# Now we get to hack around so that we know what directory we're in.
+# $(d) no longer exists when running the commands for a target, so we can't
+# simply use it verbatim. Assigning to a variable doesn't really help, as
+# there's no guarantee that someone else hasn't overridden that variable.
+# So, what we do is make the target depend on $(d), then pick it out of the
+# dependency list when running commands. This isn't pretty, but is effective.
+test_$(d): $(d) $(addprefix $(d), $(TESTS_$(d)))
+ @$(PERL) $(TOP)/$<testrunner.pl $(TOP)/$< $(EXEEXT)
-distclean:
- -@${RM} ${RMFLAGS} log
+# Build rules for each test binary -- they all depend on the debug library
+define compile_test
+$(2): $$(TOP)/$$(COMPONENT)-debug.a $(1)
+ @$$(ECHO) $$(ECHOFLAGS) "==> $(1)"
+ @$$(CC) -c -g $$(DEBUGCFLAGS) -o $$@.o $(1)
+ @$$(LD) -g -o $$@ $$@.o $$(LDFLAGS) -lhubbub-debug -lgcov
+ @$$(RM) $$(RMFLAGS) $$@.o
-setup:
+endef
-export:
+$(eval $(foreach TEST,$(addprefix $(d), $(TESTS_$(d))), \
+ $(call compile_test,$(addsuffix .c, $(TEST)),$(TEST))))
-test: $(OBJS)
- @${PERL} testrunner.pl ${EXEEXT}
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
-# Pattern rules
-%: %.c
- @${ECHO} ${ECHOFLAGS} "==> $<"
- @${CC} -c -g ${CFLAGS} -o $@.o $<
- @${LD} -g -o $@ $@.o ${LDFLAGS} -lhubbub-debug
- @${RM} ${RMFLAGS} $@.o
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/test/data/html/INDEX b/test/data/html/INDEX
index 25483db..b33a0d5 100644
--- a/test/data/html/INDEX
+++ b/test/data/html/INDEX
@@ -6,5 +6,6 @@ section-tree-construction.html HTML5 tree construction algorithm
#web-apps.html HTML5 specification
initial-close-tag.html Page with initial </html>
#phonecalls.html HTML document that breaks libxml's HTML parser
-misnested.html Misnested tags
-isindex.html Test of <isindex> parsing
+#firmaer.phtml Large(ish) document with parse errors
+misnested.html Misnested tags
+isindex.html Test of <isindex> parsing
diff --git a/test/testrunner.pl b/test/testrunner.pl
index 0aa4586..4b59969 100644
--- a/test/testrunner.pl
+++ b/test/testrunner.pl
@@ -2,7 +2,7 @@
#
# Testcase runner for libhubbub
#
-# Usage: testrunner <executable extension>
+# Usage: testrunner <directory> [<executable extension>]
#
# Operates upon INDEX files described in the README.
# Locates and executes testcases, feeding data files to programs
@@ -16,16 +16,24 @@ use strict;
use File::Spec;
use IPC::Open3;
+if (@ARGV < 1) {
+ print "Usage: testrunner.pl <directory> [<exeext>]\n";
+ exit;
+}
+
+# Get directory
+my $directory = shift @ARGV;
+
# Get EXE extension (if any)
my $exeext = "";
$exeext = shift @ARGV if (@ARGV > 0);
# Open log file and /dev/null
-open(LOG, ">log") or die "Failed opening test log";
+open(LOG, ">$directory/log") or die "Failed opening test log";
open(NULL, "+<", File::Spec->devnull) or die "Failed opening /dev/null";
# Open testcase index
-open(TINDEX, "<INDEX") or die "Failed opening test INDEX";
+open(TINDEX, "<$directory/INDEX") or die "Failed opening test INDEX";
# Parse testcase index, looking for testcases
while (my $line = <TINDEX>) {
@@ -50,8 +58,8 @@ while (my $line = <TINDEX>) {
# Testcase has external data files
# Open datafile index
- open(DINDEX, "<./data/$data/INDEX") or
- die "Failed opening ./data/$data/INDEX";
+ open(DINDEX, "<$directory/data/$data/INDEX") or
+ die "Failed opening $directory/data/$data/INDEX";
# Parse datafile index, looking for datafiles
while (my $dentry = <DINDEX>) {
@@ -64,8 +72,9 @@ while (my $line = <TINDEX>) {
$dtest =~ s/^\s+|\s+$//g;
$ddesc =~ s/^\s+|\s+$//g;
- print LOG "Running ./$test ./data/Aliases " .
- "./data/$data/$dtest\n";
+ print LOG "Running $directory/$test " .
+ "$directory/data/Aliases " .
+ "$directory/data/$data/$dtest\n";
# Make message fit on an 80 column terminal
my $msg = " ==> $test [$data/$dtest]";
@@ -75,8 +84,9 @@ while (my $line = <TINDEX>) {
# Run testcase
$pid = open3("&<NULL", \*OUT, \*ERR,
- "./$test", "./data/Aliases",
- "./data/$data/$dtest");
+ "$directory/$test",
+ "$directory/data/Aliases",
+ "$directory/data/$data/$dtest");
my $last = "FAIL";
@@ -108,7 +118,7 @@ while (my $line = <TINDEX>) {
close(DINDEX);
} else {
# Testcase has no external data files
- print LOG "Running ./$test ./data/Aliases\n";
+ print LOG "Running $directory/$test $directory/data/Aliases\n";
# Make message fit on an 80 column terminal
my $msg = " ==> $test";
@@ -118,7 +128,7 @@ while (my $line = <TINDEX>) {
# Run testcase
$pid = open3("&<NULL", \*OUT, \*ERR,
- "./$test", "./data/Aliases");
+ "$directory/$test", "$directory/data/Aliases");
my $last = "FAIL";