I'm developing a large project using Qt 4.6, CMake 2.8 and Visual Studio 2008 for the Windows platform.
As far the build system goes, it's all standard stuff: I'm using CMake's QT4_WRAP_CPP
macro to generate moc files from header files, which are then linked into the final executable in the add_executable
command. Everything is working as expected.
The only restriction with this setup is that I can't define widgets or helper using Q_OBJECT
in .cpp files. This would be very convenient for small, context-specific helpers classes that should appear right next to where they're used.
I tried to pass the whole list of source files (both .h and .cpp) to QT4_WRAP_CPP
, instead of just the header files, but that doesn't work (linking fails because some moc-related sym开发者_高级运维bols are undefined).
I think the problem is that, for a given pair of files foo.h and foo.cpp, the QT4_WRAP_CPP
macro will generate the same moc file (moc_foo.cxx) in the same directory, and obviously that means the first file will be overwritten by the second one, and as a result symbols will be missing at link-time.
Is there a way to fix or work around that problem? For instance, I tried to add a specific rule for foo.cpp of the form
QT4_GENERATE_MOC(directory/foo.cpp directory/foo.moc)
and then add
#include "foo.moc"
at the end of foo.cpp. I think this ought to work, but alas Visual Studio only allows one build rule per file, and .cpp files already have a build rule (compilation to object file), so this approach doesn't work, at least with Visual Studio.
Another idea that I had was to create a new macro, say QT4_WRAP_CPP_WITH_PREFIX
, based on QT4_WRAP_CPP
(which is defined in share/cmake-2.8/Modules/Qt4Macros.cmake), that would take an additional prefix argument and would add this prefix to the generated moc files. That way, I would call QT4_WRAP_CPP_WITH_PREFIX
twice, once for .h files and once for .cpp files, with different prefixes. What I just dislike about this approach is that I'd be messing with the internals of CMake's Qt support, instead of using the public API.
Any better idea?
Recent versions of CMake have "automoc" which worked like a charm for me: http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc
Simply add in the CMakeLists.txt:
set(CMAKE_AUTOMOC TRUE)
and then in the cpp (e.g. example.cpp) file:
#include "example.moc"
(the *.moc must match the cpp file's name).
Referring to the documentation "Using the MOC" (http://doc.qt.nokia.com/4.1/moc.html), you'd only need to import "foo.moc" at the end of your implementation file. As you can not tweak the build rules correspondingly, try to export a .pro file and apply the build rule as suggested by the nokia document.
精彩评论