[cmake-developers] Automoc in cmake

Alexander Neundorf neundorf at kde.org
Thu Jun 9 02:41:36 EDT 2011


On Thursday 09 June 2011, Rolf Eike Beer wrote:
> Clinton Stimpson wrote:
> > On Wednesday, June 08, 2011 12:59:36 pm Alexander Neundorf wrote:
> > > Beside that, I didn't ask explicitely, but I'm sure without automoc
> > > cmake
> > > is out of the game for becoming the buildsystem for Qt5 (because in Qt4
> > > they do automoc in qmake).
> > 
> > What if this was a generic tool that could scan code to handle custom
> > dependencies, with the ability to do two things: (re)generated dependent
> > files or (re)generate the file with dependencies (sounds like a make tool
> > ;) ). Don't some Visual Studio users do this type of custom build
> > phases/steps/thingy by creating an Add-In?
> > 
> > Would that be an automoc equivalent if there was a macro that gave it the
> > rules for generating the dependencies?
> > 
> > Also, (a long outstanding bug), a Qt .qrc file has dependencies specified
> > in xml, which should be handled at build time.
> 
> Isn't there already a build-time scanner to add dependencies? Those C/C++
> files need to be scanned to identify header dependencies which may change
> between build runs also, no? So isn't this all about the same stuff? And
> for automoc it's basically only a special case of this since this is also
> an include, just one with a special pattern that adds additional
> dependencies.
> 
> I'm all in favor of a generic solution. 

Yes, me too.

> So maybe we could step back and
> look from a slightly greater distance at this. What would such a scanner
> need to know? And what does it need to tell CMake to run properly?

I didn't succeed in finding a more general picture.

Automoc does:
-scan all given source files for special #includes
-if such are found, run moc to create them
-make sure this happens before the including file is compiled

So, the problem is, that at cmake time it is not known which files will have 
to be generated, so I can't use add_custom_command() to create rules for these 
files.

Right now this is done by adding an extra target <targetname>_automoc to every 
target.
If I added a custom command for every source file, which would create 
basically a timestamp file, and run automoc just on this source file, I would 
get the mocs generated, and automoc only rerun if the source file changed, but 
since the source file depends on the moc files which come from a rule which 
depends on the source file, I would get a cyclic dependency I think:

add_custom_command(
   OUTPUT <filename>.automoc
   COMMAND automoc file.cpp -o file.automoc (..and the yet unknwown mocfiles)
   DEPENDS file.cpp )

add_executable(hello main.cpp file.cpp file.automoc )

I can't remember whether we tried that approach too, but wouldn't his produce 
a cycle in the dependencies ?

Alex
 
> Tell CMake:
> -which source types it wants to pass (C/C++/Java/ASM/other/*)
> -if it cares for header files
> -to avoid tokenizing all files in all scanners a pattern to look for. If
> that pattern is empty every file is passed to the scanner, otherwise only
> those where at least one matches that pattern
> -a flag if only matching lines should be send to the scanner (greatly
> reducing computation time)
> 
> What it would return:
> -for every file passed a list of files this one would depend on (testcases
> to reject: file depending on itself, introducing simple loops)
> 
> That would work out for the qrc and header scanner as the files they depend
> on are usually already there or defined by some target. This would not be
> enough for the automoc case since someone needs to create the targets that
> generates the moc_foo.cxx or foo.moc. So the scanner needs to be able to
> return additional CMake code that would be parsed and used as if it was
> defined right before the library/executable we try to create.

But this has to happen at build time, not cmake time, since the #include "moc" 
can be added without touching the cmake files.

> The next step would be to think about how people could come up with
> additions. Say I want to write a scanner for some language. Must it be C++
> code? Or can this somehow be hooked into CMake just as CMake script? How
> would that go? This way we could implement the whole automoc stuff just
> this way.
> 
> Alex, would this be a sufficient description for automoc?
> 
> language: C++
> header files: only

No, Q_OBJECT can also be in cpp-files.

> pattern: Q_OBJECT
> 
> result files: none (will be handled by the usual include scanner of the C++
> file)
> result code: ADD_CUSTOM_TARGET(... ${QT_MOC_EXECUTABLE} ...)

See the issue above, this can change at build time, so cmake does not rerun.

Alex



More information about the cmake-developers mailing list