3

In essence I want to be able to moc header files that are not part of any target in cmake with the additional difficulty that I don't know the filenames of those headers.

The actual project is quite complex and part of an automated build system. The following is an easy example. Consider a project structured like this:

CMakeLists.txt
src/lib/source.cpp
src/lib/CMakeLists.txt
src/include/some_header.hpp # which is included in source.cpp


Content of main CMakeLists.txt:

cmake_mimimum_required(VERSION 2.8.6)
project("automoctest")
add_subdirectory(src/lib)



Content of src/lib/CMakeLists.txt:

include_directories(${CMAKE_HOME_DIRECTORY}/src/include)
find_package(Qt4 4.8 REQUIRED QtCore)
include(UseQt4)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_library(foo SHARED source.cpp)
target_link_libraries(foo ${QT_LIBRARIES})
set_target_properties(foo PROPERTIES AUTOMOC true)



Inside source.cpp the file some_header.hpp is included like this:

#include "some_header.hpp"



The Problem:
The file some_header.hpp includes a Q_OBJECT and has some signals, so moc needs to work its magic. But as the header is not inside the actual project the header will not get mocked. I don't even know the filename of some_header.hpp so I can't add it specifically to be mocked. Obviously AUTOMOC does not check the include_directories for mockable files even when a source file includes one of them.

What I tried (unsuccessfully):

  • use #include moc_some_header.cpp in source.cpp
    as it is described in the cmake documentation. This leads to an error in which cmake complains that it could not find some_header{.h,.hpp,.hxx,.H}
  • setting CMAKE_AUTOMOC_RELAXED_MODE to true. Even though it's not clear from the doc what this actually does. Made no difference anyway.
  • setting AUTOMOC_MOC_OPTIONS to -Isrc/include or -I/path/to/project/src/include or -I${CMAKE_HOME_DIRECTORY}/src/include
    Doesn't do anything that I could see.

The great thing about AUTOMOC is that I don't need to know which files actually need to be mocked. In this case however I would need to know all the headers that might have a Q_OBJECT inside, that are included by my source files.

Is there a way to tell AUTOMOC where exactly to look for mockable files?

ifschleife
  • 1,055
  • 1
  • 10
  • 21

1 Answers1

1

Did you truly set AUTOMOC_MOC_OPTIONS to -Isrc/include, or to -I/path/to/myproject/src/include? The former probably doesn't exist.


I have always used the MOC macros; it looks like AUTOMOC is something new that is built into CMake.

I usually include all headers when creating a library or executable - i.e.

add_library(foo SHARED source.cpp ../include/some_header.hpp )

I assume that this will allow AUTOMOC to work. It will have the added benefit of causing make to work as expected - rebuilding your library when the header changes.

If you are truly unable to add the file to the add_library command ahead of time, then I think you'll have to write a cmake function to search for #include statements within source.cpp, locate those files, and search them for Q_OBJECT. If they match, add them to a variable - perhaps EXTRA_MOCS. Then, the add_library line becomes

add_library(foo SHARED source.cpp ${EXTRA_MOCS} )
Mark
  • 1,035
  • 2
  • 11
  • 24
  • Ah yes, sorry. I did try several paths for the -I option. Absolute, relative using CMAKE_HOME_DIRECTORY...none worked. – ifschleife Oct 22 '12 at 09:46
  • And yes, adding the header to the library explicitly works but I can't do that. I thought of the other solution myself (or something similar) but it seems so cumbersome to scan the headers myself. I'm surprised that there seems to be no way to tell automoc to also moc the include files... – ifschleife Oct 22 '12 at 09:52
  • 3
    Did you find a way to achieve this? I am in the same boat, just using Qt5. – Vaibhav Desai Jan 15 '13 at 22:56
  • Also in the same boat. ifschleife, @vaibhav-desai did you find any solutions? – thorink Dec 14 '16 at 10:36
  • Change jobs. So never had to deal with it :) – Vaibhav Desai Jan 06 '17 at 21:15