From 3cb1b74c0be2681b4493500840f7999734bf002f Mon Sep 17 00:00:00 2001
From: Stefan Fiedler <stefan.fiedler@students.jku.at>
Date: Sat, 10 Jun 2006 09:36:49 +0000
Subject: [PATCH] Stefan Fiedler: 	experimental implementation of
 Clifford's autopch wrapper, 	see
 http://www.rocklinux.net/lurker/message/20051219.123115.82da747d.html

[2006041211494029578] (https://www.rocklinux.net/submaster)



git-svn-id: http://www.rocklinux.org/svn/rock-linux/trunk@7652 c5f82cb5-29bc-0310-9cd0-bff59a50e3bc
---
 package/base/gcc/g++-autopch.sh | 58 +++++++++++++++++++++++++++++++++
 package/base/gcc/gcc.conf       |  3 ++
 package/base/gcc/parse-config   |  8 ++++-
 scripts/config.hlp              |  7 ++++
 scripts/config.in               |  2 ++
 5 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 package/base/gcc/g++-autopch.sh

diff --git a/package/base/gcc/g++-autopch.sh b/package/base/gcc/g++-autopch.sh
new file mode 100644
index 000000000..5f69efe99
--- /dev/null
+++ b/package/base/gcc/g++-autopch.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# AutoPCH: Automatically use pre-compiled headers
+#
+# Simply use this script instead of calling g++ directly.
+# This is a dirty hack. So don't wonder if it does not work
+# out of the box with every package.
+#
+# example using kdegames:
+# -----------------------
+#
+# time make CXX="autopch"
+# real    30m41.945s
+# user    25m30.924s
+# sys     3m9.300s
+#
+# without autopch:
+# real    42m59.061s
+# user    36m50.630s
+# sys     2m41.806s
+
+
+cxx="${AUTOPCHCXX:-g++}"
+cppfile="$( echo "$*" | sed -r 's,.* ([^ ]*\.cpp).*,\1,'; )"
+cppargs="$( echo "$*" | sed -r 's, ([^- ]|-[MCSEco])[^ ]*,,g'; )"
+
+# echo "AutoPCH> $cxx $*" >&2
+# echo "AutoPCH - cppfile> $cppfile" >&2
+# echo "AutoPCH - cppargs> $cppargs" >&2
+
+if [ ".$cppfile" == ".$*" ]; then
+	exec $cxx "$@"
+	exit 1
+fi
+
+if [ ! -f autopch.h -a ! -f autopch_oops.h ]; then
+	{
+		echo "#ifndef _AUTOPCH_H_"
+		echo "#define _AUTOPCH_H_"
+		echo "#warning AutoPCH: THEWARNING"
+		[ -f autopch_incl.h ] && cat autopch_incl.h
+		egrep -h '^#(include.*\.h[">]|if|endif|define.*[^\\]$|undef)' *.cpp | \
+			egrep -v "[<\"](${AUTOPCHEXCL:-autopch.h})[\">]"
+		echo "#endif /* _AUTOPCH_H_ */"
+	} > autopch.h.plain
+	sed 's,THEWARNING,New pre-compiled header.,' < autopch.h.plain > autopch.h
+	echo "exec $cxx -I. $cppargs -x c++ -c autopch.h" > autopch.sh
+	if ! sh autopch.sh; then mv -f autopch.h autopch_oops.h; fi
+	sed 's,THEWARNING,Pre-compiled header not used!,' < autopch.h.plain > autopch.h
+fi
+
+if ! test -f autopch.h || ! $cxx -include autopch.h "$@"; then
+	echo "AutoPCH: Fallback to non pre-compiled headers!" >&2
+	exec $cxx "$@"
+	exit 1
+fi
+exit 0
+
diff --git a/package/base/gcc/gcc.conf b/package/base/gcc/gcc.conf
index 5b1d6b30d..f16edbc91 100644
--- a/package/base/gcc/gcc.conf
+++ b/package/base/gcc/gcc.conf
@@ -358,6 +358,9 @@ custmain() {
 	fi
 	if [ $ROCKCFG_DEFAULT_CXX = $xpkg ] ; then
 		create_links c++ c++filt g++
+
+		cp -a $confdir/g++-autopch.sh $root/$prefix/bin/g++-autopch
+		chmod +x $root/$prefix/bin/g++-autopch
 	fi
 	if [ $ROCKCFG_DEFAULT_F77 = $xpkg ] ; then
 		create_links g77
diff --git a/package/base/gcc/parse-config b/package/base/gcc/parse-config
index b01da80a0..8f9a9ad45 100644
--- a/package/base/gcc/parse-config
+++ b/package/base/gcc/parse-config
@@ -69,7 +69,13 @@ for x in CC CXX F77 ; do
 	fi
 done
 
-# Add the usual gcc optimazation options
+# Use automatically precompiled C++ headers
+if [ "$ROCKCFG_AUTOPCH" = 1 ] ; then
+	[ -n "$CXX" -a -n "`type -p g++-autopch`" ] && \
+		CXX="eval AUTOPCHCXX=\"$CXX\" g++-autopch"
+fi
+
+# Add the usual gcc optimization options
 # Strip or add debug information
 #
 if [ "$ROCKCFG_DEBUG" = 0 ] ; then
diff --git a/scripts/config.hlp b/scripts/config.hlp
index 18dc9f632..e92e1a03b 100644
--- a/scripts/config.hlp
+++ b/scripts/config.hlp
@@ -372,6 +372,13 @@ ROCKCFG_STATIC
 ROCKCFG_MULTILIB
   Enable installing several versions of the same library.
 
+ROCKCFG_AUTOPCH
+  Compiling C++ headers more than once (e.g. when included from different
+  files) often causes a significant increase in build time.
+  Enable this option and a wrapper for the C++ compiler will try to make
+  sure the time-expensive part of compiling C++ headers is done only once
+  at most.
+
 ROCKCFG_DISABLE_NLS
   Please check here if you do not want to use Native Language Support.
 
diff --git a/scripts/config.in b/scripts/config.in
index 406aacfcc..cf13cb312 100644
--- a/scripts/config.in
+++ b/scripts/config.in
@@ -381,6 +381,8 @@ break packages!'
 	bool 'Disable exceptions and rtti in C++' ROCKCFG_LIMITCXX 0
 	bool 'Enable C compiler multilib support' ROCKCFG_MULTILIB 0
 
+	bool 'Use automatically precompiled C++ headers' ROCKCFG_AUTOPCH 0
+
 	bool 'Disable National Language Support' ROCKCFG_DISABLE_NLS 0
 	if [ "$ROCKCFG_DISABLE_NLS" = 1 ] ; then
 		pkgremove gettext