I have been asked to convert a Qt project from QMake to CMake, and I’m having a problem with AutoMOC.
This project is structured like so:
src/
├─ include/
│ ├─ subfolder/
│ │ ├─ a.h
├─ CMakeLists.txt
├─ a.cpp
Headers are organized into subfolders, and only the top level include
directory is added with target_include_directories
. Users must specify the full path to their includes like #include <subfolder/a.h>
To speed up compile times, each of the source files also includes the moc source, like #include "moc_a.cpp"
.
This works great in QMake, but CMake does not like this. With the same setup converted to CMake, I get
AutoMoc error
-------------
"SRC:/a.cpp"
includes the moc file "moc_a.cpp",
but a header "a.{h,hh,h++,hm,hpp,hxx,in,txx}"
could not be found in the following directories
"SRC:"
"SRC:/include"
...
My CMake setup is:
cmake_minimum_required(VERSION 3.16)
project(test LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED COMPONENTS Core)
add_library(test SHARED ${CMAKE_CURRENT_SOURCE_DIR}/include/subfolder/a.h ${CMAKE_CURRENT_SOURCE_DIR}/a.cpp)
target_link_libraries(test PRIVATE Qt5::Core)
target_include_directories(test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
I understand it’s only looking in the top level include directory, as well as adjacent to the source, but QMake seemed to handle this just fine. I want to avoid recursively adding every leaf directory as an include path while still supporting this notation, because some people on this project may not want to transition to CMake yet.
Is there a way I can only pass the extra include directories to automoc? Or have it loosen its rules when checking for a matching header? I tried passing the include directories with -I/path/to/include
in CMAKE_AUTOMOC_MOC_OPTIONS
and it did not help.