2010-09-06 12 views
5

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

+0

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? –

+1

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. –

+0

@ 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). –

Odpowiedz

1

Odnosząc się do dokumentacji "Używanie MOC" (http://doc.qt.nokia.com/4.1/moc.html), którą trzeba sprowadzać „foo. moc "na końcu pliku implementacji. Ponieważ nie można odpowiednio dostosować reguł budowania, spróbuj wyeksportować plik .pro i zastosować regułę budowania zgodnie z sugestią dokumentu nokia.

Powiązane problemy