(1) how to hide helper classes (2) KDE_NO_INLINE missing?
Simon Hausmann
hausmann at kde.org
Sun Mar 14 11:34:53 GMT 2004
On Sunday 14 March 2004 02:59, Luciano Montanaro wrote:
> On Sunday 14 March 2004 00:54, Brad Hards wrote:
> > I haven't tried it yet, but anecdotal advice from Andrew Tridgell
> > indicates that Samba builds get a huge improvement. That is almost
> > certainly helped by the particular Samba header file system, where they
> > only ever include one header in each file (and it is always the same one
> > - it includes everything else that is required), so they get a lot of
> > assistance from pre-compiled headers.
> >
> > Maybe we can get better performance by making a standard <kde-includes.h>
> > that includes the 20 most common KDE headers and the 10 most common Qt
> > headers. Then work through the KDE files and rip out the duplicates.
> > Worth a try for someone with a lot of high performance hardware and a bit
> > of spare time.
>
> As you, I haven't tried it yet. However, an approach similar to yours could
> work, but I don't think the precompiled header should be #included for
> real.
>
> Reading the gcc manual, I see that the precompiled header could be included
> from the command line. Since Qt and KDE includes are guarded against
> multiple inclusion, a single include file could be used covering most of Qt
> and Kdelibs if the compiler supports it, otherwise everything would work as
> it does currently. No need to edit existing KDE files, just some more
> checks in the autotools scripts.
Right. That's pretty much what I did locally here, too. If anyone wants to
give it a try, I attached the modifications I did to unsermake and
acinclude.m4.in. It's modelled after qmake's implementation:
The idea is to have something like 'libkdecore_la_PCH = myheader.h' in
Makefile.am. That header file then gets precompiled and its inclusion is
forced with '-include' to all of libkdecore_la_SOURCES.
myheader.h should have '#if defined(__cplusplus)' guards and include a
selection of header files. The more files you add the more files you have to
recompile when you touch one of them, so including all of them is not always
a good idea, as it gives you the effect of --enable-final: You'll have to
recompile all _SOURCES when you touch one of them. But even with only a
selection of header files there is a speed-up, and it pays off for regular
development if you mainly work on the .cpp files.
In addition at configure time you have to specify '--enable-pch' .
One thing it keep in mind is that the -include breaks preprocessor tricks,
like the re-enabling of QTranslator in kapplication.cpp, so if you try it on
libkdecore you need to remove the -DQT_NO_TRANSLATIONS in MakeVars. But apart
from that I'm not aware of any problems.
So if anyone wants to try it: Please let me know if it works for you or if you
find any problems.
Simon
-------------- next part --------------
Index: handlerbase.py
===================================================================
RCS file: /home/kde/kdenonbeta/unsermake/handlerbase.py,v
retrieving revision 1.1
diff -u -p -b -r1.1 handlerbase.py
--- handlerbase.py 7 Sep 2003 15:22:11 -0000 1.1
+++ handlerbase.py 14 Mar 2004 11:15:07 -0000
@@ -17,6 +17,9 @@ class HandlerBase:
def shuffle_binaries(self, amfile):
pass
+ def postprocess(self, amfile):
+ pass
+
ext_dict = {}
handlers = []
Index: kdeinit.um
===================================================================
RCS file: /home/kde/kdenonbeta/unsermake/kdeinit.um,v
retrieving revision 1.11
diff -u -p -b -r1.11 kdeinit.um
--- kdeinit.um 7 Sep 2003 16:41:20 -0000 1.11
+++ kdeinit.um 14 Mar 2004 11:15:07 -0000
@@ -50,12 +50,16 @@ class KDEINIT_Handler(handlerbase.Handle
# reconstruct the objects and such from scratch)
kdeinitlib = copy.copy(bin)
- kdeinitlib.type = program.PTYPE_LTLIBRARY
+ kdeinitlib.set_type(program.PTYPE_LTLIBRARY)
kdeinitlib.name = 'libkdeinit_' + bin.name
kdeinitlib.canon_name = 'libkdeinit_' + bin.canon_name
kdeinitlib.final_sources = {}
kdeinitlib.prefix = 'lib'
+ pchvar = bin.canon_name + "_PCH"
+ if amfile.is_defined(pchvar):
+ amfile.add_define(kdeinitlib.canon_name + '_PCH', amfile.value_list(bin.canon_name))
+
# now do the same thing for the <bin> definition
amfile.add_define(canon_name + '_LDFLAGS', '$(KDE_RPATH)')
@@ -63,7 +67,7 @@ class KDEINIT_Handler(handlerbase.Handle
amfile.add_define(canon_name + '_LDADD', kdeinitlib.name)
kdeinit = copy.copy(bin)
- kdeinit.type = program.PTYPE_PROGRAM
+ kdeinit.set_type(program.PTYPE_PROGRAM)
kdeinit.final_sources = {}
kdeinit.prefix = 'bin'
kdeinit.name = name
Index: pch.um
===================================================================
RCS file: pch.um
diff -N pch.um
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pch.um 14 Mar 2004 11:15:07 -0000
@@ -0,0 +1,66 @@
+# -*-python-*-
+# vim: ts=4 noet
+
+import handlerbase
+
+class PCHHandler(handlerbase.HandlerBase):
+ def __init__(self):
+ pass
+
+ def postprocess(self, amfile):
+
+ for bin in amfile.binaries.values():
+
+ pchvarname = bin.canon_name + "_PCH"
+ header = amfile.value_list(pchvarname)
+
+ if not header:
+ continue
+
+ if len(header) > 1:
+ print "%s: there can be only one header file to precompile, skipping" % pchvarname
+ continue
+
+ header = header[0]
+
+ pchdir = amfile.rulef.build + bin.canon_name + ".gch"
+
+# print '%s: PCH = %s / pchdir %s' % (amfile.filename, header, pchdir)
+
+ # first create rules for precompiling the header
+ cxxlines = ["test -d %s || mkdir -p %s" % (pchdir, pchdir)]
+ clines = ["test -d %s || mkdir -p %s" % (pchdir, pchdir)]
+
+ splittedheader = string.split(header, ".")
+ base = splittedheader[0]
+ ext = "." + splittedheader[1]
+
+ pic = '';
+ #if bin.type == PTYPE_LTLIBRARY:
+ # can't use PTYPE_LTLIBRARY here :(
+ if bin.type == 3:
+ pic = '-fPIC -DPIC'
+
+ cxxtarget = pchdir + '/c++'
+ ctarget = pchdir + '/c'
+
+ cxxlines.extend(bin.compile_lines(amfile.rulef.source, base, ext, "-x c++-header " + pic, 1, 1, "_cxx", cxxtarget))
+ clines.extend(bin.compile_lines(amfile.rulef.source, base, ext, "-x c-header " + pic, 0, 1, "_c", ctarget))
+
+ amfile.rulef.insertTarget(cxxtarget, header, cxxlines)
+ amfile.rulef.insertTarget(ctarget, header, clines)
+
+ # now create target rules for forcing the inclusion of the pch with -include
+ amfile.rulef.add_define(amfile.canon_subdir + '_' + bin.canon_name + "_CPPFLAGS", "-include " + bin.canon_name, 'unsermake_enable_pch')
+
+ # the *_target_PCHDEP variable is what the actual objects depend on, to make sure the
+ # precompiled header gets created before the first inclusion
+ amfile.rulef.add_define(amfile.canon_subdir + "_" + bin.canon_name + "_PCHDEP", pchdir + "/c++" + ' ' + pchdir + '/c', 'unsermake_enable_pch')
+
+ amfile.rulef.dep_files.append('$(DEPDIR)/%s.U%s' % (base + "_cxx", bin.objext[1:]))
+ amfile.rulef.dep_files.append('$(DEPDIR)/%s.U%s' % (base + "_c", bin.objext[1:]))
+
+ bin.cleanfiles.extend([bin.canon_name + ".gch/c++", bin.canon_name + ".gch/c"])
+
+
+register_handler(PCHHandler())
Index: program.py
===================================================================
RCS file: /home/kde/kdenonbeta/unsermake/program.py,v
retrieving revision 1.9
diff -u -p -b -r1.9 program.py
--- program.py 8 Mar 2004 09:51:54 -0000 1.9
+++ program.py 14 Mar 2004 11:15:08 -0000
@@ -18,7 +18,6 @@ def program_type(suffix):
class Program:
def __init__(self, amfile, name, prefix, type):
- self.type = type
self.name = name
self.prefix = prefix
self.canon_name = utilities.canon_name(name)
@@ -27,10 +26,18 @@ class Program:
self.objs = []
self.cleanfiles = []
self.final_sources = {}
+ self.set_type(type)
def __repr__(self):
return self.name
+ def set_type(self, type):
+ self.type = type
+ if self.type == PTYPE_LTLIBRARY:
+ self.objext = '.lo'
+ else:
+ self.objext = '.o'
+
def is_cpp(self, ext):
return ext in utilities.cppext
@@ -45,18 +52,18 @@ class Program:
print '\trules to generate it. This should most probably read as'
print '\tdependencies for the object file.'
- def compile_lines(self, dir, base, ext):
+ def compile_lines(self, dir, base, ext, extraflags = "", forcecxx = 0, forcelibtoolOff = 0, depfilesuffix = '', deptargetoverride = ''):
libtool=0
compile = ""
- if self.type == PTYPE_LTLIBRARY:
+ if self.type == PTYPE_LTLIBRARY and forcelibtoolOff == 0:
libtool=1
#compile = '$(LIBTOOL) --mode=compile '
#if self.is_cpp(ext):
# compile = compile + '--tag=CXX '
- if self.is_cpp(ext):
+ if self.is_cpp(ext) or forcecxx != 0:
compile += '$(CXX) '
else:
compile += '$(CC) '
@@ -65,8 +72,10 @@ class Program:
compile += self.add_prefixed_variable("INCLUDES", 1)
# compile += self.handle_variable("CPPFLAGS") # Handle the Includepaths in CPPFLAGS
compile += self.handle_variable("CPPFLAGS", 1)
+ if len(extraflags):
+ compile += extraflags + ' '
- if self.is_cpp(ext):
+ if self.is_cpp(ext) or forcecxx:
compile += self.handle_variable("CXXFLAGS")
else:
compile += self.handle_variable("CFLAGS")
@@ -86,10 +95,14 @@ class Program:
'status=$$?; if test "$$status" -ne 0 && test ! -d "' + rulef.build + '.libs"; then \\',
'exit $$status; fi; fi'])
- lines.extend(["@depfile='%s$(DEPDIR)/%s.U%s' tmpdepfile='%s$(DEPDIR)/%s.TU%s' targetfile='$%s%s%s';\\"
- % (rulef.build, base, self.objext[1:],
- rulef.build, base, self.objext[1:],
- rulef.build, base, self.objext),
+ target = rulef.build + base + self.objext
+ if deptargetoverride:
+ target = deptargetoverride
+
+ lines.extend(["@depfile='%s$(DEPDIR)/%s.U%s' tmpdepfile='%s$(DEPDIR)/%s.TU%s' targetfile='$%s';\\"
+ % (rulef.build, base + depfilesuffix, self.objext[1:],
+ rulef.build, base + depfilesuffix, self.objext[1:],
+ target),
"set %s-c %s -o %s -Wp,-MD,$$tmpdepfile; \\" % (compile, file, output),
"$(V_COMPILE)"])
@@ -114,8 +127,13 @@ class Program:
lines = self.compile_lines(dir, base, ext)
+ dep = dir + base + ext
+ pchdep = self.amfile.canon_subdir + "_" + self.canon_name + '_PCHDEP'
+ if self.amfile.rulef.is_defined(pchdep):
+ dep += ' $(' + pchdep + ')'
+
rulef.insertTarget(rulef.build + base + self.objext,
- dir + base + ext,
+ dep,
lines)
rulef.dep_files.append('$(DEPDIR)/%s.U%s' % (base, self.objext[1:]))
@@ -186,7 +204,8 @@ class Program:
return ""
def handle_variable(self, var, replace_srcdir=0): # Now handles the Paths
- added = self.add_prefixed_variable("AM_%s" % var, replace_srcdir)
+ added = self.add_prefixed_variable("%s_%s" % (self.canon_name, var), replace_srcdir)
+ added += self.add_prefixed_variable("AM_%s" % var, replace_srcdir)
if self.amfile.is_defined(var):
added += self.add_prefixed_variable(var, replace_srcdir)
else:
@@ -453,10 +472,6 @@ class Program:
def handle_sources(self, sources):
self.sources = sources
self.objects = []
- if self.type == PTYPE_LTLIBRARY:
- self.objext = '.lo'
- else:
- self.objext = '.o'
self.use_c_linker = 1
for source in self.sources:
Index: unsermake
===================================================================
RCS file: /home/kde/kdenonbeta/unsermake/unsermake,v
retrieving revision 1.233
diff -u -p -b -r1.233 unsermake
--- unsermake 8 Mar 2004 09:51:55 -0000 1.233
+++ unsermake 14 Mar 2004 11:15:08 -0000
@@ -708,6 +708,9 @@ class AMFile(MakeFile):
for handler in handlerbase.handlers:
handler.shuffle_binaries(self)
+ for handler in handlerbase.handlers:
+ handler.postprocess(self)
+
for prog in self.binaries.values():
prog.handle_sources( self.definition_rec( prog.canon_name + '_SOURCES' ) )
prog.add_targets()
-------------- next part --------------
Index: acinclude.m4.in
===================================================================
RCS file: /home/kde/kde-common/admin/acinclude.m4.in,v
retrieving revision 2.445
diff -u -p -b -r2.445 acinclude.m4.in
--- acinclude.m4.in 26 Feb 2004 21:13:57 -0000 2.445
+++ acinclude.m4.in 14 Mar 2004 11:17:55 -0000
@@ -2975,25 +2975,49 @@ AC_DEFUN([AC_CHECK_COMPILERS],
CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS"
fi
+ AC_ARG_ENABLE(pch,
+ AC_HELP_STRING([--enable-pch],
+ [enables precompiled header support (currently only KCC or gcc >=3.4+unsermake) [default=no]]),
+ [ kde_use_pch=$enableval ],[ kde_use_pch=no ])
+
+
if test "$GXX" = "yes"; then
KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"])
KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"])
KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"])
KDE_CHECK_COMPILER_FLAG(fexceptions, [USE_EXCEPTIONS="-fexceptions"], USE_EXCEPTIONS= )
+
+ if test "$kde_use_pch" = "yes"; then
+ AC_MSG_CHECKING(wether gcc supports precompiling c header files)
+ echo >conftest.h
+ if $CC -x c-header conftest.h >/dev/null 2>/dev/null; then
+ kde_gcc_supports_pch=yes
+ AC_MSG_RESULT(yes)
+ else
+ kde_gcc_supports_pch=no
+ AC_MSG_RESULT(no)
fi
+ if test "$kde_gcc_supports_pch"; then
+ AC_MSG_CHECKING(wether gcc supports precompiling c++ header files)
+ if $CXX -x c++-header conftest.h >/dev/null 2>/dev/null; then
+ kde_gcc_supports_pch=yes
+ AC_MSG_RESULT(yes)
+ else
+ kde_gcc_supports_pch=no
+ AC_MSG_RESULT(no)
+ fi
+ fi
+ rm -f conftest.h conftest.h.gch
+ fi
+ AM_CONDITIONAL(unsermake_enable_pch, test "$kde_use_pch" = "yes" && test "$kde_gcc_supports_pch" = "yes")
+ fi
+
if test "$CXX" = "KCC"; then
dnl unfortunately we currently cannot disable exception support in KCC
dnl because doing so is binary incompatible and Qt by default links with exceptions :-(
dnl KDE_CHECK_COMPILER_FLAG(-no_exceptions,[CXXFLAGS="$CXXFLAGS --no_exceptions"])
dnl KDE_CHECK_COMPILER_FLAG(-exceptions, [USE_EXCEPTIONS="--exceptions"], USE_EXCEPTIONS= )
- AC_ARG_ENABLE(pch,
- AC_HELP_STRING([--enable-pch],
- [enables precompiled header support (currently only KCC) [default=no]]),
- [
- kde_use_pch=$enableval
- ],[kde_use_pch=no])
-
if test "$kde_use_pch" = "yes"; then
dnl TODO: support --pch-dir!
KDE_CHECK_COMPILER_FLAG(-pch,[CXXFLAGS="$CXXFLAGS --pch"])
More information about the kde-core-devel
mailing list