build: Add support for non-source-directory builds.
authorCarl Worth <cworth@cworth.org>
Wed, 9 Mar 2011 23:02:42 +0000 (15:02 -0800)
committerCarl Worth <cworth@cworth.org>
Wed, 9 Mar 2011 23:10:03 +0000 (15:10 -0800)
Such as:

     mkdir build
     cd build
     ../configure
     make

This is implemented by having the configure script set a srcdir
variable in Makefile.config, and then sprinkling $(srcdir) into
various make rules. We also use vpath directives to convince GNU make
to find the source files from the original source directory.

Makefile
Makefile.local
TODO
compat/Makefile.local
completion/Makefile.local
configure
emacs/Makefile.local
lib/Makefile.local

index 7549b40d171fdde519697e5fe3d67de307ddbf20..4ca74a3ff25a223140d6022fa1d5769393f53bd0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ extra_cxxflags :=
 # Makefile.config if it doesn't exist yet. And add Makefile.config to
 # our global dependency list.
 include Makefile.config
-Makefile.config: configure
+Makefile.config: $(srcdir)/configure
        @echo ""
        @echo "Note: Calling ./configure with no command-line arguments. This is often fine,"
        @echo "      but if you want to specify any arguments (such as an alternate prefix"
index 38ead11dd8dde9d3e6cba828e4addb8315a38e37..50bba640aa66bbfdce01099ee75ff20d58f6bb6e 100644 (file)
@@ -12,7 +12,7 @@ PACKAGE=notmuch
 
 IS_GIT=$(shell if [ -d .git ] ; then echo yes ; else echo no; fi)
 
-VERSION:=$(shell cat version)
+VERSION:=$(shell cat ${srcdir}/version)
 ifneq ($(MAKECMDGOALS),release)
 ifneq ($(MAKECMDGOALS),release-message)
 ifeq ($(IS_GIT),yes)
@@ -81,7 +81,7 @@ dist: $(TAR_FILE)
 # targets in the case of parallel invocation of make (-j).
 #
 # We carefully ensure that our VERSION variable is passed down to any
-# sub-ordinate make invocations (which won't otherwhise know that they
+# sub-ordinate make invocations (which won't otherwise know that they
 # are part of the release and need to take the version from the
 # version file).
 .PHONY: release
diff --git a/TODO b/TODO
index a34d95fa7c5b844928fad7407e0dd6c9bc6b4e41..f8147b1981769c702f6be83b97e64819abb13283 100644 (file)
--- a/TODO
+++ b/TODO
@@ -255,16 +255,6 @@ existing messages at the next database upgrade).
 Add support for the user to specify custom headers to be indexed (and
 re-index these for existing messages at the next database upgrade).
 
-Build system
-------------
-Fix to allow a non-source-directory build. For example, the below
-should be made to work:
-
-       mkdir build_dir
-       cd build_dir
-       ../configure
-       make
-
 Test suite
 ----------
 Achieve 100% test coverage with the test suite.
index 653fc710b68022d9596fc2579ec78e2c435e2a2f..504eb7157cc281e8c9c5483ca42637f0740476b4 100644 (file)
@@ -1,7 +1,7 @@
 # -*- makefile -*-
 
 dir := compat
-extra_cflags += -I$(dir)
+extra_cflags += -I$(srcdir)/$(dir)
 
 notmuch_compat_srcs :=
 
index 755b0f7e9ba2d81af4fda1ee7e5cc2022f998c42..dfc12713301dc7891008e0000a3e26db78519557 100644 (file)
@@ -5,8 +5,8 @@ dir := completion
 # The dir variable will be re-assigned to later, so we can't use it
 # directly in any shell commands. Instead we save its value in other,
 # private variables that we can use in the commands.
-bash_script := $(dir)/notmuch-completion.bash
-zsh_script := $(dir)/notmuch-completion.zsh
+bash_script := $(srcdir)/$(dir)/notmuch-completion.bash
+zsh_script := $(srcdir)/$(dir)/notmuch-completion.zsh
 
 install: install-$(dir)
 
index 3d1efb0bf7b84116c1fbdf70c4f3eec9dbf3b201..157ecf39086b08a62fa55760fa964d44ad80574b 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,26 @@
 #! /bin/sh
 
+srcdir=$(dirname "$0")
+
+# For a non-srcdir configure invocation (such as ../configure), create
+# the directory structure and copy Makefiles.
+if [ "$srcdir" != "." ]; then
+
+    for dir in . $(grep "^subdirs *=" "$srcdir"/Makefile | sed -e "s/subdirs *= *//"); do
+       mkdir -p "$dir"
+       cp "$srcdir"/"$dir"/Makefile.local "$dir"
+       cp "$srcdir"/"$dir"/Makefile "$dir"
+    done
+
+    # Easiest way to get the test suite to work is to just copy the
+    # whole thing into the build directory.
+    cp -a "$srcdir"/test/* test
+
+    # Emacs only likes to generate compiled files next to the .el files
+    # by default so copy these as well (which is not ideal0.
+    cp -a "$srcdir"/emacs/*.el emacs
+fi
+
 # Set several defaults (optionally specified by the user in
 # environemnt variables)
 CC=${CC:-gcc}
@@ -424,7 +445,7 @@ EOF
 fi
 
 printf "Checking for getline... "
-if ${CC} -o compat/have_getline compat/have_getline.c > /dev/null 2>&1
+if ${CC} -o compat/have_getline "$srcdir"/compat/have_getline.c > /dev/null 2>&1
 then
     printf "Yes.\n"
     have_getline=1
@@ -435,7 +456,7 @@ fi
 rm -f compat/have_getline
 
 printf "Checking for strcasestr... "
-if ${CC} -o compat/have_strcasestr compat/have_strcasestr.c > /dev/null 2>&1
+if ${CC} -o compat/have_strcasestr "$srcdir"/compat/have_strcasestr.c > /dev/null 2>&1
 then
     printf "Yes.\n"
     have_strcasestr=1
@@ -508,6 +529,24 @@ cat > Makefile.config <<EOF
 # changes, (and this could happen by simply calling "make" if the
 # configure script is updated).
 
+srcdir = ${srcdir}
+
+# We use vpath directives (rather than the VPATH variable) since the
+# VPATH variable matches targets as well as prerequisites, (which is
+# not useful since then a target left-over from a srcdir build would
+# cause a target to not be built in the non-srcdir build).
+#
+# Also, we don't use a single "vpath % \$(srcdir)" here because we
+# don't want the vpath to trigger for our emacs lisp compilation,
+# (unless we first find a way to convince emacs to build the .elc
+# target in a directory other than the directory of the .el
+# prerequisite). In the meantime, we're actually copying in the .el
+# files, (which is quite ugly).
+vpath %.c \$(srcdir)
+vpath %.cc \$(srcdir)
+vpath %.1 \$(srcdir)
+vpath Makefile.% \$(srcdir)
+
 # The C compiler to use
 CC = ${CC}
 
index 1c4166feca88d86164bc088d790685522f7f1062..1c09d87aa8f33c2dd453392c2b7a15a346ae29d2 100644 (file)
@@ -15,9 +15,9 @@ emacs_sources := \
        $(dir)/coolj.el
 
 emacs_images := \
-       $(dir)/notmuch-logo.png
+       $(srcdir)/$(dir)/notmuch-logo.png
 
-emacs_bytecode := $(subst .el,.elc,$(emacs_sources))
+emacs_bytecode = $(emacs_sources:.el=.elc)
 
 %.elc: %.el
        $(call quiet,EMACS) --directory emacs -batch -f batch-byte-compile $<
index f4b2c7b9603b383ee8ad39b14d36771f130358ea..d02a515cb7116ac84506508a39089c17412114b3 100644 (file)
@@ -45,7 +45,7 @@ endif
 endif
 
 dir := lib
-extra_cflags += -I$(dir) -fPIC
+extra_cflags += -I$(srcdir)/$(dir) -fPIC
 
 libnotmuch_c_srcs =            \
        $(notmuch_compat_srcs)  \
@@ -85,13 +85,13 @@ install: install-$(dir)
 # but cannot be used reliably within commands, so copy its value to a
 # variable that is not reused.
 lib := $(dir)
-install-$(dir):
+install-$(dir): $(dir)/$(LIBNAME)
        mkdir -p "$(DESTDIR)$(libdir)/"
        install -m0644 "$(lib)/$(LIBNAME)" "$(DESTDIR)$(libdir)/"
        ln -sf $(LIBNAME) "$(DESTDIR)$(libdir)/$(SONAME)"
        ln -sf $(LIBNAME) "$(DESTDIR)$(libdir)/$(LINKER_NAME)"
        mkdir -p "$(DESTDIR)$(includedir)"
-       install -m0644 "$(lib)/notmuch.h" "$(DESTDIR)$(includedir)/"
+       install -m0644 "$(srcdir)/$(lib)/notmuch.h" "$(DESTDIR)$(includedir)/"
        $(LIBRARY_INSTALL_POST_COMMAND)
 
 SRCS  := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs)