FILE(REMOVE) and FILE(APPEND) don't resolve relative filenames the same way

David Faure faure at kde.org
Fri Mar 6 15:35:30 CET 2009


On Friday 06 March 2009, Brad King wrote:
> David Faure wrote:
> > Testcase:
> > 
> > macro(mymacro)
> > FILE(REMOVE out)
> > FILE(APPEND out "hello\n")
> > endmacro(mymacro)
> > add_subdirectory(subdir)
> > 
> > and in subdir/CMakeLists.txt:
> > mymacro()
> > mymacro()
> > 
> > Expected result: only one line "hello" in the file "subdir/out".
> > Actual result: two lines "hello" in the file "subdir/out".
> > 
> > It looks like FILE(REMOVE out) uses the "current dir of the macro" (i.e. the toplevel)
> > while FILE(APPEND out) uses the real "current dir" (subdir/).
> > 
> > Is this a bug, or is it expected behavior? I'll play with the commands to get
> > absolute paths in order to fix this for now...
> 
> At one time we just required people to always use full paths, but around 2.4 we
> established the convention that relative paths are interpreted with respect to
> the location of the CMakeLists.txt file. It looks like file(REMOVE) was never 
> taught this convention.  However, don't you want this file to be manipulated
> in the *build* tree?  That will require full paths anyway.

Yes, the bug was in the code calling the macro, adding a
${CMAKE_CURRENT_BINARY_DIR}/ fixed it.
But I was very surprised by the FILE(...) behavior - and lost a long time
debugging why QT4_CREATE_MOC_COMMAND was creating a parameters
file with the arguments being duplicated (which leads to a rather vague error
message from moc), despite the FILE(REMOVE) call inside QT4_CREATE_MOC_COMMAND (see FindQt4.cmake).

=> Before QT4_CREATE_MOC_COMMAND calls 
FILE(REMOVE ${_moc_parameters_file}), could you make it check that
${_moc_parameters_file} is an absolute path and not a relative one,
since that's bound to fail and give unexpected results?

I think this would make it easier to debug the problem than the current
"moc: too many input files" error, it's hard to go up from that to
"I should pass an absolute path to qt4_generate_moc".




(And the reason for all this: there doesn't seem to be a way to generate
a foo.moc when foo.cpp defines a Q_OBJECT itself (rather than the header file)
and foo.cpp includes foo.moc. Well, kde4automoc handles this, but I'm abusing
this list to ask questions about a qt-only project ;) ). So I wrote this macro
macro(macro_included_moc cppfile)
  GET_FILENAME_COMPONENT(_basename ${cppfile} NAME_WE)
  SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc)
  qt4_generate_moc(${cppfile} ${_moc})
  macro_add_file_dependencies(${cppfile} ${_moc})
endmacro(macro_included_moc)

Alternative solution: including kde4automoc into cmake. I know we discussed
it in the past and it was rejected, but this is another argument for it.
My boss wouldn't let me add it as dependency, he wanted an
"off-the-shelf cmake" solution: importing kde4automoc and integrating it
into the compilation properly sounded like a bit too much trouble 
for a single cpp file that defined a Q_OBJECT...)

-- 
David Faure, faure at kde.org, sponsored by Qt Software @ Nokia to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).


More information about the Kde-buildsystem mailing list