diff --git a/build-aux/run-test.sh.in b/build-aux/run-test.sh.in
new file mode 100644
index 0000000000000000000000000000000000000000..3b58806e318a26d8f2cb0e604856bd1e97ba1cb7
--- /dev/null
+++ b/build-aux/run-test.sh.in
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+## serial 1
+
+set -eu
+
+top_srcdir="@abs_top_srcdir@"
+VALGRIND="@VALGRIND@"
+
+if test $# -eq 0 || test "$1" = ""; then
+  echo "Missing target binary" >&2
+  exit 1
+fi
+
+if test "${NOUNDEF:-}" != ""; then
+  noundef="--undef-value-errors=no"
+else
+  noundef=""
+fi
+
+if test "${NOCHILDREN:-}" != ""; then
+  trace_children="--trace-children=no"
+else
+  trace_children="--trace-children=yes"
+fi
+
+skip_path="$top_srcdir/run-test-valgrind.exclude"
+if test -r "$skip_path" && grep -w -q "$(basename $[1])" "$skip_path"; then
+  NOVALGRIND=true
+fi
+
+if test "${NOVALGRIND:-}" != ""; then
+  "$@"
+  ret=$?
+else
+  test_out="test.out~$$"
+  trap "rm -f $test_out" 0 1 2 3 15
+  supp_path="$top_srcdir/run-test-valgrind.supp"
+  if test -r "$supp_path"; then
+    $VALGRIND -q $trace_children --error-exitcode=213 --leak-check=full --gen-suppressions=all --suppressions="$supp_path" --log-file=$test_out $noundef "$@"
+  else
+    $VALGRIND -q $trace_children --error-exitcode=213 --leak-check=full --gen-suppressions=all --log-file=$test_out $noundef "$@"
+  fi
+  ret=$?
+  if test -s $test_out; then
+    cat $test_out
+    ret=1
+  fi
+fi
+if test $ret != 0; then
+  echo "Failed to run: $@" >&2
+fi
+
+exit $ret
diff --git a/configure.ac b/configure.ac
index d8ba11cacac8a294c0612f12a86f50b6daf38575..3f6efe97898c8b94ff5fadad042db276bffd257c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -239,6 +239,7 @@ src/sieve-tools/Makefile
 src/managesieve/Makefile
 src/managesieve-login/Makefile
 src/testsuite/Makefile
+build-aux/run-test.sh
 stamp.h])
 
 AC_OUTPUT
diff --git a/m4/dovecot.m4 b/m4/dovecot.m4
index 037d5e40e673b564c6f4c52d72bfd6d4cebea359..17295bffc7388e3b3222ee58a3b5924701175b1f 100644
--- a/m4/dovecot.m4
+++ b/m4/dovecot.m4
@@ -6,7 +6,7 @@ dnl This file is free software; the authors give
 dnl unlimited permission to copy and/or distribute it, with or without
 dnl modifications, as long as this notice is preserved.
 
-# serial 34
+# serial 35
 
 dnl
 dnl Check for support for D_FORTIFY_SOURCE=2
@@ -239,7 +239,7 @@ AC_DEFUN([DC_DOVECOT_MODULEDIR],[
 	AC_ARG_WITH(moduledir,
 	[  --with-moduledir=DIR    Base directory for dynamically loadable modules],
 		[moduledir="$withval"],
-		[moduledir="$dovecot_moduledir"]
+		[moduledir="\$(libdir)/dovecot"]
 	)
 	AC_SUBST(moduledir)
 ])
@@ -259,55 +259,11 @@ AC_DEFUN([DC_PLUGIN_DEPS],[
 ])
 
 AC_DEFUN([DC_DOVECOT_TEST_WRAPPER],[
+  AC_REQUIRE_AUX_FILE([run-test.sh.in])
   AC_ARG_VAR([VALGRIND], [Path to valgrind])
   AC_PATH_PROG(VALGRIND, valgrind, reject)
   AS_IF([test "$VALGRIND" != reject], [
-    cat > run-test.sh <<_DC_EOF
-#!/bin/sh
-top_srcdir=\$[1]
-shift
-
-if test "\$NOUNDEF" != ""; then
-  noundef="--undef-value-errors=no"
-else
-  noundef=""
-fi
-
-if test "\$NOCHILDREN" != ""; then
-  trace_children="--trace-children=no"
-else
-  trace_children="--trace-children=yes"
-fi
-
-skip_path="\$top_srcdir/run-test-valgrind.exclude"
-if test -r "\$skip_path" && grep -w -q "\$(basename \$[1])" "\$skip_path"; then
-  NOVALGRIND=true
-fi
-
-if test "\$NOVALGRIND" != ""; then
-  \$[*]
-  ret=\$?
-else
-  test_out="test.out~\$\$"
-  trap "rm -f \$test_out" 0 1 2 3 15
-  supp_path="\$top_srcdir/run-test-valgrind.supp"
-  if test -r "\$supp_path"; then
-    $VALGRIND -q \$trace_children --error-exitcode=213 --leak-check=full --gen-suppressions=all --suppressions="\$supp_path" --log-file=\$test_out \$noundef \$[*]
-  else
-    $VALGRIND -q \$trace_children --error-exitcode=213 --leak-check=full --gen-suppressions=all --log-file=\$test_out \$noundef \$[*]
-  fi
-  ret=\$?
-  if test -s \$test_out; then
-    cat \$test_out
-    ret=1
-  fi
-fi
-if test \$ret != 0; then
-  echo "Failed to run: \$[*]" >&2
-fi
-exit \$ret
-_DC_EOF
-    RUN_TEST='$(LIBTOOL) execute $(SHELL) $(top_builddir)/run-test.sh $(top_srcdir)'
+    RUN_TEST='$(LIBTOOL) execute $(SHELL) $(top_builddir)/build-aux/run-test.sh'
   ], [
     RUN_TEST=''
   ])