Pracuję nad dużym projektem przy użyciu Qt 4.6, CMake 2.8 i Visual Studio 2008 dla platformy Windows.Qt, CMake, Visual Studio i Q_OBJECT w plikach cpp
Jeśli chodzi o system kompilacji, wszystko to jest standardowe: używam makra CMake QT4_WRAP_CPP
do generowania plików moc z plików nagłówkowych, które są następnie łączone z końcowym plikiem wykonywalnym w komendzie add_executable
. Wszystko działa zgodnie z oczekiwaniami.
Jedynym ograniczeniem związanym z tą konfiguracją jest to, że nie mogę zdefiniować widżetów ani pomocnika przy użyciu plików Q_OBJECT
w .cpp. Byłoby to bardzo wygodne dla małych, kontekstowych klas pomocników, które powinny pojawić się tuż obok miejsca, w którym są używane.
starałem się przekazać całą listę plików źródłowych (zarówno .h i .cpp) do QT4_WRAP_CPP
, a nie tylko plików nagłówkowych, ale to nie działa (łączenie nie powiedzie, ponieważ niektóre związane MOC symbole są niezdefiniowane).
Myślę, że problemem jest to, że dla danej pary plików Foo.h i foo.cpp The QT4_WRAP_CPP
makro będzie generować ten sam plik MOC (moc_foo.cxx) w tym samym katalogu, i oczywiście oznacza to, że pierwszy plik zostanie nadpisany przez drugi, w wyniku czego symbole będą tracone w czasie łącza.
Czy istnieje sposób naprawienia lub obejścia tego problemu? Na przykład, próbowałem dodać konkretną regułę dla foo.cpp formularza
QT4_GENERATE_MOC(directory/foo.cpp directory/foo.moc)
a następnie dodać
#include "foo.moc"
na koniec foo.cpp. Myślę, że to powinno zadziałać, ale niestety Visual Studio zezwala tylko na jedną regułę kompilacji na plik, a pliki .cpp mają już regułę kompilacji (kompilacja do pliku obiektowego), więc to podejście nie działa, przynajmniej z Visual Studio .
Innym pomysłem, który miałem było stworzenie nowego makra powiedzieć QT4_WRAP_CPP_WITH_PREFIX
, na podstawie QT4_WRAP_CPP
(który jest zdefiniowany w share/cmake-2,8/Moduły/Qt4Macros.cmake), która miałaby dodatkowy argument i prefiksu doda ten przedrostek do wygenerowanych plików mocy. W ten sposób będę dwa razy wywoływać QT4_WRAP_CPP_WITH_PREFIX
, raz dla plików .h i raz dla plików .cpp, z różnymi prefiksami. To, czego po prostu nie lubię w tym podejściu, polega na tym, że wpadałbym w interakcje z obsługą CMt Qt zamiast publicznego interfejsu API.
Lepszy pomysł?
Cheerz Franz
Nie jestem pewien, czy rozumiem ten bit: "Jedynym ograniczeniem w tej konfiguracji jest to, że nie mogę zdefiniować widżetów ani pomocnika przy użyciu Q_OBJECT w plikach .cpp." Nie powinieneś nigdy uruchamiać MOC na czymkolwiek poza plikami nagłówkowymi? –
Uważam, że wygodnie zdarza się definiować małą klasę pomocniczą w pliku .cpp i nie ujawniać jej poza tym plikiem .cpp. W tym celu muszę mieć możliwość uruchamiania MOC na plikach .cpp. Podejście makr "QT4_WRAP_CPP_WITH_PREFIX" opisane w moim poście działa jak urok. –
@ FrançoisBeaune - czy kiedykolwiek wymyśliłeś rozwiązanie tego problemu? Nawet coś to prosta: #include #include #include klasa MyClass: QObject publicznego { Q_OBJECT }; int main (int, char * []) { MyClass myClass; return 0; } Nie mogę dowiedzieć się, jak to MOC, ponieważ jest w pliku cpp (i otrzymuję błędy vtable podczas próby zbudowania go normalnie). –