AW: KDevelop ctags symbol browsing on external dependencies (solution)

Markus Kuehni markus.kuehni at trilab.ch
Tue Nov 6 12:23:16 UTC 2001


Roland,

> I looked at your patch and while the idea is very good, I am not sure
> that this is really what we want. It'd be much better to implement a
> dialog that allows the configuration of the ctags command and to have
> multiple tags files. One for the actual project and another one for
> source code that doesnt change as much, e.g. kdelibs, qt, /usr/include.

Yes, I see.

You should still somehow scan for actual #includes in the project and *not*
only offer headers well-known in advance.

I think KDevelop has reached a level that qualifies it for much more than
"just" plain-vanilla KDE apps. I intend to use it for a wxWindows project,
for instance, with its own set of headers.

Also you'd have to be careful not to include too much. This approach would
either have to scan for actual #includes in the project too or let the user
configure (tedious!) the tags dbs to be considered. Otherwise you'd get tons
of unrelated symbols.

ctags already has the "shortcoming" of not considering conditional
compilation (#ifdefs) and thus catalogueing symbols that are not active in
the current project configuration. Indiscriminately adding headers would
"pollute" the symbol space further.

> This tags file doesnt have to be regenerated and should be stored in a
> central location.

You're right, that's a much cleaner approach in theory.

But you'll open a can of worms there. You'll either have write access to the
#include directories or build a mirror repository which, again, should be
protected from user tamper. So you'd have to /su/ in order to (re)generate
the tags. You'd have problems keeping up to date with installed headers.

A deamon for that pupose is the only valid solution, I think, and in my
opinion that's "mit Kanonen auf Tauben geschossen".

Another problem are tweaked -I and $INCLUDE to alternative versions of
well-known headers. Some people need to write code against newer versions of
installed headers.

The KDevelop project itself (which I consider a "big" example) has a
0.8Mbyte tags file normally and a 2.3Mbyte one with the patch. This compares
against 43.5Mbytes of *.o files which roughly is 5.3%. I think that's
acceptable.

> Still, if you think it makes your live easier I can apply the patch.
> There are definitely portability issues with the grep command,
> especially on older Solaris.

I think the /concept/ of my patch is the right thing to do. But not the
implementation.

Using shell command line expansion is always incredibly effortless but at
the same time it's still somehow a hack, because it heavily depends on OS
facilities. Who knows when KDevelop will be ported to Windows ;-) ?

Sooner or later this sould be replaced by built-in (C++) functionality.

In the interim, one could add a HAS_EGREP autoconf macro and
conditionally-compile the patch in. Or a U*X-guru could probably rewrite the
commands using awk, which I believe is universally available.

*NOTE*

Another, even better approach IMO would be using the preprocessor that runs
in the make process anyway. The CFLAGS/CPPFLAGS options " -save-temps -dD "
(set in the environment before configure) force gcc to leave behind the
preprocessed C-files (*.i and *.ii files) which contain all the assembled
#includes and all the right conditional code according to the (possibly
tweaked) environment/configuration.

Also (like in M$ Visual Studio) the expanded macro's symbols are catalogued
which can be very, very important when you have to track references to a
particular symbol. On the other hand you lose macro references but you can
"grep" for that; ctags chokes on some macros anyway (see man page).

The *.i* files contain #-directives which identify origin files and line
numbers.
The option -dD leaves #defines in the source, so you get aliasing
definitions (which can then be followed by the user).

After make, KDevelop can feed the intermediate files to

> ctags --langmap=c:.i,c++:.ii \
  --line-directives \
  --excmd=number \
  --recurse \
  <other options> \
  <prjdir>

and then optionally dispose of them (along with any *.s file also left
behind with -save-temps).

ctags understands the #-directives and maps symbols correctly. Duplicate
#include expansion is automatically eliminated.

NOTE: The --langmap option crashes ctags on my machine if used together
with --line-directives so you'd probably have to use

> find <prjdir> -name "*.ii" -print | ctags ... --language-force=c++ -L-
> find <prjdir> -name "*.i" -print | ctags
... --append --language-force=c -L-

instead until this is resolved (I submitted a bug).

This approach uses much more resources (intermediate disk space and time)
than the current approach. But it yields the best results IMO. The method
could be optimized by eliminating equal parts from the *.ii files (split
files on #-directives, save first occurrence according to orgin file name).

-- Mark


-
to unsubscribe from this list send an email to kdevelop-devel-request at kdevelop.org with the following body:
unsubscribe »your-email-address«



More information about the KDevelop-devel mailing list