I have a header like this:
#ifdef WITH_QT
#include <QObject>
#endif
namespace foo {
#ifdef WITH_QT
Q_NAMESPACE
#endif
enum class Letters {A, B, C };
#ifdef WITH_QT
Q_ENUM_NS(Letters)
#endif
}
And a cmake file:
cmake_minimum_required(VERSION 3.13)
find_package(Qt5 COMPONENTS Core)
qt5_wrap_cpp(moc_source foo.h)
add_library(foo STATIC ${moc_source})
target_compile_definitions(foo PUBLIC WITH_QT)
make VERBOSE=1
shows (abbreviated):
/usr/bin/moc foo.h
foo.h:0: Note: No relevant classes found. No output generated.
CodePudding user response:
moc
needs to be run with
/usr/bin/moc -DWITH_QT foo.h
CMake isn't forwarding your compile definitions to moc
. That prevents those macros from existing, and inhibits moc
from finding anything useful to generate.
A few solutions:
- This will add
WITH_QT
globally:
add_definitions(-DWITH_QT)
- This more refined method will tell
qt5_wrap_cpp
to import the compile definitions of a specific target. This is better as it avoids contaminating the compile definitions of the rest of your project.
qt5_wrap_cpp(moc_source foo.h TARGET foo)
See https://doc.qt.io/qt-5/qtcore-cmake-qt5-wrap-cpp.html for qt5_wrap_cpp()
usage.
- Use
AUTOMOC
by changing your CMakeLists to:
cmake_minimum_required(VERSION 3.13)
find_package(Qt5 COMPONENTS Core)
set(CMAKE_AUTOMOC ON)
add_library(foo STATIC foo.h)
target_compile_definitions(foo PUBLIC WITH_QT)
All three solutions will give you an archive with the missing symbol:
$ nm -gC libfoo.a
moc_foo.cpp.o:
U _GLOBAL_OFFSET_TABLE_
U qt_version_tag
0000000000000000 D foo::staticMetaObject