Using cmake's automoc on external header files without knowing their filenames

3.4k Views Asked by At

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?

1

There are 1 best solutions below

5
On

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} )